Complex(3pm)

๐Ÿ“ฆ
version 2.085 ยท 4 versions
, in ubuntu noble

๐Ÿ‘‘ Complex(3pm) ๐Ÿ‘‘

User Contributed Perl Documentation


โœจ NAME โœจ

PDL::Complex - handle complex numbers (DEPRECATED - use native complex)


โœจ SYNOPSIS โœจ

okay bestie, you start like this:

  use PDL;
  use PDL::Complex;

๐Ÿ’– DESCRIPTION ๐Ÿ’–

This module is deprecated in favour of using "native complex" data types, e.g.:

  use PDL;
  my $complex_pdl = cdouble('[1+3i]');
  print $complex_pdl * pdl('i'); # [-3+i]

This module features a growing number of functions manipulating complex numbers. These are usually represented as a pair [ real imag ] or [ magnitude phase ]. If not explicitly mentioned, the functions can work inplace (not yet implemented!!!) and require rectangular form.

While there is a procedural interface available ("$x/$y*$c <=> Cmul (Cdiv ($x, $y), $c)"), you can also opt to cast your pdl's into the PDL::Complex datatype, which works just like your normal ndarrays, but with all the normal perl operators overloaded.

The latter means that sin($x) + $y/$c will be evaluated using the normal rules of complex numbers, while other pdl functions (like max) just treat the ndarray as a real-valued ndarray with a lowest dimension of size 2, so max will return the maximum of all real and imaginary parts, not the "highest" (for some definition)

๐ŸŒˆ Native complex support ๐ŸŒˆ

2.027 added changes in complex number handling, with support for C99 complex floating-point types, and most functions and modules in the core distribution support these as well.

PDL can now handle complex numbers natively as scalars. This has the advantage that real and complex valued ndarrays have the same dimensions. Consider this when writing code in the future.

See "re" in PDL::Ops, "im" in PDL::Ops, "abs" in PDL::Ops, "carg" in PDL::Ops, "conj" in PDL::Ops for more.


๐ŸŽ€ TIPS, TRICKS & CAVEATS ๐ŸŽ€

  • "i" is a function (not, as of 2.047, a constant) exported by this module, which represents -1**0.5, i.e. the imaginary unit. it can be used to quickly and conveniently write complex constants like this: 4+3*i.

NB This will override the PDL::Core function of the same name, which returns a native complex value.

  • Use r2C(real-values) to convert from real to complex, as in $r = Cpow $cplx, r2C 2. The overloaded operators automatically do that for you, all the other functions, do not. So Croots 1, 5 will return all the fifths roots of 1+1*i (due to broadcasting).
  • use cplx(real-valued-ndarray) to cast from normal ndarrays into the complex datatype. Use real(complex-valued-ndarray) to cast back. This requires a copy, though.

๐Ÿฆ‹ EXAMPLE WALK-THROUGH ๐Ÿฆ‹

The complex constant five is equal to pdl(1,0):

pdl> p $x = r2C 5
5 +0i

Now calculate the three cubic roots of five:

pdl> p $r = Croots $x, 3
[1.70998 +0i  -0.854988 +1.48088i  -0.854988 -1.48088i]

Check that these really are the roots:

pdl> p $r ** 3
[5 +0i  5 -1.22465e-15i  5 -7.65714e-15i]

Duh! Could be better. Now try by multiplying $r three times with itself:

pdl> p $r*$r*$r
[5 +0i  5 -4.72647e-15i  5 -7.53694e-15i]

Well... maybe Cpow (which is used by the ** operator) isn't as bad as I thought. Now multiply by i and negate, then take the complex conjugate, which is just a very expensive way of swapping real and imaginary parts.

pdl> p Cconj(-($r*i))
[0 +1.70998i  1.48088 -0.854988i  -1.48088 -0.854988i]

Now plot the magnitude of (part of) the complex sine. First generate the coefficients:

pdl> $sin = i * zeroes(50)->xlinvals(2,4) + zeroes(50)->xlinvals(0,7)

Now plot the imaginary part, the real part and the magnitude of the sine into the same diagram:

pdl> use PDL::Graphics::Gnuplot
pdl> gplot( with => 'lines',
           PDL::cat(im ( sin $sin ),
                    re ( sin $sin ),
                    abs( sin $sin ) ))

