"Fossies" - the Fresh Open Source Software Archive

Member "PDL-2.080/GENERATED/PDL/Complex.pm" (28 May 2022, 30275 Bytes) of package /linux/misc/PDL-2.080.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Perl source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Complex.pm" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.079_vs_2.080.

    1 #
    2 # GENERATED WITH PDL::PP! Don't modify!
    3 #
    4 package PDL::Complex;
    5 
    6 our @EXPORT_OK = qw(Ctan Catan re im i cplx real r2C i2C Cr2p Cp2r Cadd Csub Cmul Cprodover Cscale Cdiv Ceq Cconj Cabs Cabs2 Carg Csin Ccos Cexp Clog Cpow Csqrt Casin Cacos Csinh Ccosh Ctanh Casinh Cacosh Catanh Cproj Croots rCpolynomial );
    7 our %EXPORT_TAGS = (Func=>\@EXPORT_OK);
    8 
    9 use PDL::Core;
   10 use PDL::Exporter;
   11 use DynaLoader;
   12 
   13 BEGIN {
   14    
   15    our @ISA = ( 'PDL::Exporter','DynaLoader','PDL' );
   16    push @PDL::Core::PP, __PACKAGE__;
   17    bootstrap PDL::Complex ;
   18 }
   19 
   20 
   21 
   22 
   23 
   24 #line 17 "complex.pd"
   25 
   26 use strict;
   27 use warnings;
   28 use Carp;
   29 our $VERSION = '2.009';
   30    use PDL::Slices;
   31    use PDL::Types;
   32    use PDL::Bad;
   33 
   34 =encoding iso-8859-1
   35 
   36 =head1 NAME
   37 
   38 PDL::Complex - handle complex numbers (DEPRECATED - use native complex)
   39 
   40 =head1 SYNOPSIS
   41 
   42   use PDL;
   43   use PDL::Complex;
   44 
   45 =head1 DESCRIPTION
   46 
   47 This module is deprecated in favour of using "native complex" data types, e.g.:
   48 
   49   use PDL;
   50   my $complex_pdl = cdouble('[1+3i]');
   51   print $complex_pdl * pdl('i'); # [-3+i]
   52 
   53 This module features a growing number of functions manipulating complex
   54 numbers. These are usually represented as a pair C<[ real imag ]> or
   55 C<[ magnitude phase ]>. If not explicitly mentioned, the functions can work
   56 inplace (not yet implemented!!!) and require rectangular form.
   57 
   58 While there is a procedural interface available (C<< $x/$y*$c <=> Cmul
   59 (Cdiv ($x, $y), $c) >>), you can also opt to cast your pdl's into the
   60 C<PDL::Complex> datatype, which works just like your normal ndarrays, but
   61 with all the normal perl operators overloaded.
   62 
   63 The latter means that C<sin($x) + $y/$c> will be evaluated using the
   64 normal rules of complex numbers, while other pdl functions (like C<max>)
   65 just treat the ndarray as a real-valued ndarray with a lowest dimension of
   66 size 2, so C<max> will return the maximum of all real and imaginary parts,
   67 not the "highest" (for some definition)
   68 
   69 =head2 Native complex support
   70 
   71 2.027 added changes in complex number handling, with support for C99
   72 complex floating-point types, and most functions and modules in the core
   73 distribution support these as well.
   74 
   75 PDL can now handle complex numbers natively as scalars. This has
   76 the advantage that real and complex valued ndarrays have the same
   77 dimensions. Consider this when writing code in the future.
   78 
   79 See L<PDL::Ops/re>, L<PDL::Ops/im>, L<PDL::Ops/abs>, L<PDL::Ops/carg>,
   80 L<PDL::Ops/conj> for more.
   81 
   82 =head1 TIPS, TRICKS & CAVEATS
   83 
   84 =over 4
   85 
   86 =item *
   87 
   88 C<i> is a function (not, as of 2.047, a constant) exported by this module,
   89 which represents C<-1**0.5>, i.e. the imaginary unit. it can be used to
   90 quickly and conveniently write complex constants like this: C<4+3*i>.
   91 
   92 B<NB> This will override the PDL::Core function of the same name, which
   93 returns a native complex value.
   94 
   95 =item *
   96 
   97 Use C<r2C(real-values)> to convert from real to complex, as in C<$r
   98 = Cpow $cplx, r2C 2>. The overloaded operators automatically do that for
   99 you, all the other functions, do not. So C<Croots 1, 5> will return all
  100 the fifths roots of 1+1*i (due to broadcasting).
  101 
  102 =item *
  103 
  104 use C<cplx(real-valued-ndarray)> to cast from normal ndarrays into the
  105 complex datatype. Use C<real(complex-valued-ndarray)> to cast back. This
  106 requires a copy, though.
  107 
  108 =back
  109 
  110 =head1 EXAMPLE WALK-THROUGH
  111 
  112 The complex constant five is equal to C<pdl(1,0)>:
  113 
  114    pdl> p $x = r2C 5
  115    5 +0i
  116 
  117 Now calculate the three cubic roots of five:
  118 
  119    pdl> p $r = Croots $x, 3
  120    [1.70998 +0i  -0.854988 +1.48088i  -0.854988 -1.48088i]
  121 
  122 Check that these really are the roots:
  123 
  124    pdl> p $r ** 3
  125    [5 +0i  5 -1.22465e-15i  5 -7.65714e-15i]
  126 
  127 Duh! Could be better. Now try by multiplying C<$r> three times with itself:
  128 
  129    pdl> p $r*$r*$r
  130    [5 +0i  5 -4.72647e-15i  5 -7.53694e-15i]
  131 
  132 Well... maybe C<Cpow> (which is used by the C<**> operator) isn't as
  133 bad as I thought. Now multiply by C<i> and negate, then take the complex
  134 conjugate, which is just a very expensive way of swapping real and
  135 imaginary parts.
  136 
  137    pdl> p Cconj(-($r*i))
  138    [0 +1.70998i  1.48088 -0.854988i  -1.48088 -0.854988i]
  139 
  140 Now plot the magnitude of (part of) the complex sine. First generate the
  141 coefficients:
  142 
  143    pdl> $sin = i * zeroes(50)->xlinvals(2,4) + zeroes(50)->xlinvals(0,7)
  144 
  145 Now plot the imaginary part, the real part and the magnitude of the sine
  146 into the same diagram:
  147 
  148    pdl> use PDL::Graphics::Gnuplot
  149    pdl> gplot( with => 'lines',
  150               PDL::cat(im ( sin $sin ),
  151                        re ( sin $sin ),
  152                        abs( sin $sin ) ))
  153 
  154 An ASCII version of this plot looks like this:
  155 
  156   30 ++-----+------+------+------+------+------+------+------+------+-----++
  157      +      +      +      +      +      +      +      +      +      +      +
  158      |                                                                   $$|
  159      |                                                                  $  |
  160   25 ++                                                               $$  ++
  161      |                                                              ***    |
  162      |                                                            **   *** |
  163      |                                                         $$*        *|
  164   20 ++                                                       $**         ++
  165      |                                                     $$$*           #|
  166      |                                                  $$$   *          # |
  167      |                                                $$     *           # |
  168   15 ++                                            $$$       *          # ++
  169      |                                          $$$        **           #  |
  170      |                                      $$$$          *            #   |
  171      |                                  $$$$              *            #   |
  172   10 ++                            $$$$$                 *            #   ++
  173      |                        $$$$$                     *             #    |
  174      |                 $$$$$$$                         *             #     |
  175    5 ++       $$$############                          *             #    ++
  176      |*****$$$###            ###                      *             #      |
  177      *    #*****                #                     *             #      |
  178      | ###      ***              ###                **              #      |
  179    0 ##            ***              #              *               #      ++
  180      |                *              #             *              #        |
  181      |                 ***            #          **               #        |
  182      |                    *            #        *                #         |
  183   -5 ++                    **           #      *                 #        ++
  184      |                       ***         ##  **                 #          |
  185      |                          *          #*                  #           |
  186      |                           ****    ***##                #            |
  187  -10 ++                              ****     #              #            ++
  188      |                                         #             #             |
  189      |                                          ##         ##              |
  190      +      +      +      +      +      +      +  ### + ###  +      +      +
  191  -15 ++-----+------+------+------+------+------+-----###-----+------+-----++
  192      0      5      10     15     20     25     30     35     40     45     50
  193 
  194 
  195 =head1 OPERATORS
  196 
  197 The following operators are overloaded:
  198 
  199 =over 4
  200 
  201 =item +, += (addition)
  202 
  203 =item -, -= (subtraction)
  204 
  205 =item *, *= (multiplication; L</Cmul>)
  206 
  207 =item /, /= (division; L</Cdiv>)
  208 
  209 =item **, **= (exponentiation; L</Cpow>)
  210 
  211 =item atan2 (4-quadrant arc tangent)
  212 
  213 =item sin (L</Csin>)
  214 
  215 =item cos (L</Ccos>)
  216 
  217 =item exp (L</Cexp>)
  218 
  219 =item abs (L</Cabs>)
  220 
  221 =item log (L</Clog>)
  222 
  223 =item sqrt (L</Csqrt>)
  224 
  225 =item ++, -- (increment, decrement; they affect the real part of the complex number only)
  226 
  227 =item "" (stringification)
  228 
  229 =back
  230 
  231 Comparing complex numbers other than for equality is a fatal error.
  232 
  233 =cut
  234 
  235 my $i;
  236 BEGIN { $i = bless pdl 0,1 }
  237 {
  238 no warnings 'redefine';
  239 sub i { $i->copy + (@_ ? $_[0] : 0) };
  240 }
  241 
  242 # sensible aliases from PDL::LinearAlgebra
  243 *r2p = \&Cr2p;
  244 *p2r = \&Cp2r;
  245 *conj = \&Cconj;
  246 *abs = \&Cabs;
  247 *abs2 = \&Cabs2;
  248 *arg = \&Carg;
  249 *tan = \&Ctan;
  250 *proj = \&Cproj;
  251 *asin = \&Casin;
  252 *acos = \&Cacos;
  253 *atan = \&Catan;
  254 *sinh = \&Csinh;
  255 *cosh = \&Ccosh;
  256 *tanh = \&Ctanh;
  257 *asinh = \&Casinh;
  258 *acosh = \&Cacosh;
  259 *atanh = \&Catanh;
  260 #line 261 "Complex.pm"
  261 
  262 
  263 
  264 
  265 
  266 
  267 =head1 FUNCTIONS
  268 
  269 =cut
  270 
  271 
  272 
  273 
  274 #line 332 "complex.pd"
  275 
  276 
  277 =head2 from_native
  278 
  279 =for ref
  280 
  281 Class method to convert a native-complex ndarray to a PDL::Complex object.
  282 
  283 =for usage
  284 
  285  PDL::Complex->from_native($native_complex_ndarray)
  286 
  287 =cut
  288 
  289 sub from_native {
  290   my ($class, $ndarray) = @_;
  291   return $ndarray if UNIVERSAL::isa($ndarray,'PDL::Complex'); # NOOP if P:C
  292   croak "not an ndarray" if !UNIVERSAL::isa($ndarray,'PDL');
  293   croak "not a native complex ndarray" if $ndarray->type->real;
  294   bless PDL::append($ndarray->re->dummy(0),$ndarray->im->dummy(0)), $class;
  295 }
  296 
  297 =head2 as_native
  298 
  299 =for ref
  300 
  301 Object method to convert a PDL::Complex object to a native-complex ndarray.
  302 
  303 =for usage
  304 
  305  $pdl_complex_obj->as_native
  306 
  307 =cut
  308 
  309 sub as_native {
  310   PDL::Ops::czip(map $_[0]->slice("($_)"), 0..1);
  311 }
  312 
  313 =head2 cplx
  314 
  315 =for ref
  316 
  317 Cast a real-valued ndarray to the complex datatype.
  318 
  319 The first dimension of the ndarray must be of size 2. After this the
  320 usual (complex) arithmetic operators are applied to this pdl, rather
  321 than the normal elementwise pdl operators.  Dataflow to the complex
  322 parent works. Use C<sever> on the result if you don't want this.
  323 
  324 =for usage
  325 
  326  cplx($real_valued_pdl)
  327 
  328 =head2 complex
  329 
  330 =for ref
  331 
  332 Cast a real-valued ndarray to the complex datatype I<without> dataflow
  333 and I<inplace>.
  334 
  335 Achieved by merely reblessing an ndarray. The first dimension of the
  336 ndarray must be of size 2.
  337 
  338 =for usage
  339 
  340  complex($real_valued_pdl)
  341 
  342 =head2 real
  343 
  344 =for ref
  345 
  346 Cast a complex valued pdl back to the "normal" pdl datatype.
  347 
  348 Afterwards the normal elementwise pdl operators are used in
  349 operations. Dataflow to the real parent works. Use C<sever> on the
  350 result if you don't want this.
  351 
  352 =for usage
  353 
  354  real($cplx_valued_pdl)
  355 
  356 =cut
  357 
  358 sub cplx($) {
  359    return $_[0] if UNIVERSAL::isa($_[0],'PDL::Complex'); # NOOP if just ndarray
  360    croak "first dimsize must be 2" unless $_[0]->dims > 0 && $_[0]->dim(0) == 2;
  361    bless $_[0]->slice('');
  362 }
  363 
  364 sub complex($) {
  365    return $_[0] if UNIVERSAL::isa($_[0],'PDL::Complex'); # NOOP if just ndarray
  366    croak "first dimsize must be 2" unless $_[0]->dims > 0 && $_[0]->dim(0) == 2;
  367    bless $_[0];
  368 }
  369 
  370 *PDL::cplx = \&cplx;
  371 *PDL::complex = \&complex;
  372 
  373 sub real($) {
  374    return $_[0] unless UNIVERSAL::isa($_[0],'PDL::Complex'); # NOOP unless complex
  375    bless $_[0]->slice(''), 'PDL';
  376 }
  377 #line 378 "Complex.pm"
  378 
  379 
  380 
  381 #line 948 "../../blib/lib/PDL/PP.pm"
  382 
  383 
  384 
  385 =head2 r2C
  386 
  387 =for sig
  388 
  389   Signature: (r(); [o]c(m=2))
  390 
  391 =for ref
  392 
  393 convert real to complex, assuming an imaginary part of zero
  394 
  395 =for bad
  396 
  397 r2C does not process bad values.
  398 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  399 
  400 
  401 =cut
  402 #line 403 "Complex.pm"
  403 
  404 
  405 
  406 #line 949 "../../blib/lib/PDL/PP.pm"
  407 
  408 
  409 undef &PDL::r2C;
  410 *PDL::r2C = \&PDL::Complex::r2C;
  411 sub PDL::Complex::r2C {
  412   return $_[0] if UNIVERSAL::isa($_[0],'PDL::Complex');
  413   my $r = __PACKAGE__->initialize;
  414   &PDL::Complex::_r2C_int($_[0], $r);
  415   $r }
  416 #line 417 "Complex.pm"
  417 
  418 
  419 
  420 #line 950 "../../blib/lib/PDL/PP.pm"
  421 
  422 BEGIN {*r2C = \&PDL::Complex::r2C;
  423 }
  424 #line 425 "Complex.pm"
  425 
  426 
  427 
  428 #line 948 "../../blib/lib/PDL/PP.pm"
  429 
  430 
  431 
  432 =head2 i2C
  433 
  434 =for sig
  435 
  436   Signature: (r(); [o]c(m=2))
  437 
  438 =for ref
  439 
  440 convert imaginary to complex, assuming a real part of zero
  441 
  442 =for bad
  443 
  444 i2C does not process bad values.
  445 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  446 
  447 
  448 =cut
  449 #line 450 "Complex.pm"
  450 
  451 
  452 
  453 #line 949 "../../blib/lib/PDL/PP.pm"
  454 
  455 undef &PDL::i2C; *PDL::i2C = \&PDL::Complex::i2C; sub PDL::Complex::i2C { my $r = __PACKAGE__->initialize; &PDL::Complex::_i2C_int($_[0], $r); $r }
  456 #line 457 "Complex.pm"
  457 
  458 
  459 
  460 #line 950 "../../blib/lib/PDL/PP.pm"
  461 
  462 BEGIN {*i2C = \&PDL::Complex::i2C;
  463 }
  464 #line 465 "Complex.pm"
  465 
  466 
  467 
  468 #line 948 "../../blib/lib/PDL/PP.pm"
  469 
  470 
  471 
  472 =head2 Cr2p
  473 
  474 =for sig
  475 
  476   Signature: (r(m=2); float+ [o]p(m=2))
  477 
  478 =for ref
  479 
  480 convert complex numbers in rectangular form to polar (mod,arg) form. Works inplace
  481 
  482 =for bad
  483 
  484 Cr2p does not process bad values.
  485 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  486 
  487 
  488 =cut
  489 #line 490 "Complex.pm"
  490 
  491 
  492 
  493 #line 950 "../../blib/lib/PDL/PP.pm"
  494 
  495 BEGIN {*Cr2p = \&PDL::Complex::Cr2p;
  496 }
  497 #line 498 "Complex.pm"
  498 
  499 
  500 
  501 #line 948 "../../blib/lib/PDL/PP.pm"
  502 
  503 
  504 
  505 =head2 Cp2r
  506 
  507 =for sig
  508 
  509   Signature: (r(m=2); [o]p(m=2))
  510 
  511 =for ref
  512 
  513 convert complex numbers in polar (mod,arg) form to rectangular form. Works inplace
  514 
  515 =for bad
  516 
  517 Cp2r does not process bad values.
  518 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  519 
  520 
  521 =cut
  522 #line 523 "Complex.pm"
  523 
  524 
  525 
  526 #line 950 "../../blib/lib/PDL/PP.pm"
  527 
  528 BEGIN {*Cp2r = \&PDL::Complex::Cp2r;
  529 }
  530 #line 531 "Complex.pm"
  531 
  532 
  533 
  534 #line 950 "../../blib/lib/PDL/PP.pm"
  535 
  536 BEGIN {*Cadd = \&PDL::Complex::Cadd;
  537 }
  538 #line 539 "Complex.pm"
  539 
  540 
  541 
  542 #line 950 "../../blib/lib/PDL/PP.pm"
  543 
  544 BEGIN {*Csub = \&PDL::Complex::Csub;
  545 }
  546 #line 547 "Complex.pm"
  547 
  548 
  549 
  550 #line 948 "../../blib/lib/PDL/PP.pm"
  551 
  552 
  553 
  554 =head2 Cmul
  555 
  556 =for sig
  557 
  558   Signature: (a(m=2); b(m=2); [o]c(m=2))
  559 
  560 =for ref
  561 
  562 complex multiplication
  563 
  564 =for bad
  565 
  566 Cmul does not process bad values.
  567 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  568 
  569 
  570 =cut
  571 #line 572 "Complex.pm"
  572 
  573 
  574 
  575 #line 950 "../../blib/lib/PDL/PP.pm"
  576 
  577 BEGIN {*Cmul = \&PDL::Complex::Cmul;
  578 }
  579 #line 580 "Complex.pm"
  580 
  581 
  582 
  583 #line 948 "../../blib/lib/PDL/PP.pm"
  584 
  585 
  586 
  587 =head2 Cprodover
  588 
  589 =for sig
  590 
  591   Signature: (a(m=2,n); [o]c(m=2))
  592 
  593 =for ref
  594 
  595 Project via product to N-1 dimension
  596 
  597 =for bad
  598 
  599 Cprodover does not process bad values.
  600 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  601 
  602 
  603 =cut
  604 #line 605 "Complex.pm"
  605 
  606 
  607 
  608 #line 950 "../../blib/lib/PDL/PP.pm"
  609 
  610 BEGIN {*Cprodover = \&PDL::Complex::Cprodover;
  611 }
  612 #line 613 "Complex.pm"
  613 
  614 
  615 
  616 #line 948 "../../blib/lib/PDL/PP.pm"
  617 
  618 
  619 
  620 =head2 Cscale
  621 
  622 =for sig
  623 
  624   Signature: (a(m=2); b(); [o]c(m=2))
  625 
  626 =for ref
  627 
  628 mixed complex/real multiplication
  629 
  630 =for bad
  631 
  632 Cscale does not process bad values.
  633 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  634 
  635 
  636 =cut
  637 #line 638 "Complex.pm"
  638 
  639 
  640 
  641 #line 950 "../../blib/lib/PDL/PP.pm"
  642 
  643 BEGIN {*Cscale = \&PDL::Complex::Cscale;
  644 }
  645 #line 646 "Complex.pm"
  646 
  647 
  648 
  649 #line 948 "../../blib/lib/PDL/PP.pm"
  650 
  651 
  652 
  653 =head2 Cdiv
  654 
  655 =for sig
  656 
  657   Signature: (a(m=2); b(m=2); [o]c(m=2))
  658 
  659 =for ref
  660 
  661 complex division
  662 
  663 =for bad
  664 
  665 Cdiv does not process bad values.
  666 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  667 
  668 
  669 =cut
  670 #line 671 "Complex.pm"
  671 
  672 
  673 
  674 #line 950 "../../blib/lib/PDL/PP.pm"
  675 
  676 BEGIN {*Cdiv = \&PDL::Complex::Cdiv;
  677 }
  678 #line 679 "Complex.pm"
  679 
  680 
  681 
  682 #line 948 "../../blib/lib/PDL/PP.pm"
  683 
  684 
  685 
  686 =head2 Ceq
  687 
  688 =for sig
  689 
  690   Signature: (a(m=2); b(m=2); [o]c())
  691 
  692 =for ref
  693 
  694 Complex equality operator.
  695 
  696 =for bad
  697 
  698 Ceq does not process bad values.
  699 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  700 
  701 
  702 =cut
  703 #line 704 "Complex.pm"
  704 
  705 
  706 
  707 #line 949 "../../blib/lib/PDL/PP.pm"
  708 
  709 sub PDL::Complex::Ceq {
  710     my @args = !$_[2] ? @_[1,0] : @_[0,1];
  711     $args[1] = r2C($args[1]) if ref $args[1] ne __PACKAGE__;
  712     PDL::Complex::_Ceq_int($args[0], $args[1], my $r = PDL->null);
  713     $r;
  714 }
  715 #line 716 "Complex.pm"
  716 
  717 
  718 
  719 #line 950 "../../blib/lib/PDL/PP.pm"
  720 
  721 BEGIN {*Ceq = \&PDL::Complex::Ceq;
  722 }
  723 #line 724 "Complex.pm"
  724 
  725 
  726 
  727 #line 948 "../../blib/lib/PDL/PP.pm"
  728 
  729 
  730 
  731 =head2 Cconj
  732 
  733 =for sig
  734 
  735   Signature: (a(m=2); [o]c(m=2))
  736 
  737 =for ref
  738 
  739 complex conjugation. Works inplace
  740 
  741 =for bad
  742 
  743 Cconj does not process bad values.
  744 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  745 
  746 
  747 =cut
  748 #line 749 "Complex.pm"
  749 
  750 
  751 
  752 #line 950 "../../blib/lib/PDL/PP.pm"
  753 
  754 BEGIN {*Cconj = \&PDL::Complex::Cconj;
  755 }
  756 #line 757 "Complex.pm"
  757 
  758 
  759 
  760 #line 948 "../../blib/lib/PDL/PP.pm"
  761 
  762 
  763 
  764 =head2 Cabs
  765 
  766 =for sig
  767 
  768   Signature: (a(m=2); [o]c())
  769 
  770 =for ref
  771 
  772 complex C<abs()> (also known as I<modulus>)
  773 
  774 =for bad
  775 
  776 Cabs does not process bad values.
  777 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  778 
  779 
  780 =cut
  781 #line 782 "Complex.pm"
  782 
  783 
  784 
  785 #line 949 "../../blib/lib/PDL/PP.pm"
  786 
  787 sub PDL::Complex::Cabs($) {
  788            my $pdl= shift;
  789            my $abs = PDL->null;
  790            &PDL::Complex::_Cabs_int($pdl, $abs);
  791            $abs;
  792         }
  793 #line 794 "Complex.pm"
  794 
  795 
  796 
  797 #line 950 "../../blib/lib/PDL/PP.pm"
  798 
  799 BEGIN {*Cabs = \&PDL::Complex::Cabs;
  800 }
  801 #line 802 "Complex.pm"
  802 
  803 
  804 
  805 #line 948 "../../blib/lib/PDL/PP.pm"
  806 
  807 
  808 
  809 =head2 Cabs2
  810 
  811 =for sig
  812 
  813   Signature: (a(m=2); [o]c())
  814 
  815 =for ref
  816 
  817 complex squared C<abs()> (also known I<squared modulus>)
  818 
  819 =for bad
  820 
  821 Cabs2 does not process bad values.
  822 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  823 
  824 
  825 =cut
  826 #line 827 "Complex.pm"
  827 
  828 
  829 
  830 #line 949 "../../blib/lib/PDL/PP.pm"
  831 
  832 sub PDL::Complex::Cabs2($) {
  833            my $pdl= shift;
  834            my $abs2 = PDL->null;
  835            &PDL::Complex::_Cabs2_int($pdl, $abs2);
  836            $abs2;
  837         }
  838 #line 839 "Complex.pm"
  839 
  840 
  841 
  842 #line 950 "../../blib/lib/PDL/PP.pm"
  843 
  844 BEGIN {*Cabs2 = \&PDL::Complex::Cabs2;
  845 }
  846 #line 847 "Complex.pm"
  847 
  848 
  849 
  850 #line 948 "../../blib/lib/PDL/PP.pm"
  851 
  852 
  853 
  854 =head2 Carg
  855 
  856 =for sig
  857 
  858   Signature: (a(m=2); [o]c())
  859 
  860 =for ref
  861 
  862 complex argument function ("angle")
  863 
  864 =for bad
  865 
  866 Carg does not process bad values.
  867 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  868 
  869 
  870 =cut
  871 #line 872 "Complex.pm"
  872 
  873 
  874 
  875 #line 949 "../../blib/lib/PDL/PP.pm"
  876 
  877 sub PDL::Complex::Carg($) {
  878            my $pdl= shift;
  879            my $arg = PDL->null;
  880            &PDL::Complex::_Carg_int($pdl, $arg);
  881            $arg;
  882         }
  883 #line 884 "Complex.pm"
  884 
  885 
  886 
  887 #line 950 "../../blib/lib/PDL/PP.pm"
  888 
  889 BEGIN {*Carg = \&PDL::Complex::Carg;
  890 }
  891 #line 892 "Complex.pm"
  892 
  893 
  894 
  895 #line 948 "../../blib/lib/PDL/PP.pm"
  896 
  897 
  898 
  899 =head2 Csin
  900 
  901 =for sig
  902 
  903   Signature: (a(m=2); [o]c(m=2))
  904 
  905 =for ref
  906 
  907   sin (a) = 1/(2*i) * (exp (a*i) - exp (-a*i)). Works inplace
  908 
  909 =for bad
  910 
  911 Csin does not process bad values.
  912 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  913 
  914 
  915 =cut
  916 #line 917 "Complex.pm"
  917 
  918 
  919 
  920 #line 950 "../../blib/lib/PDL/PP.pm"
  921 
  922 BEGIN {*Csin = \&PDL::Complex::Csin;
  923 }
  924 #line 925 "Complex.pm"
  925 
  926 
  927 
  928 #line 948 "../../blib/lib/PDL/PP.pm"
  929 
  930 
  931 
  932 =head2 Ccos
  933 
  934 =for sig
  935 
  936   Signature: (a(m=2); [o]c(m=2))
  937 
  938 =for ref
  939 
  940   cos (a) = 1/2 * (exp (a*i) + exp (-a*i)). Works inplace
  941 
  942 =for bad
  943 
  944 Ccos does not process bad values.
  945 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  946 
  947 
  948 =cut
  949 #line 950 "Complex.pm"
  950 
  951 
  952 
  953 #line 950 "../../blib/lib/PDL/PP.pm"
  954 
  955 BEGIN {*Ccos = \&PDL::Complex::Ccos;
  956 }
  957 #line 958 "Complex.pm"
  958 
  959 
  960 
  961 #line 687 "complex.pd"
  962 
  963 
  964 =head2 Ctan
  965 
  966 =for ref
  967 
  968 Complex tangent
  969 
  970   tan (a) = -i * (exp (a*i) - exp (-a*i)) / (exp (a*i) + exp (-a*i))
  971 
  972 Does not work inplace.
  973 
  974 =cut
  975 
  976 sub Ctan($) { Csin($_[0]) / Ccos($_[0]) }
  977 #line 978 "Complex.pm"
  978 
  979 
  980 
  981 #line 948 "../../blib/lib/PDL/PP.pm"
  982 
  983 
  984 
  985 =head2 Cexp
  986 
  987 =for sig
  988 
  989   Signature: (a(m=2); [o]c(m=2))
  990 
  991 =for ref
  992 
  993   exp (a) = exp (real (a)) * (cos (imag (a)) + i * sin (imag (a))). Works inplace
  994 
  995 =for bad
  996 
  997 Cexp does not process bad values.
  998 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  999 
 1000 
 1001 =cut
 1002 #line 1003 "Complex.pm"
 1003 
 1004 
 1005 
 1006 #line 950 "../../blib/lib/PDL/PP.pm"
 1007 
 1008 BEGIN {*Cexp = \&PDL::Complex::Cexp;
 1009 }
 1010 #line 1011 "Complex.pm"
 1011 
 1012 
 1013 
 1014 #line 948 "../../blib/lib/PDL/PP.pm"
 1015 
 1016 
 1017 
 1018 =head2 Clog
 1019 
 1020 =for sig
 1021 
 1022   Signature: (a(m=2); [o]c(m=2))
 1023 
 1024 =for ref
 1025 
 1026   log (a) = log (cabs (a)) + i * carg (a). Works inplace
 1027 
 1028 =for bad
 1029 
 1030 Clog does not process bad values.
 1031 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1032 
 1033 
 1034 =cut
 1035 #line 1036 "Complex.pm"
 1036 
 1037 
 1038 
 1039 #line 950 "../../blib/lib/PDL/PP.pm"
 1040 
 1041 BEGIN {*Clog = \&PDL::Complex::Clog;
 1042 }
 1043 #line 1044 "Complex.pm"
 1044 
 1045 
 1046 
 1047 #line 948 "../../blib/lib/PDL/PP.pm"
 1048 
 1049 
 1050 
 1051 =head2 Cpow
 1052 
 1053 =for sig
 1054 
 1055   Signature: (a(m=2); b(m=2); [o]c(m=2))
 1056 
 1057 =for ref
 1058 
 1059 complex C<pow()> (C<**>-operator)
 1060 
 1061 =for bad
 1062 
 1063 Cpow does not process bad values.
 1064 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1065 
 1066 
 1067 =cut
 1068 #line 1069 "Complex.pm"
 1069 
 1070 
 1071 
 1072 #line 950 "../../blib/lib/PDL/PP.pm"
 1073 
 1074 BEGIN {*Cpow = \&PDL::Complex::Cpow;
 1075 }
 1076 #line 1077 "Complex.pm"
 1077 
 1078 
 1079 
 1080 #line 948 "../../blib/lib/PDL/PP.pm"
 1081 
 1082 
 1083 
 1084 =head2 Csqrt
 1085 
 1086 =for sig
 1087 
 1088   Signature: (a(m=2); [o]c(m=2))
 1089 
 1090 =for ref
 1091 
 1092 Works inplace
 1093 
 1094 =for bad
 1095 
 1096 Csqrt does not process bad values.
 1097 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1098 
 1099 
 1100 =cut
 1101 #line 1102 "Complex.pm"
 1102 
 1103 
 1104 
 1105 #line 950 "../../blib/lib/PDL/PP.pm"
 1106 
 1107 BEGIN {*Csqrt = \&PDL::Complex::Csqrt;
 1108 }
 1109 #line 1110 "Complex.pm"
 1110 
 1111 
 1112 
 1113 #line 948 "../../blib/lib/PDL/PP.pm"
 1114 
 1115 
 1116 
 1117 =head2 Casin
 1118 
 1119 =for sig
 1120 
 1121   Signature: (a(m=2); [o]c(m=2))
 1122 
 1123 =for ref
 1124 
 1125 Works inplace
 1126 
 1127 =for bad
 1128 
 1129 Casin does not process bad values.
 1130 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1131 
 1132 
 1133 =cut
 1134 #line 1135 "Complex.pm"
 1135 
 1136 
 1137 
 1138 #line 950 "../../blib/lib/PDL/PP.pm"
 1139 
 1140 BEGIN {*Casin = \&PDL::Complex::Casin;
 1141 }
 1142 #line 1143 "Complex.pm"
 1143 
 1144 
 1145 
 1146 #line 948 "../../blib/lib/PDL/PP.pm"
 1147 
 1148 
 1149 
 1150 =head2 Cacos
 1151 
 1152 =for sig
 1153 
 1154   Signature: (a(m=2); [o]c(m=2))
 1155 
 1156 =for ref
 1157 
 1158 Works inplace
 1159 
 1160 =for bad
 1161 
 1162 Cacos does not process bad values.
 1163 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1164 
 1165 
 1166 =cut
 1167 #line 1168 "Complex.pm"
 1168 
 1169 
 1170 
 1171 #line 950 "../../blib/lib/PDL/PP.pm"
 1172 
 1173 BEGIN {*Cacos = \&PDL::Complex::Cacos;
 1174 }
 1175 #line 1176 "Complex.pm"
 1176 
 1177 
 1178 
 1179 #line 834 "complex.pd"
 1180 
 1181 
 1182 =head2 Catan
 1183 
 1184 =for ref
 1185 
 1186 Return the complex C<atan()>.
 1187 
 1188 Does not work inplace.
 1189 
 1190 =cut
 1191 
 1192 sub Catan($) {
 1193    my $z = shift;
 1194    Cmul Clog(Cdiv (PDL::Complex::i()+$z, PDL::Complex::i()-$z)), pdl(0, 0.5);
 1195 }
 1196 #line 1197 "Complex.pm"
 1197 
 1198 
 1199 
 1200 #line 948 "../../blib/lib/PDL/PP.pm"
 1201 
 1202 
 1203 
 1204 =head2 Csinh
 1205 
 1206 =for sig
 1207 
 1208   Signature: (a(m=2); [o]c(m=2))
 1209 
 1210 =for ref
 1211 
 1212   sinh (a) = (exp (a) - exp (-a)) / 2. Works inplace
 1213 
 1214 =for bad
 1215 
 1216 Csinh does not process bad values.
 1217 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1218 
 1219 
 1220 =cut
 1221 #line 1222 "Complex.pm"
 1222 
 1223 
 1224 
 1225 #line 950 "../../blib/lib/PDL/PP.pm"
 1226 
 1227 BEGIN {*Csinh = \&PDL::Complex::Csinh;
 1228 }
 1229 #line 1230 "Complex.pm"
 1230 
 1231 
 1232 
 1233 #line 948 "../../blib/lib/PDL/PP.pm"
 1234 
 1235 
 1236 
 1237 =head2 Ccosh
 1238 
 1239 =for sig
 1240 
 1241   Signature: (a(m=2); [o]c(m=2))
 1242 
 1243 =for ref
 1244 
 1245   cosh (a) = (exp (a) + exp (-a)) / 2. Works inplace
 1246 
 1247 =for bad
 1248 
 1249 Ccosh does not process bad values.
 1250 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1251 
 1252 
 1253 =cut
 1254 #line 1255 "Complex.pm"
 1255 
 1256 
 1257 
 1258 #line 950 "../../blib/lib/PDL/PP.pm"
 1259 
 1260 BEGIN {*Ccosh = \&PDL::Complex::Ccosh;
 1261 }
 1262 #line 1263 "Complex.pm"
 1263 
 1264 
 1265 
 1266 #line 948 "../../blib/lib/PDL/PP.pm"
 1267 
 1268 
 1269 
 1270 =head2 Ctanh
 1271 
 1272 =for sig
 1273 
 1274   Signature: (a(m=2); [o]c(m=2))
 1275 
 1276 =for ref
 1277 
 1278 Works inplace
 1279 
 1280 =for bad
 1281 
 1282 Ctanh does not process bad values.
 1283 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1284 
 1285 
 1286 =cut
 1287 #line 1288 "Complex.pm"
 1288 
 1289 
 1290 
 1291 #line 950 "../../blib/lib/PDL/PP.pm"
 1292 
 1293 BEGIN {*Ctanh = \&PDL::Complex::Ctanh;
 1294 }
 1295 #line 1296 "Complex.pm"
 1296 
 1297 
 1298 
 1299 #line 948 "../../blib/lib/PDL/PP.pm"
 1300 
 1301 
 1302 
 1303 =head2 Casinh
 1304 
 1305 =for sig
 1306 
 1307   Signature: (a(m=2); [o]c(m=2))
 1308 
 1309 =for ref
 1310 
 1311 Works inplace
 1312 
 1313 =for bad
 1314 
 1315 Casinh does not process bad values.
 1316 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1317 
 1318 
 1319 =cut
 1320 #line 1321 "Complex.pm"
 1321 
 1322 
 1323 
 1324 #line 950 "../../blib/lib/PDL/PP.pm"
 1325 
 1326 BEGIN {*Casinh = \&PDL::Complex::Casinh;
 1327 }
 1328 #line 1329 "Complex.pm"
 1329 
 1330 
 1331 
 1332 #line 948 "../../blib/lib/PDL/PP.pm"
 1333 
 1334 
 1335 
 1336 =head2 Cacosh
 1337 
 1338 =for sig
 1339 
 1340   Signature: (a(m=2); [o]c(m=2))
 1341 
 1342 =for ref
 1343 
 1344 Works inplace
 1345 
 1346 =for bad
 1347 
 1348 Cacosh does not process bad values.
 1349 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1350 
 1351 
 1352 =cut
 1353 #line 1354 "Complex.pm"
 1354 
 1355 
 1356 
 1357 #line 950 "../../blib/lib/PDL/PP.pm"
 1358 
 1359 BEGIN {*Cacosh = \&PDL::Complex::Cacosh;
 1360 }
 1361 #line 1362 "Complex.pm"
 1362 
 1363 
 1364 
 1365 #line 948 "../../blib/lib/PDL/PP.pm"
 1366 
 1367 
 1368 
 1369 =head2 Catanh
 1370 
 1371 =for sig
 1372 
 1373   Signature: (a(m=2); [o]c(m=2))
 1374 
 1375 =for ref
 1376 
 1377 Works inplace
 1378 
 1379 =for bad
 1380 
 1381 Catanh does not process bad values.
 1382 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1383 
 1384 
 1385 =cut
 1386 #line 1387 "Complex.pm"
 1387 
 1388 
 1389 
 1390 #line 950 "../../blib/lib/PDL/PP.pm"
 1391 
 1392 BEGIN {*Catanh = \&PDL::Complex::Catanh;
 1393 }
 1394 #line 1395 "Complex.pm"
 1395 
 1396 
 1397 
 1398 #line 948 "../../blib/lib/PDL/PP.pm"
 1399 
 1400 
 1401 
 1402 =head2 Cproj
 1403 
 1404 =for sig
 1405 
 1406   Signature: (a(m=2); [o]c(m=2))
 1407 
 1408 =for ref
 1409 
 1410 compute the projection of a complex number to the riemann sphere. Works inplace
 1411 
 1412 =for bad
 1413 
 1414 Cproj does not process bad values.
 1415 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1416 
 1417 
 1418 =cut
 1419 #line 1420 "Complex.pm"
 1420 
 1421 
 1422 
 1423 #line 950 "../../blib/lib/PDL/PP.pm"
 1424 
 1425 BEGIN {*Cproj = \&PDL::Complex::Cproj;
 1426 }
 1427 #line 1428 "Complex.pm"
 1428 
 1429 
 1430 
 1431 #line 948 "../../blib/lib/PDL/PP.pm"
 1432 
 1433 
 1434 
 1435 =head2 Croots
 1436 
 1437 =for sig
 1438 
 1439   Signature: (a(m=2); [o]c(m=2,n); int n => n)
 1440 
 1441 =for ref
 1442 
 1443 Compute the C<n> roots of C<a>. C<n> must be a positive integer. The result will always be a complex type!
 1444 
 1445 =for bad
 1446 
 1447 Croots does not process bad values.
 1448 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1449 
 1450 
 1451 =cut
 1452 #line 1453 "Complex.pm"
 1453 
 1454 
 1455 
 1456 #line 949 "../../blib/lib/PDL/PP.pm"
 1457 
 1458 sub PDL::Complex::Croots($$) {
 1459            my ($pdl, $n) = @_;
 1460            my $r = PDL->null;
 1461            &PDL::Complex::_Croots_int($pdl, $r, $n);
 1462            bless $r;
 1463         }
 1464 #line 1465 "Complex.pm"
 1465 
 1466 
 1467 
 1468 #line 950 "../../blib/lib/PDL/PP.pm"
 1469 
 1470 BEGIN {*Croots = \&PDL::Complex::Croots;
 1471 }
 1472 #line 1473 "Complex.pm"
 1473 
 1474 
 1475 
 1476 #line 1002 "complex.pd"
 1477 
 1478 
 1479 =head2 re, im
 1480 
 1481 Return the real or imaginary part of the complex number(s) given.
 1482 
 1483 These are slicing operators, so data flow works. The real and
 1484 imaginary parts are returned as ndarrays (ref eq PDL).
 1485 
 1486 =cut
 1487 
 1488 sub re($) { $_[0]->slice("(0)") }
 1489 sub im($) { $_[0]->slice("(1)") }
 1490 
 1491 {
 1492 no warnings 'redefine';
 1493 # if the argument does anything other than pass through 0-th dim, re-bless
 1494 sub slice :lvalue {
 1495   my $first = ref $_[1] ? $_[1][0] : (split ',', $_[1])[0];
 1496   my $class = ($first//'') =~ /^[:x]?$/i ? ref($_[0]) : 'PDL';
 1497   my $ret = bless $_[0]->SUPER::slice(@_[1..$#_]), $class;
 1498   $ret;
 1499 }
 1500 }
 1501 #line 1502 "Complex.pm"
 1502 
 1503 
 1504 
 1505 #line 948 "../../blib/lib/PDL/PP.pm"
 1506 
 1507 
 1508 
 1509 =head2 rCpolynomial
 1510 
 1511 =for sig
 1512 
 1513   Signature: (coeffs(n); x(c=2,m); [o]out(c=2,m))
 1514 
 1515 =for ref
 1516 
 1517 evaluate the polynomial with (real) coefficients C<coeffs> at the (complex) position(s) C<x>. C<coeffs[0]> is the constant term.
 1518 
 1519 =for bad
 1520 
 1521 rCpolynomial does not process bad values.
 1522 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1523 
 1524 
 1525 =cut
 1526 #line 1527 "Complex.pm"
 1527 
 1528 
 1529 
 1530 #line 949 "../../blib/lib/PDL/PP.pm"
 1531 
 1532 
 1533 sub rCpolynomial {
 1534     my $coeffs = shift;
 1535     my $x = shift;
 1536     my $out = $x->copy;
 1537     _rCpolynomial_int($coeffs,$x,$out);
 1538     return PDL::complex($out);
 1539     }
 1540 #line 1541 "Complex.pm"
 1541 
 1542 
 1543 
 1544 #line 950 "../../blib/lib/PDL/PP.pm"
 1545 
 1546 BEGIN {*rCpolynomial = \&PDL::Complex::rCpolynomial;
 1547 }
 1548 #line 1549 "Complex.pm"
 1549 
 1550 
 1551 
 1552 
 1553 
 1554 #line 1067 "complex.pd"
 1555 
 1556 
 1557 # overload must be here, so that all the functions can be seen
 1558 
 1559 # undocumented compatibility functions (thanks to Luis Mochan!)
 1560 sub Catan2($$) { Clog( $_[1] + i()*$_[0])/i }
 1561 sub atan2($$) { Clog( $_[1] + i()*$_[0])/i }
 1562 
 1563 
 1564 =begin comment
 1565 
 1566 In _gen_biop, the '+' or '-' between the operator (e.g., '*') and the
 1567 function that it overloads (e.g., 'Cmul') flags whether the operation
 1568 is ('+') or is not ('-') commutative. See the discussion of argument
 1569 swapping in the section "Calling Conventions and Magic Autogeneration"
 1570 in "perldoc overload".
 1571 
 1572 =end comment
 1573 
 1574 =cut
 1575 
 1576 my %NO_MUTATE; BEGIN { @NO_MUTATE{qw(atan2 .= ==)} = (); }
 1577 sub _gen_biop {
 1578    local $_ = shift;
 1579    my $sub;
 1580    if (/(\S+)\+(\w+)/) { #commutes
 1581       $sub = eval 'sub { '.$2.' $_[0], ref $_[1] eq __PACKAGE__ ? $_[1] : r2C $_[1] }';
 1582    } elsif (/(\S+)\-(\w+)/) { #does not commute
 1583       $sub = eval 'sub { my $y = ref $_[1] eq __PACKAGE__ ? $_[1] : r2C $_[1];
 1584                        $_[2] ? '.$2.' $y, $_[0] : '.$2.' $_[0], $y }'; #need to swap?
 1585    } else {
 1586       die;
 1587    }
 1588    return ($1, $sub) if exists $NO_MUTATE{$1};
 1589    ($1, $sub, "$1=", $sub);
 1590 }
 1591 
 1592 sub _gen_unop {
 1593    my ($op, $func) = ($_[0] =~ /(.+)@(\w+)/);
 1594    no strict 'refs';
 1595    *$op = \&$func if $op =~ /\w+/; # create an alias
 1596    ($op, eval 'sub { '.$func.' $_[0] }');
 1597 }
 1598 
 1599 sub initialize {
 1600    # Bless a null PDL into the supplied 1st arg package
 1601    #   If 1st arg is a ref, get the package from it
 1602    bless PDL->null, ref($_[0]) || $_[0];
 1603 }
 1604 
 1605 # so broadcasting doesn't also assign the real value into the imaginary
 1606 sub Cassgn {
 1607     my @args = !$_[2] ? @_[1,0] : @_[0,1];
 1608     $args[1] = r2C($args[1]) if ref $args[1] ne __PACKAGE__;
 1609     PDL::Ops::assgn(@args);
 1610     $args[1];
 1611 }
 1612 
 1613 use overload
 1614    (map _gen_biop($_), qw(++Cadd --Csub *+Cmul /-Cdiv **-Cpow atan2-Catan2 ==+Ceq .=-Cassgn)),
 1615    (map _gen_unop($_), qw(sin@Csin cos@Ccos exp@Cexp abs@Cabs log@Clog sqrt@Csqrt)),
 1616    (map +($_ => sub { confess "Can't compare complex numbers" }), qw(< > <= >=)),
 1617    "!=" => sub { !($_[0] == $_[1]) },
 1618    '""' => sub { $_[0]->isnull ? "PDL::Complex->null" : $_[0]->as_native->string },
 1619 ;
 1620 
 1621 sub sum {
 1622   my($x) = @_;
 1623   return $x if $x->dims==1;
 1624   my $tmp = $x->mv(0,-1)->clump(-2)->mv(1,0)->sumover;
 1625   return $tmp;
 1626 }
 1627 
 1628 sub sumover{
 1629   my $m = shift;
 1630   PDL::Ufunc::sumover($m->transpose);
 1631 }
 1632 
 1633 *PDL::Complex::Csumover=\&sumover; # define through alias
 1634 
 1635 *PDL::Complex::prodover=\&Cprodover; # define through alias
 1636 
 1637 sub prod {
 1638   my($x) = @_;
 1639   return $x if $x->dims==1;
 1640   my $tmp = $x->mv(0,-1)->clump(-2)->mv(1,0)->prodover;
 1641   return $tmp;
 1642 }
 1643 
 1644 =head1 AUTHOR
 1645 
 1646 Copyright (C) 2000 Marc Lehmann <pcg@goof.com>.
 1647 All rights reserved. There is no warranty. You are allowed
 1648 to redistribute this software / documentation as described
 1649 in the file COPYING in the PDL distribution.
 1650 
 1651 =head1 SEE ALSO
 1652 
 1653 perl(1), L<PDL>.
 1654 
 1655 =cut
 1656 #line 1657 "Complex.pm"
 1657 
 1658 
 1659 
 1660 
 1661 # Exit with OK status
 1662 
 1663 1;