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)