PDLA-Core
view release on metacpan or search on metacpan
GENERATED/PDLA/Complex.pm view on Meta::CPAN
0 ## *** # * # ++
| * # * # |
| *** # ** # |
| * # * # |
-5 ++ ** # * # ++
| *** ## ** # |
| * #* # |
| **** ***## # |
-10 ++ **** # # ++
| # # |
| ## ## |
+ + + + + + + ### + ### + + +
-15 ++-----+------+------+------+------+------+-----###-----+------+-----++
0 5 10 15 20 25 30 35 40 45 50
=head1 OPERATORS
The following operators are overloaded:
=over 4
=item +, += (addition)
=item -, -= (subtraction)
=item *, *= (multiplication; L<Cmul|/Cmul>)
=item /, /= (division; L<Cdiv|/Cdiv>)
=item **, **= (exponentiation; L<Cpow|/Cpow>)
=item atan2 (4-quadrant arc tangent)
=item <=> (nonsensical comparison operator; L<Ccmp|/Ccmp>)
=item sin (L<Csin|/Csin>)
=item cos (L<Ccos|/Ccos>)
=item exp (L<Cexp|/Cexp>)
=item abs (L<Cabs|/Cabs>)
=item log (L<Clog|/Clog>)
=item sqrt (L<Csqrt|/Csqrt>)
=item <, <=, ==, !=, >=, > (just as nonsensical as L<Ccmp|/Ccmp>)
=item ++, -- (increment, decrement; they affect the real part of the complex number only)
=item "" (stringification)
=back
=cut
my $i;
BEGIN { $i = bless pdl 0,1 }
sub i () { $i->copy };
=head1 FUNCTIONS
=cut
=head2 cplx
=for ref
Cast a real-valued piddle to the complex datatype.
The first dimension of the piddle must be of size 2. After this the
usual (complex) arithmetic operators are applied to this pdl, rather
than the normal elementwise pdl operators. Dataflow to the complex
parent works. Use C<sever> on the result if you don't want this.
=for usage
cplx($real_valued_pdl)
=head2 complex
=for ref
Cast a real-valued piddle to the complex datatype I<without> dataflow
and I<inplace>.
Achieved by merely reblessing a piddle. The first dimension of the
piddle must be of size 2.
=for usage
complex($real_valued_pdl)
=head2 real
=for ref
Cast a complex valued pdl back to the "normal" pdl datatype.
Afterwards the normal elementwise pdl operators are used in
operations. Dataflow to the real parent works. Use C<sever> on the
result if you don't want this.
=for usage
real($cplx_valued_pdl)
=cut
GENERATED/PDLA/Complex.pm view on Meta::CPAN
Cproj does not process bad values.
It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
=cut
BEGIN {*Cproj = \&PDLA::Complex::Cproj;
}
=head2 Croots
=for sig
Signature: (a(m=2); [o]c(m=2,n); int n => n)
=for ref
Compute the C<n> roots of C<a>. C<n> must be a positive integer. The result will always be a complex type!
=for bad
Croots does not process bad values.
It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
=cut
sub PDLA::Complex::Croots($$) {
my ($pdl, $n) = @_;
my $r = PDLA->null;
&PDLA::Complex::_Croots_int($pdl, $r, $n);
bless $r;
}
BEGIN {*Croots = \&PDLA::Complex::Croots;
}
=head2 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 are returned as piddles (ref eq PDLA).
=cut
sub re($) { bless $_[0]->slice("(0)"), 'PDLA'; }
sub im($) { bless $_[0]->slice("(1)"), 'PDLA'; }
*PDLA::Complex::re = \&re;
*PDLA::Complex::im = \&im;
=head2 rCpolynomial
=for sig
Signature: (coeffs(n); x(c=2,m); [o]out(c=2,m))
=for ref
evaluate the polynomial with (real) coefficients C<coeffs> at the (complex) position(s) C<x>. C<coeffs[0]> is the constant term.
=for bad
rCpolynomial does not process bad values.
It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
=cut
sub rCpolynomial {
my $coeffs = shift;
my $x = shift;
my $out = $x->copy;
_rCpolynomial_int($coeffs,$x,$out);
return PDLA::complex($out);
}
BEGIN {*rCpolynomial = \&PDLA::Complex::rCpolynomial;
}
;
# overload must be here, so that all the functions can be seen
# undocumented compatibility functions (thanks to Luis Mochan!)
sub Catan2($$) { Clog( $_[1] + i*$_[0])/i }
sub atan2($$) { Clog( $_[1] + i*$_[0])/i }
=begin comment
In _gen_biop, the '+' or '-' between the operator (e.g., '*') and the
function that it overloads (e.g., 'Cmul') flags whether the operation
is ('+') or is not ('-') commutative. See the discussion of argument
swapping in the section "Calling Conventions and Magic Autogeneration"
in "perldoc overload".
GENERATED/PDLA/Complex.pm view on Meta::CPAN
$sub = eval 'sub { my $y = ref $_[1] eq __PACKAGE__ ? $_[1] : r2C $_[1];
$_[2] ? '.$2.' $y, $_[0] : '.$2.' $_[0], $y }'; #need to swap?
} else {
die;
}
if($1 eq "atan2" || $1 eq "<=>") { return ($1, $sub) }
($1, $sub, "$1=", $sub);
}
sub _gen_unop {
my ($op, $func) = ($_[0] =~ /(.+)@(\w+)/);
*$op = \&$func if $op =~ /\w+/; # create an alias
($op, eval 'sub { '.$func.' $_[0] }');
}
#sub _gen_cpop {
# ($_[0], eval 'sub { my $y = ref $_[1] eq __PACKAGE__ ? $_[1] : r2C $_[1];
# ($_[2] ? $y <=> $_[0] : $_[0] <=> $y) '.$_[0].' 0 }');
#}
sub initialize {
# Bless a null PDLA into the supplied 1st arg package
# If 1st arg is a ref, get the package from it
bless PDLA->null, ref($_[0]) ? ref($_[0]) : $_[0];
}
use overload
(map _gen_biop($_), qw(++Cadd --Csub *+Cmul /-Cdiv **-Cpow atan2-Catan2 <=>-Ccmp)),
(map _gen_unop($_), qw(sin@Csin cos@Ccos exp@Cexp abs@Cabs log@Clog sqrt@Csqrt)),
# (map _gen_cpop($_), qw(< <= == != >= >)), #segfaults with infinite recursion of the operator.
#final ternary used to make result a scalar, not a PDLA:::Complex (thx CED!)
"<" => sub { my $y = ref $_[1] eq __PACKAGE__ ? $_[1] : r2C $_[1];
PDLA::lt( ($_[2] ? $y <=> $_[0] : $_[0] <=> $y), 0, 0) ? 1 : 0;},
"<=" => sub { my $y = ref $_[1] eq __PACKAGE__ ? $_[1] : r2C $_[1];
PDLA::le( ($_[2] ? $y <=> $_[0] : $_[0] <=> $y), 0, 0) ? 1 : 0;},
"==" => sub { my $y = ref $_[1] eq __PACKAGE__ ? $_[1] : r2C $_[1];
PDLA::eq( ($_[2] ? $y <=> $_[0] : $_[0] <=> $y), 0, 0) ? 1 : 0;},
"!=" => sub { my $y = ref $_[1] eq __PACKAGE__ ? $_[1] : r2C $_[1];
PDLA::ne( ($_[2] ? $y <=> $_[0] : $_[0] <=> $y), 0, 0) ? 1 : 0;},
">=" => sub { my $y = ref $_[1] eq __PACKAGE__ ? $_[1] : r2C $_[1];
PDLA::ge( ($_[2] ? $y <=> $_[0] : $_[0] <=> $y), 0, 0) ? 1 : 0;},
">" => sub { my $y = ref $_[1] eq __PACKAGE__ ? $_[1] : r2C $_[1];
PDLA::gt( ($_[2] ? $y <=> $_[0] : $_[0] <=> $y), 0, 0) ? 1 : 0;},
'++' => sub { $_[0] += 1 },
'--' => sub { $_[0] -= 1 },
'""' => \&PDLA::Complex::string
;
# overwrite PDLA's overloading to honour subclass methods in + - * /
{ package PDLA;
my $warningFlag;
# This strange usage of BEGINs is to ensure the
# warning messages get disabled and enabled in the
# proper order. Without the BEGIN's the 'use overload'
# would be called first.
BEGIN {$warningFlag = $^W; # Temporarily disable warnings caused by
$^W = 0; # redefining PDLA's subs
}
sub cp(;@) {
my $foo;
if (ref $_[1]
&& (ref $_[1] ne 'PDLA')
&& defined ($foo = overload::Method($_[1],'+')))
{ &$foo($_[1], $_[0], !$_[2])}
else { PDLA::plus (@_)}
}
sub cm(;@) {
my $foo;
if (ref $_[1]
&& (ref $_[1] ne 'PDLA')
&& defined ($foo = overload::Method($_[1],'*')))
{ &$foo($_[1], $_[0], !$_[2])}
else { PDLA::mult (@_)}
}
sub cmi(;@) {
my $foo;
if (ref $_[1]
&& (ref $_[1] ne 'PDLA')
&& defined ($foo = overload::Method($_[1],'-')))
{ &$foo($_[1], $_[0], !$_[2])}
else { PDLA::minus (@_)}
}
sub cd(;@) {
my $foo;
if (ref $_[1]
&& (ref $_[1] ne 'PDLA')
&& defined ($foo = overload::Method($_[1],'/')))
{ &$foo($_[1], $_[0], !$_[2])}
else { PDLA::divide (@_)}
}
# Used in overriding standard PDLA +, -, *, / ops in the complex subclass.
use overload (
'+' => \&cp,
'*' => \&cm,
'-' => \&cmi,
'/' => \&cd,
);
BEGIN{ $^W = $warningFlag;} # Put Back Warnings
};
{
our $floatformat = "%4.4g"; # Default print format for long numbers
our $doubleformat = "%6.6g";
$PDLA::Complex::_STRINGIZING = 0;
sub PDLA::Complex::string {
my($self,$format1,$format2)=@_;
my @dims = $self->dims;
return PDLA::string($self) if ($dims[0] != 2);
if($PDLA::Complex::_STRINGIZING) {
return "ALREADY_STRINGIZING_NO_LOOPS";
}
local $PDLA::Complex::_STRINGIZING = 1;
my $ndims = $self->getndims;
if($self->nelem > $PDLA::toolongtoprint) {
return "TOO LONG TO PRINT";
}
if ($ndims==0){
PDLA::Core::string($self,$format1);
}
return "Null" if $self->isnull;
return "Empty" if $self->isempty; # Empty piddle
local $sep = $PDLA::use_commas ? ", " : " ";
local $sep2 = $PDLA::use_commas ? ", " : "";
if ($ndims < 3) {
return str1D($self,$format1,$format2);
}
else{
return strND($self,$format1,$format2,0);
}
}
sub sum {
( run in 2.109 seconds using v1.01-cache-2.11-cpan-e1769b4cff6 )