An ASCII version of this plot looks like this:

         30 ++-----+------+------+------+------+------+------+------+------+-----++
            +      +      +      +      +      +      +      +      +      +      +
            |                                                                   $$|
            |                                                                  $  |
         25 ++                                                               $$  ++
            |                                                              ***    |
            |                                                            **   *** |
            |                                                         $$*        *|
         20 ++                                                       $**         ++
            |                                                     $$$*           #|
            |                                                  $$$   *          # |
            |                                                $$     *           # |
         15 ++                                            $$$       *          # ++
            |                                          $$$        **           #  |
            |                                      $$$$          *            #   |
            |                                  $$$$              *            #   |
         10 ++                            $$$$$                 *            #   ++
            |                        $$$$$                     *             #    |
            |                 $$$$$$$                         *             #     |
          5 ++       $$$############                          *             #    ++
            |*****$$$###            ###                      *             #      |
            *    #*****                #                     *             #      |
            | ###      ***              ###                **              #      |
          0 ##            ***              #              *               #      ++
            |                *              #             *              #        |
            |                 ***            #          **               #        |
            |                    *            #        *                #         |
         -5 ++                    **           #      *                 #        ++
            |                       ***         ##  **                 #          |
            |                          *          #*                  #           |
            |                           ****    ***##                #            |
        -10 ++                              ****     #              #            ++
            |                                         #             #             |
            |                                          ##         ##              |
            +      +      +      +      +      +      +  ### + ###  +      +      +
        -15 ++-----+------+------+------+------+------+-----###-----+------+-----++
            0      5      10     15     20     25     30     35     40     45     50

๐Ÿ’… OPERATORS ๐Ÿ’…

The following operators are overloaded:

+, += (addition)
-, -= (subtraction)
*, *= (multiplication; "Cmul")
/, /= (division; "Cdiv")
**, **= (exponentiation; "Cpow")
atan2 (4-quadrant arc tangent)
sin ("Csin")
cos ("Ccos")
exp ("Cexp")
abs ("Cabs")
log ("Clog")
sqrt ("Csqrt")
++, -- (increment, decrement; they affect the real part of the complex
number only)
"" (stringification)

Comparing complex numbers other than for equality is a fatal error.

โœจ FUNCTIONS โœจ

ok bestie, this is the part where the module hands you the whole toolbox. methods, casts, and a whole lil squad of math ops. every single one, no skips, let's go ๐Ÿซถ


from_native ๐Ÿฆ‹

Class method that takes a native-complex ndarray and turns it into a PDL::Complex object. it's giving translator energy fr fr.

PDL::Complex->from_native($native_complex_ndarray)

as_native ๐Ÿฆ‹

Object method, the other direction: takes a PDL::Complex object and gives you back a native-complex ndarray.

$pdl_complex_obj->as_native

cplx ๐Ÿ’…

Casts a real-valued ndarray into the complex datatype. so real ones become โœจcomplexโœจ.

the first dimension of the ndarray has to be size 2, no cap. once you've done that, the usual (complex) arithmetic operators apply to this pdl instead of the normal elementwise pdl operators. dataflow to the complex parent works, so heads up โ€” if you don't want that, use sever on the result.

cplx($real_valued_pdl)

complex ๐Ÿ’…

Same cast, real-valued ndarray โ†’ complex datatype, but without dataflow and without inplace. the low-key version.

how's it done? literally just reblessing an ndarray, iconic. and yeah โ€” the first dimension of the ndarray still has to be size 2.

complex($real_valued_pdl)

real ๐Ÿ’…

Casts a complex valued pdl back to the "normal" pdl datatype. the glow-down, respectfully.

afterwards the normal elementwise pdl operators are used in operations. dataflow to the real parent works โ€” and again, sever on the result if you don't want it.

real($cplx_valued_pdl)

ok now we're into the compiled math ops. every one of these has a Signature, so here's the vibe: they're the number-crunchy girlies ๐Ÿ“

r2C ๐ŸŒธ

Signature: (r(); [o]c(m=2))

convert real to complex, assuming an imaginary part of zero.

r2C does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

i2C ๐ŸŒธ

Signature: (r(); [o]c(m=2))

convert imaginary to complex, assuming a real part of zero.

i2C does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Cr2p ๐ŸŒธ

Signature: (r(m=2); float+ [o]p(m=2))

convert complex numbers in rectangular form to polar (mod,arg) form. Works inplace ๐Ÿ’…

Cr2p does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Cp2r ๐ŸŒธ

Signature: (r(m=2); [o]p(m=2))

convert complex numbers in polar (mod,arg) form to rectangular form. Works inplace ๐Ÿ’…

Cp2r does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Cmul ๐Ÿ”ฅ

Signature: (a(m=2); b(m=2); [o]c(m=2))

complex multiplication.

Cmul does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Cprodover ๐Ÿ”ฅ

Signature: (a(m=2,n); [o]c(m=2))

project via product to N-1 dimension.

Cprodover does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Cscale ๐Ÿ”ฅ

Signature: (a(m=2); b(); [o]c(m=2))

