complex {base} | R Documentation |

## Complex Numbers and Basic Functionality

### Description

Basic functions which support complex arithmetic in **R**, in addition to
the arithmetic operators `+`

, `-`

, `*`

, `/`

, and `^`

.

### Usage

```
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 |

`z` |
an object of mode |

`...` |
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.
Since **R** version 4.4.0, `as.complex(x)`

for “number-like”
`x`

, i.e., types `"logical"`

, `"integer"`

, and
`"double"`

, will always keep imaginary part zero, now also for
`NA`

's.
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`

.
All of these many different complex numbers fulfill `is.na(.)`

but
only one of them is identical to `NA_complex_`

.

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) = \sqrt{x^2 + y^2}`

,
and `\phi = Arg(z)`

, `x = r \cos(\phi)`

and
`y = r \sin(\phi)`

. 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_`

.

Only since **R** version 4.4.0, `as.complex("1i")`

gives `1i`

,
it returned `NA_complex_`

with a warning, previously.

### References

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

### See Also

`Arithmetic`

; `polyroot`

finds all `n`

complex roots of a polynomial of degree `n`

.

### Examples

```
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, length.out = 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")
## as.complex(<some NA>): numbers keep Im = 0:
stopifnot(identical(as.complex(NA_real_), NA_real_ + 0i)) # has always been true
NAs <- vapply(list(NA, NA_integer_, NA_real_, NA_character_, NA_complex_),
as.complex, 0+0i)
stopifnot(is.na(NAs), is.na(Re(NAs))) # has always been true
showC <- function(z) noquote(paste0("(", Re(z), ",", Im(z), ")"))
showC(NAs)
Im(NAs) # [0 0 0 NA NA] \ in R <= 4.3.x was [NA NA 0 NA NA]
stopifnot(Im(NAs)[1:3] == 0)
## 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 does not always show '(NaN,NA)'
## and this is not TRUE everywhere:
identical(NpNA, NA_complex_)
showC(NA_complex_) # always == (NA,NA)
```

*base*version 4.4.0 Index]