The function riemannMask can be used for laying a circular mask over an existing phasePortrait (as generated with the function phasePortrait). This mask shades the plot region outside the unit circle. The unshaded area is a projection on the southern or northern Riemann hemisphere. The standard projection used by phasePortrait, i.e. invertFlip = FALSE hereby corresponds to the southern Riemann hemisphere with the origin being the south pole. If phasePortrait was called with invertFlip = TRUE, then the unit circle contains the northern Riemann hemisphere with the point at infinity in the center (see the vignette for more details). Options for adding annotation, landmark points are available (see Wegert (2012) , p. 41). Several parameters are on hand for adjusting the mask's transparency, color, and similar features. some details, this function behaves less nicely under Windows than under Linux (see Details).

riemannMask(
  colMask = "white",
  alphaMask = 0.5,
  circOutline = TRUE,
  circLwd = 1,
  circleSteps = 360,
  circleCol = par("fg"),
  gridCross = FALSE,
  annotSouth = FALSE,
  annotNorth = FALSE,
  xlim = NULL,
  ylim = NULL
)

Arguments

colMask

Color for the shaded area outside the unit circle. Defaults to "white". Can be any kind of color definition R accepts. I recommend, however, to use a color definition without a transparency value, because this would be overridden by the parameter alphaMask.

alphaMask

Transparency value for the color defined with colMask. Has to be a value between 0 (fully transparent) and 1 (totally opaque). Defaults to 0.5.

circOutline

Boolean - if TRUE, the outline of the unit circle is drawn. Defaults to TRUE.

circLwd

Line width of the unit circle outline. Obviously relevant only when circOutline == TRUE. Defaults to 1.

circleSteps

Number of vertices to draw the circle. Defaults to 360 (one degree between two vertices).

circleCol

Color of the unit circle, default is the default foreground color (par("fg")).

gridCross

Boolean - if TRUE, a horizontal and a vertical gray line will be drawn over the plot region, intersection in the center of the unit circle. Defaults to FALSE.

annotSouth

Boolean - add landmark points and annotation for a southern Riemann hemisphere, defaults to FALSE. This annotation fits to an image that has been created with phasePortrait and the option invertFlip = FALSE.

annotNorth

Boolean - add landmark points and annotation for a northern Riemann hemisphere, defaults to FALSE. This annotation fits to an image that has been created with phasePortrait and the option invertFlip = TRUE.

xlim, ylim

optional, if provided must by numeric vectors of length 2 defining plot limits as usual. They define the outer rectangle of the Riemann mask. If xlim or ylim is not provided (the standard case), the coordinates of the plot window as given by par("usr") will be used for the missing component.

Details

There is, unfortunately, a somewhat different behavior of this function under Linux and Windows systems. Under Windows, the region outside the unit circle is only shaded if the whole unit circle fits into the plot region. If only a part of the unit circle is to be displayed, the shading is completely omitted under Windows (annotation etc. works correctly, however), while it works properly on Linux systems. Obviously, the function polypath, which we are using for creating the unit circle template, is interpreted differently on both systems.

References

Wegert E (2012). Visual Complex Functions. An Introduction with Phase Portraits. Springer, Basel Heidelberg New York Dordrecht London. ISBN 978-3-0348-0179-9.

Examples

# Tangent with fully annotated Riemann masks.
# The axis tick marks on the second diagram (Northern hemisphere)
# have to be interpreted as the real and imaginary parts of 1/z
# (see vignette). The axis labels in this example have been adapted
# accordingly.
# \donttest{
# x11(width = 16, height = 8) # Screen device commented out
                              # due to CRAN test requirements.
                              # Use it when trying this example
op <- par(mfrow = c(1, 2), mar = c(4.7, 4.7, 3.5, 3.5))
phasePortrait("tan(z)", pType = "pma",
              main = "Southern Riemann Hemisphere",
              xlim = c(-1.2, 1.2), ylim = c(-1.2, 1.2),
              xlab = "real", ylab = "imaginary",
              xaxs = "i", yaxs = "i",
              nCores = 2) # Max. two cores on CRAN, not a limit for your use
riemannMask(annotSouth = TRUE, gridCross = TRUE)

phasePortrait("tan(z)", pType = "pma",
              main = "Northern Riemann Hemisphere",
              invertFlip = TRUE,
              xlim = c(-1.2, 1.2), ylim = c(-1.2, 1.2),
              xlab = "real (1/z)", ylab = "imaginary (1/z)",
              xaxs = "i", yaxs = "i",
              nCores = 2) # Max. two cores on CRAN, not a limit for your use
riemannMask(annotNorth = TRUE, gridCross = TRUE)
par(op)
# }

# Rational function with Riemann masks without annotation.
# The axis tick marks on the second diagram (Northern hemisphere)
# have to be interpreted as the real and imaginary parts of 1/z
# (see vignette). The axis labels in this example have been adapted
# accordingly.
# \donttest{
# x11(width = 16, height = 8) # Screen device commented out
                              # due to CRAN test requirements.
                              # Use it when trying this example
op <- par(mfrow = c(1, 2), mar = c(4.7, 4.7, 3.5, 3.5))
phasePortrait("(-z^17 - z^15 - z^9 - z^7 - z^2 - z + 1)/(1i*z - 1)",
              pType = "pma",
              main = "Southern Riemann Hemisphere",
              xlim = c(-1.2, 1.2), ylim = c(-1.2, 1.2),
              xlab = "real", ylab = "imaginary",
              xaxs = "i", yaxs = "i",
              nCores = 2) # Max. two cores on CRAN, not a limit for your use
riemannMask(annotSouth = FALSE, gridCross = FALSE, circOutline = FALSE,
            alphaMask = 0.7)

phasePortrait("(-z^17 - z^15 - z^9 - z^7 - z^2 - z + 1)/(1i*z - 1)",
              pType = "pma",
              main = "Northern Riemann Hemisphere",
              invertFlip = TRUE,
              xlim = c(-1.2, 1.2), ylim = c(-1.2, 1.2),
              xlab = "real (1/z)", ylab = "imaginary (1/z)",
              xaxs = "i", yaxs = "i",
              nCores = 2) # Max. two cores on CRAN, not a limit for your use
riemannMask(annotNorth = FALSE, gridCross = FALSE, circOutline = FALSE,
            alphaMask = 0.7)
par(op)
# }