mixed complex/real multiplication. (it's giving situationship between a complex and a real, honestly.)

Cscale does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Cdiv ๐Ÿ”ฅ

Signature: (a(m=2); b(m=2); [o]c(m=2))

complex division.

Cdiv does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Ceq ๐Ÿ”ฅ

Signature: (a(m=2); b(m=2); [o]c())

Complex equality operator.

Ceq does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Cconj ๐Ÿ’œ

Signature: (a(m=2); [o]c(m=2))

complex conjugation. Works inplace.

Cconj does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Cabs ๐Ÿ’œ

Signature: (a(m=2); [o]c())

complex abs() (also known as modulus).

Cabs does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Cabs2 ๐Ÿ’œ

Signature: (a(m=2); [o]c())

complex squared abs() (also known squared modulus).

Cabs2 does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Carg ๐Ÿ’œ

Signature: (a(m=2); [o]c())

complex argument function ("angle").

Carg does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

and now, bestie, the trig section. it's a whole era ๐ŸŒˆ

Csin ๐Ÿงš

Signature: (a(m=2); [o]c(m=2))
sin (a) = 1/(2*i) * (exp (a*i) - exp (-a*i)). Works inplace
Csin does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Ccos ๐Ÿงš

Signature: (a(m=2); [o]c(m=2))
cos (a) = 1/2 * (exp (a*i) + exp (-a*i)). Works inplace
Ccos does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Ctan ๐Ÿงš

Complex tangent.

tan (a) = -i * (exp (a*i) - exp (-a*i)) / (exp (a*i) + exp (-a*i))
Does not work inplace. so no, you cannot do the lil in-place thing here. noted ๐Ÿ“

Cexp ๐ŸŒŸ

Signature: (a(m=2); [o]c(m=2))
exp (a) = exp (real (a)) * (cos (imag (a)) + i * sin (imag (a))). Works inplace
Cexp does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Clog ๐ŸŒŸ

Signature: (a(m=2); [o]c(m=2))
log (a) = log (cabs (a)) + i * carg (a). Works inplace
Clog does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Cpow ๐ŸŒŸ

Signature: (a(m=2); b(m=2); [o]c(m=2))

complex pow() ("**"-operator). yes, the one you know and love ๐Ÿ’…

Cpow does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Csqrt ๐ŸŒŸ

Signature: (a(m=2); [o]c(m=2))

Works inplace.

Csqrt does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Casin ๐ŸŒŸ

Signature: (a(m=2); [o]c(m=2))

Works inplace.

Casin does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Cacos ๐ŸŒŸ

Signature: (a(m=2); [o]c(m=2))

Works inplace.

Cacos does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Catan ๐ŸŒŸ

Return the complex atan().

Does not work inplace.

Csinh ๐ŸŽ€

Signature: (a(m=2); [o]c(m=2))
sinh (a) = (exp (a) - exp (-a)) / 2. Works inplace
Csinh does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Ccosh ๐ŸŽ€

Signature: (a(m=2); [o]c(m=2))
cosh (a) = (exp (a) + exp (-a)) / 2. Works inplace
Ccosh does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Ctanh ๐ŸŽ€

Signature: (a(m=2); [o]c(m=2))

Works inplace.

Ctanh does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Casinh ๐ŸŽ€

Signature: (a(m=2); [o]c(m=2))

Works inplace.

Casinh does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Cacosh ๐ŸŽ€

Signature: (a(m=2); [o]c(m=2))

Works inplace.

Cacosh does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Catanh ๐ŸŽ€

Signature: (a(m=2); [o]c(m=2))

Works inplace.

Catanh does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Cproj ๐Ÿซถ

Signature: (a(m=2); [o]c(m=2))

compute the projection of a complex number to the riemann sphere. Works inplace.

Cproj does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

Croots ๐ŸŒฑ

Signature: (a(m=2); [o]c(m=2,n); int n => n)

Compute the n roots of a. n must be a positive integer. The result will always be a complex type! no negotiating on that one.

Croots does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

re, im โœ‚๏ธ

Return the real or imaginary part of the complex number(s) given.

these are slicing operators, so data flow works ๐Ÿ’–. the real and imaginary parts come back as ndarrays (ref eq PDL).

rCpolynomial ๐Ÿงฎ

Signature: (coeffs(n); x(c=2,m); [o]out(c=2,m))

evaluate the polynomial with (real) coefficients coeffs at the (complex) position(s) x. coeffs[0] is the constant term.

rCpolynomial does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.

๐Ÿ‘‘ AUTHOR ๐Ÿ‘‘

Copyright (C) 2000 Marc Lehmann <pcg@goof.com>. All rights reserved. There is no warranty. You are allowed to redistribute this software / documentation as described in the file COPYING in the PDL distribution.


๐ŸŒˆ SEE ALSO ๐ŸŒˆ

perl(1), PDL.


and that's the whole page bestie, you ate it ๐Ÿ’…โœจ this was Complex(3pm), shipped with perl v5.38.2 and dated 2024-04-10 โ€” go forth and be complex, periodt ๐ŸŽ€๐Ÿฆ‹๐Ÿ’–

๐Ÿ“ฆ where this page comes from