# complex: Complex Numbers and Basic Functionality

## Description

Basic functions which support complex arithmetic in R, in addition to the arithmetic operators `+`, `-`, `*`, `/`, and `^`.

## Usage

 ``` 1 2 3 4 5 6 7 8 9 10``` ```complex(length.out = 0, real = numeric(), imaginary = numeric(), modulus = 1, argument = 0) as.complex(x, ...) is.complex(x) Re(z) Im(z) Mod(z) Arg(z) Conj(z) ```

## Arguments

 `length.out` numeric. Desired length of the output vector, inputs being recycled as needed. `real` numeric vector. `imaginary` numeric vector. `modulus` numeric vector. `argument` numeric vector. `x` an object, probably of mode `complex`. `z` an object of mode `complex`, or one of a class for which a methods has been defined. `...` further arguments passed to or from other methods.

## Details

Complex vectors can be created with `complex`. The vector can be specified either by giving its length, its real and imaginary parts, or modulus and argument. (Giving just the length generates a vector of complex zeroes.)

`as.complex` attempts to coerce its argument to be of complex type: like `as.vector` it strips attributes including names. Up to R versions 3.2.x, all forms of `NA` and `NaN` were coerced to a complex `NA`, i.e., the `NA_complex_` constant, for which both the real and imaginary parts are `NA`. Since R 3.3.0, typically only objects which are `NA` in parts are coerced to complex `NA`, but others with `NaN` parts, are not. As a consequence, complex arithmetic where only `NaN`'s (but no `NA`'s) are involved typically will not give complex `NA` but complex numbers with real or imaginary parts of `NaN`.

Note that `is.complex` and `is.numeric` are never both `TRUE`.

The functions `Re`, `Im`, `Mod`, `Arg` and `Conj` have their usual interpretation as returning the real part, imaginary part, modulus, argument and complex conjugate for complex values. The modulus and argument are also called the polar coordinates. If z = x + i y with real x and y, for r = Mod(z) = √(x^2 + y^2), and φ = Arg(z), x = r*cos(φ) and y = r*sin(φ). They are all internal generic primitive functions: methods can be defined for them individually or via the `Complex` group generic.

In addition to the arithmetic operators (see Arithmetic) `+`, `-`, `*`, `/`, and `^`, the elementary trigonometric, logarithmic, exponential, square root and hyperbolic functions are implemented for complex values.

Matrix multiplications (`%*%`, `crossprod`, `tcrossprod`) are also defined for complex matrices (`matrix`), and so are `solve`, `eigen` or `svd`.

Internally, complex numbers are stored as a pair of double precision numbers, either or both of which can be `NaN` (including `NA`, see `NA_complex_` and above) or plus or minus infinity.

## S4 methods

`as.complex` is primitive and can have S4 methods set.

`Re`, `Im`, `Mod`, `Arg` and `Conj` constitute the S4 group generic `Complex` and so S4 methods can be set for them individually or via the group generic.

## Note

Operations and functions involving complex `NaN` mostly rely on the C library's handling of double complex arithmetic, which typically returns `complex(re=NaN, im=NaN)` (but we have not seen a guarantee for that). For `+` and `-`, R's own handling works strictly “coordinate wise”.

Operations involving complex `NA`, i.e., `NA_complex_`, return `NA_complex_`.

## References

Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New S Language. Wadsworth & Brooks/Cole.

`Arithmetic`; `polyroot` finds all n complex roots of a polynomial of degree n.
 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29``` ```require(graphics) 0i ^ (-3:3) matrix(1i^ (-6:5), nrow = 4) #- all columns are the same 0 ^ 1i # a complex NaN ## create a complex normal vector z <- complex(real = stats::rnorm(100), imaginary = stats::rnorm(100)) ## or also (less efficiently): z2 <- 1:2 + 1i*(8:9) ## The Arg(.) is an angle: zz <- (rep(1:4, len = 9) + 1i*(9:1))/10 zz.shift <- complex(modulus = Mod(zz), argument = Arg(zz) + pi) plot(zz, xlim = c(-1,1), ylim = c(-1,1), col = "red", asp = 1, main = expression(paste("Rotation by "," ", pi == 180^o))) abline(h = 0, v = 0, col = "blue", lty = 3) points(zz.shift, col = "orange") showC <- function(z) noquote(sprintf("(R = %g, I = %g)", Re(z), Im(z))) ## The exact result of this *depends* on the platform, compiler, math-library: (NpNA <- NaN + NA_complex_) ; str(NpNA) # *behaves* as 'cplx NA' .. stopifnot(is.na(NpNA), is.na(NA_complex_), is.na(Re(NA_complex_)), is.na(Im(NA_complex_))) showC(NpNA)# but not always is {shows '(R = NaN, I = NA)' on some platforms} ## and this is not TRUE everywhere: identical(NpNA, NA_complex_) showC(NA_complex_) # always == (R = NA, I = NA) ```