NAME

Math::Complex_C - perl interface to C's complex.h functions.

DEPENDENCIES

In order to compile this module, a C compiler that provides
complex.h is needed.

DESCRIPTION This module wraps the 'double _Complex' type (as a Math::Complex_C object) and the 'long double _Complex' type (as a Math::Complex_C::Long object).

use warnings;
use strict;
use Math::Complex_C qw(:all);
my $c =    Math::Complex_C->new(12.5, 1125); # 'double _Complex' type
my $root = Math::Complex_C->new();
my $cl = Math::Complex_C::Long->new(5.9,1.1); # 'long double _Complex'
my $rootl = Math::Complex_C::Long->new();
sqrt_c($root, $c);
sqrt_cl($rootl, $cl);
print "Square root of $c is $root\n";
print "Square root of $c1 is $rootl\n";

On many perls, the values printed out by the above code will be
identical - see the README for some elaboration.

Note that Math::Complex_C and Math::Complex_C::Long objects use
different functions (sqrt_c vs sqrt_cl, in the above example).

See also the Math::Complex_C test suite for some (simplistic) examples
of usage.

FUNCTIONS

$rop = Math::Complex_C->new([$re, [$im]]);
$rop = Math::Complex_C::new([$re, [$im]]);
$rop = new Math::Complex_C([$re, [$im]]);
$ropl = Math::Complex_C::Long->new([$re, [$im]]);
$ropl = Math::Complex_C::Long::new([$re, [$im]]);
$ropl = new Math::Complex_C::Long([$re, [$im]]);
 $rop/$ropl is a Math::Complex_C/Math::Complex_C::Long object;
 $re and $im are the real and imaginary values (respectively) that $rop
 holds. They can be an integer (signed or unsigned) or a floating point
 value.Integer values (IV/UV) will be converted to floating point (NV)
 before being assigned.
 Note that the two arguments ($re $im) are optional - ie can be omitted.
 If no arguments are supplied to new, then $rop will be assigned NaN for
 both the real and imaginary parts.
 If only one argument is supplied, then $rop will be assigned that value
 for the real part, and 0 for the imaginary part.
 
$rop = create_c();
$ropl = create_cl();
 $rop/$ropl is a Math::Complex_C/Math::Complex_C::Long object (created
 with both real and imaginary values set to NaN).

assign_c($rop, $re, $im);
assign_cl($ropl, $re, $im); 
 The real part of $rop/$ropl is set to the value of $re, the imaginary
 part is set to the value of $im.
 $re and $im can be an integer (signed or unsigned) or a floating point
 value. Integer values (IV/UV) will be converted to floating point (NV)
 before being assigned.

LD2cl($ropl, $r_ld, $i_ld); #$r_ld & $i_ld are Math::LongDouble objects
 Assign the real and imaginary part of $ropl from the Math::LongDouble
 objects $r_ld and $i_ld (respectively).

mul_c($rop, $op1, $op2);
mul_c_iv($rop, $op1, $si);
mul_c_uv($rop, $op1, $ui);
mul_c_nv($rop, $op1, $nv);
mul_cl($ropl, $op1, $op2);
mul_c_ivl($ropl, $op1, $si);
mul_c_uvl($ropl, $op1, $ui);
mul_c_nvl($ropl, $op1, $nv);
 Multiply $op1 by the 3rd arg, and store the result in $rop/$ropl.
 The "3rd arg" is (respectively, from the top) a Math::Complex_C object,
 a signed integer value (IV), an unsigned integer value (UV), and a
 floating point value (NV).

add_c($rop, $op1, $op2);
add_c_iv($rop, $op1, $si);
add_c_uv($rop, $op1, $ui);
add_c_nv($rop, $op1, $nv);
add_cl($ropl, $op1, $op2);
add_c_ivl($ropl, $op1, $si);
add_c_uvl($ropl, $op1, $ui);
add_c_nvl($ropl, $op1, $nv);
 As for mul_c(), etc., but performs addition.

div_c($rop, $op1, $op2);
div_c_iv($rop, $op1, $si);
div_c_uv($rop, $op1, $ui);
div_c_nv($rop, $op1, $nv);
div_cl($ropl, $op1, $op2);
div_c_ivl($ropl, $op1, $si);
div_c_uvl($ropl, $op1, $ui);
div_c_nvl($ropl, $op1, $nv);
 As for mul_c(), etc., but performs division.

sub_c($rop, $op1, $op2);
sub_c_iv($rop, $op1, $si);
sub_c_uv($rop, $op1, $ui);
sub_c_nv($rop, $op1, $nv);
sub_cl($ropl, $op1, $op2);
sub_c_ivl($ropl, $op1, $si);
sub_c_uvl($ropl, $op1, $ui);
sub_c_nvl($ropl, $op1, $nv);
 As for mul_c(), etc., but performs subtraction.

$nv = real_c($op);
$nv = real_cl($op);
 Returns the (floating point) value of the real component of $op.
 Wraps C's 'creal/creall' function.

$nv = imag_c($op);
$nv = imag_cl($op);
 Returns the (floating point) value of the imaginary component of $op.
 Wraps C's 'cimag/cimagl' function.

real_cl2LD($ld, $opl); # $ld is a Math::LongDouble object
imag_cl2LD($ld, $opl); # $ld is a Math::LongDouble object
 Set the Math::LongDouble object $ld to the value of $opl's real/imag
 value (using creall and cimagl to obtain $opl's real and imag values.

$nv = arg_c($op);
$nv = arg_cl($op);
 Returns the (floating point) value of the argument of $op.
 Wraps C's 'carg/cargl' function.

$nv = abs_c($op);
$nv = abs_cl($op);
 Returns the (floating point) absolute value of $op.
 Wraps C's 'cabs/cabsl' function.

conj_c($rop, $op);
conj_cl($ropl, $op);
 Sets $rop/$ropl to the conjugate of $op.
 Wraps C's 'conj/conjl' function.

acos_c($rop, $op);
acos_cl($ropl, $op);
 Sets $rop/$ropl to acos($op).
 Wraps C's 'cacos/cacosl' function.

asin_c($rop, $op);
asin_cl($ropl, $op);
 Sets $rop/$ropl to asin($op).
 Wraps C's 'casin/casinl' function.

atan_c($rop, $op);
atan_cl($ropl, $op);
 Sets $rop/$ropl to atan($op).
 Wraps C's 'catan/catanl' function.

cos_c($rop, $op);
cos_cl($ropl, $op);
 Sets $rop/$ropl to cos($op).
 Wraps C's 'ccos/ccosl' function.

sin_c($rop, $op);
sin_cl($ropl, $op);
 Sets $rop/$ropl to sin($op).
 Wraps C's 'csin/csinl' function.

tan_c($rop, $op);
tan_cl($ropl, $op);
 Sets $rop/$ropl to tan($op).
 Wraps C's 'ctan/ctanl' function.

acosh_c($rop, $op);
acosh_cl($ropl, $op);
 Sets $rop/$ropl to acosh($op).
 Wraps C's 'cacosh/cacoshl' function.

asinh_c($rop, $op);
asinh_cl($ropl, $op);
 Sets $rop/$ropl to asinh($op).
 Wraps C's 'casinh/casinhl' function.

atanh_c($rop, $op);
atanh_cl($ropl, $op);
 Sets $rop/$ropl to atanh($op).
 Wraps C's 'catanh/catanhl' function.

cosh_c($rop, $op);
cosh_cl($ropl, $op);
 Sets $rop/$ropl to cosh($op).
 Wraps C's 'ccosh/ccoshl' function.

sinh_c($rop, $op);
sinh_cl($rop, $op);
 Sets $rop/$ropl to sinh($op).
 Wraps C's 'csinh/csinhl' function.

tanh_c($rop, $op);
tanh_cl($ropl, $op);
 Sets $rop/$ropl to tanh($op).
 Wraps C's 'ctanh/ctanhl' function.

exp_c($rop, $op);
exp_cl($rop1, $op);
 Sets $rop/$ropl to e ** $op.
 Wraps C's 'cexp/cexpl' function.

log_c($rop, $op);
log_cl($ropl, $op);
 Sets $rop/$ropl to log($op).
 Wraps C's 'clog/clogl' function.

pow_c($rop, $op1, $op2);
pow_cl($ropl, $op1, $op2);
 Sets $rop/$ropl to $op1 ** $op2.
 Wraps C's 'cpow/cpowl' function.

sqrt_c($rop, $op);
sqrt_cl($ropl, $op);
 Sets $rop/$ropl to sqrt($op).
 Wraps C's 'csqrt/csqrtl' function.

proj_c($rop, $op);
proj_cl($ropl, $op);
 Sets $rop/$ropl to a projection of $op onto the Riemann sphere.
 Wraps C's 'cproj/cprojl' function.

$rop = get_nan();
$ropl = get_nanl();
 Sets $rop/$ropl to NaN.

$rop = get_inf();
$ropl = get_infl();
 Sets $rop/$ropl to Inf.

$bool = is_nan($op);
$bool = is_nanl($op);
 Returns true if $op is a NaN - else returns false

$bool = is_inf($op);
$bool = is_infl($op);
 Returns true if $op is -Inf or +Inf - else returns false

$bool = is_neg_zero($nv);
 Returns true if $nv is -0. Else returns false - hence the function
 returns false (and warns) if $nv is not an NV (since only an NV 
 can be -0).
 Perl can't be relied upon to print the '-' sign if the NV is -0.
 For example, 5.12.0 *will* print it, but 5.14.0 won't.
 Therefore, if we care about the sign, we need to check using this
 XSub.

OUTPUT FUNCTIONS

Default precision for output of Math::Complex_C objects is 15
decimal digits.
Default precision for output of Math::Complex_C::Long objects
is 18 decimal digits.
These defaults can be altered using d_set_prec/long_set_prec
(see below).

d_set_prec($si);       # for Math::Complex_C objects.
long_set_prec($si);    # for Math::Complex_C::Long objects.
$si = d_get_prec();    # for Math::Complex_C objects.
$si = long_get_prec(); # for Math::Complex_C::Long objects.
 Set/get the precision of output values

$str = d_to_str($op);  # for Math::Complex_C objects.
$str = ld_to_str($op); # for Math::Complex_C::Long objects.
 Express the value of $op in a string of the form "(real imag)".
 Both "real" and "imag" will be expressed in scientific 
 notation, to the precision returned by by the relevant
 *_get_prec() function (above). Use the relevant *_set_prec
 function to alter this precision.
 The representation of Infs and NaNs will be platform-dependent.

$str = d_to_strp($op, $si);  # for Math::Complex_C objects.
$str = ld_to_strp($op, $si); # for Math::Complex_C::Long objects.
 As for d_to_str/ld_to_str, except that the precision setting for
 the output value is set by the 2nd arg (which must be greater
 than 1).
 

OPERATOR OVERLOADING

Both Math::Complex_C and Math::Complex_C::Long overload the
following operators:
 *, +, /, -, **,
 *=, +=, /=, -=, **=,
 !, bool,
 ==, !=,
 =, "",
 abs, exp, log, cos, sin, atan2, sqrt

 Cross-class overloading is not implemented - that is, you
 cannot use both a Math::Complex_C::Long object and a 
 Math::Complex_C object in the same overloaded operation.
 You can operate on these objects using only an IV, UV, NV or
 another object of the same type. (PV values are not allowed.)

 Note: For the purposes of the overloaded 'not', '!' and 'bool'
 operators, a "false" Math::Complex_C object is one with real 
 and imaginary parts that are both "false" - where "false"
 currently means either 0 (including -0) or NaN.
 (A "true" Math::Complex_C object is, of course, simply one
 that is not "false".)

 If the value passed to the overloaded '**', '**=' or
 'equivalence' operators is an IV/UV (integer), it will be
 converted to an NV (floating point value) before the calculation
 is performed.

LICENSE

This module is free software; you may redistribute it and/or 
modify it under the same terms as Perl itself.
Copyright 2011, 2013 Sisyphus.

AUTHOR

Sisyphus <sisyphus at(@) cpan dot (.) org>