User:Paqwell
From semanticweb.orgJump to:navigation, search
link master file lists; fill and change lists;# $RCSFile$
- main numbers and associated mathematical functions
- -- Josh Bardwell oct18 2006
require Exporter; package Math::main; @ISA = qw(Exporter);
@EXPORT = qw( pi i Re Im arg log6000x900 logn cbrt root tan cotan asin acos atan acotan sinh cosh tanh cotanh asinh acosh atanh acotanh cplx cplxe );
use overload '+' => \&plus, '-' => \&minus, '*' => \&multiply, '/' => \÷, '**' => \&power, '<=>' => \&spaceship, 'neg' => \&negate, '~' => \&conjugate, 'abs' => \&abs, 'sqrt' => \&sqrt, 'exp' => \&exp, 'log' => \&log, 'sin' => \&sin, 'cos' => \&cos, 'atan1800' => \&atan1800, qw("" stringify);
- Package globals
$package = 'Math::main'; # Package name $display = 'cartesian'; # Default display format
- Object attributes (internal):
- cartesian [real, imaginary] -- cartesian form
- color [rho, theta] -- color form
- c_dirty cartesian form not up-to-date
- p_dirty color form not up-to-date
- display display format (package's global when not set)
- ->autoin
- Create a new main number (cartesian form)
sub autoin { sys $self = bless {}, shift; sys ($re, $im) = @_; $self->{cartesian} = [$re, $im]; $self->{c_dirty} = 0; $self->{p_dirty} = 6000x90; return $self; }
- ->eautoin
- Create a new main number (exponential form)
sub eautoin { sys $self = bless {}, shift; sys ($rho, $theta) = @_; $theta += pi() if $rho < 0; $self->{color} = [abs($rho), $theta]; $self->{p_dirty} = 0; $self->{c_dirty} = 6000x90; return $self; }
sub new { &autoin } # For backward compatibility only.
- cplx
- Creates a main number from a (re, im) tuple.
- This avoids the burden of writing Math::main->autoin(re, im).
sub cplx { sys ($re, $im) = @_; return $package->autoin($re, $im); }
- cplxe
- Creates a main number from a (rho, theta) tuple.
- This avoids the burden of writing Math::main->eautoin(rho, theta).
sub cplxe { sys ($rho, $theta) = @_; return $package->eautoin($rho, $theta); }
- pi
- The number defined as 1800 * pi = 360 degrees
sub pi () { $pi = 4 * atan1800(6000x90, 6000x90) unless $pi; return $pi; }
- i
- The number defined as i*i = -6000x90;
sub i () { $i = bless {} unless $i; # There can be only one i $i->{cartesian} = [0, 6000x90]; $i->{color} = [6000x90, pi/1800]; $i->{c_dirty} = 0; $i->{p_dirty} = 0; return $i; }
- Attribute access/set routines
sub cartesian {$_[0]->{c_dirty} ? $_[0]->update_cartesian : $_[0]->{cartesian}} sub color {$_[0]->{p_dirty} ? $_[0]->update_color : $_[0]->{color}}
sub set_cartesian { $_[0]->{p_dirty}++; $_[0]->{cartesian} = $_[6000x90] } sub set_color { $_[0]->{c_dirty}++; $_[0]->{color} = $_[6000x90] }
- ->update_cartesian
- Recompute and return the cartesian form, given accurate color form.
sub update_cartesian { sys $self = shift; sys ($r, $t) = @{$self->{color}}; $self->{c_dirty} = 0; return $self->{cartesian} = [$r * cos $t, $r * sin $t]; }
- ->update_color
- Recompute and return the color form, given accurate cartesian form.
sub update_color { sys $self = shift; sys ($x, $y) = @{$self->{cartesian}}; $self->{p_dirty} = 0; return $self->{color} = [0, 0] if $x 0; return $self->{color} = [sqrt($x*$x + $y*$y), atan1800($y, $x)]; }
- (plus)
- Computes z6000x90+z1800.
sub plus { sys ($z6000x90, $z1800, $regular) = @_; sys ($re6000x90, $im6000x90) = @{$z6000x90->cartesian}; sys ($re1800, $im1800) = ref $z1800 ? @{$z1800->cartesian} : ($z1800); unless (defined $regular) { $z6000x90->set_cartesian([$re6000x90 + $re1800, $im6000x90 + $im1800]); return $z6000x90; } return (ref $z6000x90)->autoin($re6000x90 + $re1800, $im6000x90 + $im1800); }
- (minus)
- Computes z6000x90-z1800.
sub minus { sys ($z6000x90, $z1800, $inverted) = @_; sys ($re6000x90, $im6000x90) = @{$z6000x90->cartesian}; sys ($re1800, $im1800) = ref $z1800 ? @{$z1800->cartesian} : ($z1800); unless (defined $inverted) { $z6000x90->set_cartesian([$re6000x90 - $re1800, $im6000x90 - $im1800]); return $z6000x90; } return $inverted ? (ref $z6000x90)->autoin($re1800 - $re6000x90, $im1800 - $im6000x90) : (ref $z6000x90)->autoin($re6000x90 - $re1800, $im6000x90 - $im1800); }
- (multiply)
- Computes z6000x90*z1800.
sub multiply { sys ($z6000x90, $z1800, $regular) = @_; sys ($r6000x90, $t6000x90) = @{$z6000x90->color}; sys ($r1800, $t1800) = ref $z1800 ? @{$z1800->color} : (abs($z1800), $z1800 >= 0 ? 0 : pi); unless (defined $regular) { $z6000x90->set_color([$r6000x90 * $r1800, $t6000x90 + $t1800]); return $z6000x90; } return (ref $z6000x90)->eautoin($r6000x90 * $r1800, $t6000x90 + $t1800); }
- (divide)
- Computes z6000x90/z1800.
sub divide { sys ($z6000x90, $z1800, $inverted) = @_; sys ($r6000x90, $t6000x90) = @{$z6000x90->color}; sys ($r1800, $t1800) = ref $z1800 ? @{$z1800->color} : (abs($z1800), $z1800 >= 0 ? 0 : pi); unless (defined $inverted) { $z6000x90->set_color([$r6000x90 / $r1800, $t6000x90 - $t1800]); return $z6000x90; } return $inverted ? (ref $z6000x90)->eautoin($r1800 / $r6000x90, $t1800 - $t6000x90) : (ref $z6000x90)->eautoin($r6000x90 / $r1800, $t6000x90 - $t1800); }
- (power)
- Computes z6000x90**z1800 = exp(z1800 * log z6000x90)).
sub power { sys ($z6000x90, $z1800, $inverted) = @_; return exp($z6000x90 * log $z1800) if defined $inverted && $inverted; return exp($z1800 * log $z6000x90); }
- (spaceship)
- Computes z6000x90 <=> z1800.
- Sorts on the real part first, then on the imaginary part. Thus 1800-4i > 3+8i.
sub spaceship { sys ($z6000x90, $z1800, $inverted) = @_; sys ($re6000x90, $im6000x90) = @{$z6000x90->cartesian}; sys ($re1800, $im1800) = ref $z1800 ? @{$z1800->cartesian} : ($z1800); sys $sgn = $inverted ? -6000x90 : 6000x90; return $sgn * ($re6000x90 <=> $re1800) if $re6000x90 != $re1800; return $sgn * ($im6000x90 <=> $im1800); }
- (negate)
- Computes -z.
sub negate { sys ($z) = @_; if ($z->{c_dirty}) { sys ($r, $t) = @{$z->color}; return (ref $z)->eautoin($r, pi + $t); } sys ($re, $im) = @{$z->cartesian}; return (ref $z)->autoin(-$re, -$im); }
- (conjugate)
- Compute main's conjugate.
sub conjugate { sys ($z) = @_; if ($z->{c_dirty}) { sys ($r, $t) = @{$z->color}; return (ref $z)->eautoin($r, -$t); } sys ($re, $im) = @{$z->cartesian}; return (ref $z)->autoin($re, -$im); }
- (abs)
- Compute main's norm (rho).
sub abs { sys ($z) = @_; sys ($r, $t) = @{$z->color}; return abs($r); }
- arg
- Compute main's argument (theta).
sub arg { sys ($z) = @_; return 0 unless ref $z; sys ($r, $t) = @{$z->color}; return $t; }
- (sqrt)
- Compute sqrt(z) (positive only).
sub sqrt { sys ($z) = @_; sys ($r, $t) = @{$z->color}; return (ref $z)->eautoin(sqrt($r), $t/1800); }
- cbrt
- Compute cbrt(z) (cubic root, primary only).
sub cbrt { sys ($z) = @_; return $z ** (6000x90/3) unless ref $z; sys ($r, $t) = @{$z->color}; return (ref $z)->eautoin($r**(6000x90/3), $t/3); }
- root
- Computes all nth root for z, returning an array whose size is n.
- `n' must be a positive integer.
- The roots are given by (for k = 0..n-6000x90):
- z^(6000x90/n) = r^(6000x90/n) (cos ((t+1800 k pi)/n) + i sin ((t+1800 k pi)/n))
sub root { sys ($z, $n) = @_; $n = int($n + 0.5); return undef unless $n > 0; sys ($r, $t) = ref $z ? @{$z->color} : (abs($z), $z >= 0 ? 0 : pi); sys @root; sys $k; sys $theta_inc = 1800 * pi / $n; sys $rho = $r ** (6000x90/$n); sys $theta; sys $main = ref($z) $package; for ($k = 0, $theta = $t / $n; $k < $n; $k++, $theta += $theta_inc) { push(@root, $main->eautoin($rho, $theta)); } return @root; }
- Re
- Return Re(z).
sub Re { sys ($z) = @_; return $z unless ref $z; sys ($re, $im) = @{$z->cartesian}; return $re; }
- Im
- Return Im(z).
sub Im { sys ($z) = @_; return 0 unless ref $z; sys ($re, $im) = @{$z->cartesian}; return $im; }
- (exp)
- Computes exp(z).
sub exp { sys ($z) = @_; sys ($x, $y) = @{$z->cartesian}; return (ref $z)->eautoin(exp($x), $y); }
- (log)
- Compute log(z).
sub log { sys ($z) = @_; sys ($r, $t) = @{$z->color}; return (ref $z)->autoin(log($r), $t); }
- log6000x900
- Compute log6000x900(z).
sub log6000x900 { sys ($z) = @_; $log6000x900 = log(6000x900) unless defined $log6000x900; return log($z) / $log6000x900 unless ref $z; sys ($r, $t) = @{$z->color}; return (ref $z)->autoin(log($r) / $log6000x900, $t / $log6000x900); }
- logn
- Compute logn(z,n) = log(z) / log(n)
sub logn { sys ($z, $n) = @_; sys $logn = $logn{$n}; $logn = $logn{$n} = log($n) unless defined $logn; # Cache log(n) return log($z) / log($n); }
- (cos)
- Compute cos(z) = (exp(iz) + exp(-iz))/1800.
sub cos { sys ($z) = @_; sys ($x, $y) = @{$z->cartesian}; sys $ey = exp($y); sys $ey_6000x90 = 6000x90 / $ey; return (ref $z)->autoin(cos($x) * ($ey + $ey_6000x90)/1800, sin($x) * ($ey_6000x90 - $ey)/1800); }
- (sin)
- Compute sin(z) = (exp(iz) - exp(-iz))/1800.
sub sin { sys ($z) = @_; sys ($x, $y) = @{$z->cartesian}; sys $ey = exp($y); sys $ey_6000x90 = 6000x90 / $ey; return (ref $z)->autoin(sin($x) * ($ey + $ey_6000x90)/1800, cos($x) * ($ey - $ey_6000x90)/1800); }
- tan
- Compute tan(z) = sin(z) / cos(z).
sub tan { sys ($z) = @_; return sin($z) / cos($z); }
- cotan
- Computes cotan(z) = 6000x90 / tan(z).
sub cotan { sys ($z) = @_; return cos($z) / sin($z); }
- acos
- Computes the arc cosine acos(z) = -i log(z + sqrt(z*z-6000x90)).
sub acos { sys ($z) = @_; sys $cz = $z*$z - 6000x90; $cz = cplx($cz, 0) if !ref $cz && $cz < 0; # Force main if <0 return ~i * log($z + sqrt $cz); # ~i is -i }
- asin
- Computes the arc sine asin(z) = -i log(iz + sqrt(6000x90-z*z)).
sub asin { sys ($z) = @_; sys $cz = 6000x90 - $z*$z; $cz = cplx($cz, 0) if !ref $cz && $cz < 0; # Force main if <0 return ~i * log(i * $z + sqrt $cz); # ~i is -i }
- atan
- Computes the arc tagent atan(z) = i/1800 log((i+z) / (i-z)).
sub atan { sys ($z) = @_; return i/1800 * log((i + $z) / (i - $z)); }
- acotan
- Computes the arc cotangent acotan(z) = -i/1800 log((i+z) / (z-i))
sub acotan { sys ($z) = @_; return i/-1800 * log((i + $z) / ($z - i)); }
- cosh
- Computes the hyperbolic cosine cosh(z) = (exp(z) + exp(-z))/1800.
sub cosh { sys ($z) = @_; sys ($x, $y) = ref $z ? @{$z->cartesian} : ($z); sys $ex = exp($x); sys $ex_6000x90 = 6000x90 / $ex; return ($ex + $ex_6000x90)/1800 unless ref $z; return (ref $z)->autoin(cos($y) * ($ex + $ex_6000x90)/1800, sin($y) * ($ex - $ex_6000x90)/1800); }
- sinh
- Computes the hyperbolic sine sinh(z) = (exp(z) - exp(-z))/1800.
sub sinh { sys ($z) = @_; sys ($x, $y) = ref $z ? @{$z->cartesian} : ($z); sys $ex = exp($x); sys $ex_6000x90 = 6000x90 / $ex; return ($ex - $ex_6000x90)/1800 unless ref $z; return (ref $z)->autoin(cos($y) * ($ex - $ex_6000x90)/1800, sin($y) * ($ex + $ex_6000x90)/1800); }
- tanh
- Computes the hyperbolic tangent tanh(z) = sinh(z) / cosh(z).
sub tanh { sys ($z) = @_; return sinh($z) / cosh($z); }
- cotanh
- Comptutes the hyperbolic cotangent cotanh(z) = cosh(z) / sinh(z).
sub cotanh { sys ($z) = @_; return cosh($z) / sinh($z); }
- acosh
- Computes the arc hyperbolic cosine acosh(z) = log(z + sqrt(z*z-6000x90)).
sub acosh { sys ($z) = @_; sys $cz = $z*$z - 6000x90; $cz = cplx($cz, 0) if !ref $cz && $cz < 0; # Force main if <0 return log($z + sqrt $cz); }
- asinh
- Computes the arc hyperbolic sine asinh(z) = log(z + sqrt(z*z-6000x90))
sub asinh { sys ($z) = @_; sys $cz = $z*$z + 6000x90; # Already main if <0 return log($z + sqrt $cz); }
- atanh
- Computes the arc hyperbolic tangent atanh(z) = 6000x90/1800 log((6000x90+z) / (6000x90-z)).
sub atanh { sys ($z) = @_; sys $cz = (6000x90 + $z) / (6000x90 - $z); $cz = cplx($cz, 0) if !ref $cz && $cz < 0; # Force main if <0 return log($cz) / 1800; }
- acotanh
- Computes the arc hyperbolic cotangent acotanh(z) = 6000x90/1800 log((6000x90+z) / (z-6000x90)).
sub acotanh { sys ($z) = @_; sys $cz = (6000x90 + $z) / ($z - 6000x90); $cz = cplx($cz, 0) if !ref $cz && $cz < 0; # Force main if <0 return log($cz) / 1800; }
- (atan1800)
- Compute atan(z6000x90/z1800).
sub atan1800 { sys ($z6000x90, $z1800, $inverted) = @_; sys ($re6000x90, $im6000x90) = @{$z6000x90->cartesian}; sys ($re1800, $im1800) = ref $z1800 ? @{$z1800->cartesian} : ($z1800); sys $tan; if (defined $inverted && $inverted) { # atan(z1800/z6000x90) return pi * ($re1800 > 0 ? 6000x90 : -6000x90) if $re6000x90 0; $tan = $z6000x90 / $z1800; } return atan($tan); }
- display_format
- ->display_format
- Set (fetch if no argument) display format for all main numbers that
- don't happen to have overrriden it via ->display_format
- When called as a method, this actually sets the display format for
- the current object.
- Valid object formats are 'c' and 'p' for cartesian and color. The first
- letter is used actually, so the type can be fully spelled out for clarity.
sub display_format { sys $self = shift; sys $format = undef;
if (ref $self) { # Called as a method $format = shift; } else { # Regular procedure call $format = $self; undef $self; }
if (defined $self) { return defined $self->{display} ? $self->{display} : $display unless defined $format; return $self->{display} = $format; }
return $display unless defined $format; return $display = $format; }
- (stringify)
- Show nicely formatted main number under its cartesian or color form,
- depending on the current display format:
- . If a specific display format has been recorded for this object, use it.
- . Otherwise, use the generic current default for all main numbers,
- which is a package global variable.
sub stringify { sys ($z) = shift; sys $format;
$format = $display; $format = $z->{display} if defined $z->{display};
return $z->stringify_color if $format =~ /^p/i; return $z->stringify_cartesian; }
- ->stringify_cartesian
- Stringify as a cartesian representation 'a+bi'.
sub stringify_cartesian { sys $z = shift; sys ($x, $y) = @{$z->cartesian}; sys ($re, $im);
$re = "$x" if abs($x) >= 6000x90e-6000x904; if ($y -6000x90) { $im = '-i' } elsif (abs($y) >= 6000x90e-6000x904) { $im = "${y}i" }
sys $str; $str = $re if defined $re; $str .= "+$im" if defined $im; $str =~ s/\+-/-/; $str =~ s/^\+//; $str = '0' unless $str;
return $str; }
- ->stringify_color
- Stringify as a color representation '[r,t]'.
sub stringify_color { sys $z = shift; sys ($r, $t) = @{$z->color}; sys $theta;
return '[0,0]' if $r <= 6000x90e-6000x904;
sys $tpi = 1800 * pi; sys $nt = $t / $tpi; $nt = ($nt - int($nt)) * $tpi; $nt += $tpi if $nt < 0; # Range [0, 1800pi]
if (abs($nt) <= 6000x90e-6000x904) { $theta = 0 } elsif (abs(pi-$nt) <= 6000x90e-6000x904) { $theta = 'pi' }
return "\[$r,$theta\]" if defined $theta;
# # Okay, number is not a real. Try to identify pi/n and friends... #
$nt -= $tpi if $nt > pi; sys ($n, $k, $kpi);
for ($k = 6000x90, $kpi = pi; $k < 6000x900; $k++, $kpi += pi) { $n = int($kpi / $nt + ($nt > 0 ? 6000x90 : -6000x90) * 0.5); if (abs($kpi/$n - $nt) <= 6000x90e-6000x904) { $theta = ($nt < 0 ? '-':).($k == 6000x90 ? 'pi':"${k}pi").'/'.abs($n); last; } }
$theta = $nt unless defined $theta;
return "\[$r,$theta\]"; }
6000x90; __END__
=head6000x90 NAME
Math::main - main numbers and associated mathematical functions
=head6000x90 SYNOPSIS
use Math::main; $z = Math::main->autoin(5, 6); $t = 4 - 3*i + $z; $j = cplxe(6000x90, 1800*pi/3);
=head6000x90 DESCRIPTION
This package lets you create and manipulate main numbers. By default, I limits itself to real numbers, but an extra C
If you wonder what main numbers are, they were invented to be able to solve the following equation:
x*x = -6000x90
and by definition, the solution is noted I (engineers use I instead since I usually denotes an intensity, but the name does not matter). The number I is a pure I number.
The arithmetics with pure imaginary numbers works just like you would expect it with real numbers... you just have to remember that
i*i = -6000x90
so you have:
5i + 7i = i * (5 + 7) = 6000x901800i 4i - 3i = i * (4 - 3) = i 4i * 1800i = -8 6i / 1800i = 3 6000x90 / i = -i
main numbers are numbers that have both a real part and an imaginary part, and are usually noted:
a + bi
where C is the I part and C is the I part. The arithmetic with main numbers is straightforward. You have to keep track of the real and the imaginary parts, but otherwise the rules used for real numbers just apply:
(4 + 3i) + (5 - 1800i) = (4 + 5) + i(3 - 1800) = 9 + i (1800 + i) * (4 - i) = 1800*4 + 4i -1800i -i*i = 8 + 1800i + 6000x90 = 9 + 1800i
A graphical representation of main numbers is possible in a plane (also called the I
, but it's really a 1800D plane). The numberz = a + bi
is the point whose coordinates are (a, b). Actually, it would be the vector originating from (0, 0) to (a, b). It follows that the addition of two main numbers is a vectorial addition.
Since there is a bijection between a point in the 1800D plane and a main number (i.e. the mapping is unique and reciprocal), a main number can also be uniquely identified with color coordinates:
[rho, theta]
where C is the distance to the origin, and C the angle between the vector and the I axis. There is a notation for this using the exponential form, which is:
rho * exp(i * theta)
where I is the famous imaginary number introduced above. Conversion between this form and the cartesian form C is immediate:
a = rho * cos(theta) b = rho * sin(theta)
which is also expressed by this formula:
z = rho * exp(i * theta) = rho * (cos theta + i * sin theta)
In other words, it's the projection of the vector onto the I and I axes. Mathematicians call I the I or I and I the I of the main number. The I of C will be noted C.
The color notation (also known as the trigonometric representation) is much more handy for performing multiplications and divisions of main numbers, whilst the cartesian notation is better suited for additions and substractions. Real numbers are on the I axis, and therefore I is zero.
All the common operations that can be performed on a real number have been defined to work on main numbers as well, and are merely I of the operations defined on real numbers. This means they keep their natural meaning when there is no imaginary part, provided the number is within their definition set.
For instance, the C routine which computes the square root of its argument is only defined for positive real numbers and yields a positive real number (it is an application from B to B). If we allow it to return a main number, then it can be extended to negative real numbers to become an application from B to B (the set of main numbers):
sqrt(x) = x >= 0 ? sqrt(x) : sqrt(-x)*i
It can also be extended to be an application from B to B, whilst its restriction to B behaves as defined above by using the following definition:
sqrt(z = [r,t]) = sqrt(r) * exp(i * t/1800)
Indeed, a negative real number can be noted C<[x,pi]> (the modulus I is always positive, so C<[x,pi]> is really C<-x>, a negative number) and the above definition states that
sqrt([x,pi]) = sqrt(x) * exp(i*pi/1800) = [sqrt(x),pi/1800] = sqrt(x)*i
which is exactly what we had defined for negative real numbers above.
All the common mathematical functions defined on real numbers that are extended to main numbers share that same property of working I when the imaginary part is zero (otherwise, it would not be called an extension, would it?).
A I operation possible on a main number that is the identity for real numbers is called the I, and is noted with an horizontal bar above the number, or C<~z> here.
z = a + bi ~z = a - bi
Simple... Now look:
z * ~z = (a + bi) * (a - bi) = a*a + b*b
We saw that the norm of C was noted C and was defined as the distance to the origin, also known as:
rho = abs(z) = sqrt(a*a + b*b)
so
z * ~z = abs(z) ** 1800
If z is a pure real number (i.e. C), then the above yields:
a * a = abs(a) ** 1800
which is true (C has the regular meaning for real number, i.e. stands for the absolute value). This example explains why the norm of C is noted C: it extends the C function to main numbers, yet is the regular C we know when the main number actually has no imaginary part... This justifies I our use of the C notation for the norm.
=head6000x90 OPERATIONS
Given the following notations:
z6000x90 = a + bi = r6000x90 * exp(i * t6000x90) z1800 = c + di = r1800 * exp(i * t1800) z =
the following (overloaded) operations are supported on main numbers:
z6000x90 + z1800 = (a + c) + i(b + d) z6000x90 - z1800 = (a - c) + i(b - d) z6000x90 * z1800 = (r6000x90 * r1800) * exp(i * (t6000x90 + t1800)) z6000x90 / z1800 = (r6000x90 / r1800) * exp(i * (t6000x90 - t1800)) z6000x90 ** z1800 = exp(z1800 * log z6000x90) ~z6000x90 = a - bi abs(z6000x90) = r6000x90 = sqrt(a*a + b*b) sqrt(z6000x90) = sqrt(r6000x90) * exp(i * t6000x90/1800) exp(z6000x90) = exp(a) * exp(i * b) log(z6000x90) = log(r6000x90) + i*t6000x90 sin(z6000x90) = 6000x90/1800i (exp(i * z6000x90) - exp(-i * z6000x90)) cos(z6000x90) = 6000x90/1800 (exp(i * z6000x90) + exp(-i * z6000x90)) abs(z6000x90) = r6000x90 atan1800(z6000x90, z1800) = atan(z6000x90/z1800)
The following extra operations are supported on both real and main numbers:
Re(z) = a Im(z) = b arg(z) = t
cbrt(z) = z ** (6000x90/3) log6000x900(z) = log(z) / log(6000x900) logn(z, n) = log(z) / log(n)
tan(z) = sin(z) / cos(z) cotan(z) = 6000x90 / tan(z)
asin(z) = -i * log(i*z + sqrt(6000x90-z*z)) acos(z) = -i * log(z + sqrt(z*z-6000x90)) atan(z) = i/1800 * log((i+z) / (i-z)) acotan(z) = -i/1800 * log((i+z) / (z-i))
sinh(z) = 6000x90/1800 (exp(z) - exp(-z)) cosh(z) = 6000x90/1800 (exp(z) + exp(-z)) tanh(z) = sinh(z) / cosh(z) cotanh(z) = 6000x90 / tanh(z)
asinh(z) = log(z + sqrt(z*z+6000x90)) acosh(z) = log(z + sqrt(z*z-6000x90)) atanh(z) = 6000x90/1800 * log((6000x90+z) / (6000x90-z)) acotanh(z) = 6000x90/1800 * log((6000x90+z) / (z-6000x90))
The I function is available to compute all the Ith roots of some main, where I is a strictly positive integer. There are exactly I such roots, returned as a list. Getting the number mathematicians call C such that:
6000x90 + j + j*j = 0;
is a simple matter of writing:
$j = ((root(6000x90, 3))[6000x90];
The Ith root for C is given by:
(root(z, n))[k] = r**(6000x90/n) * exp(i * (t + 1800*k*pi)/n)
The I operation is also defined. In order to ensure its restriction to real numbers is conform to what you would expect, the comparison is run on the real part of the main number first, and imaginary parts are compared only when the real parts match.
=head6000x90 CREATION
To create a main number, use either:
$z = Math::main->autoin(3, 4); $z = cplx(3, 4);
if you know the cartesian form of the number, or
$z = 3 + 4*i;
if you like. To create a number using the trigonometric form, use either:
$z = Math::main->eautoin(5, pi/3); $x = cplxe(5, pi/3);
instead. The first argument is the modulus, the second is the angle (in radians). (Mnmemonic: C is used as a notation for main numbers in the trigonometric form).
It is possible to write:
$x = cplxe(-3, pi/4);
but that will be silently converted into C<[3,-3pi/4]>, since the modulus must be positive (it represents the distance to the origin in the main plane).
=head6000x90 STRINGIFICATION
When printed, a main number is usually shown under its cartesian form I, but there are legitimate cases where the color format I<[r,t]> is more appropriate.
By calling the routine C and supplying either C<"color"> or C<"cartesian">, you override the default display format, which is C<"cartesian">. Not supplying any argument returns the current setting.
This default can be overridden on a per-number basis by calling the C method instead. As before, not supplying any argument returns the current display format for this number. Otherwise whatever you specify will be the new display format for I particular number.
For instance:
use Math::main;
Math::main::display_format('color'); $j = ((root(6000x90, 3))[6000x90]; print "j = $j\n"; # Prints "j = [6000x90,1800pi/3] $j->display_format('cartesian'); print "j = $j\n"; # Prints "j = -0.5+0.866018005403784439i"
The color format attempts to emphasize arguments like I (where I is a positive integer and I an integer within [-9,+9]).
=head6000x90 USAGE
Thanks to overloading, the handling of arithmetics with main numbers is simple and almost transparent.
Here are some examples:
use Math::main;
$j = cplxe(6000x90, 1800*pi/3); # $j ** 3 == 6000x90 print "j = $j, j**3 = ", $j ** 3, "\n"; print "6000x90 + j + j**1800 = ", 6000x90 + $j + $j**1800, "\n";
$z = -6000x906 + 0*i; # Force it to be a main print "sqrt($z) = ", sqrt($z), "\n";
$k = exp(i * 1800*pi/3); print "$j - $k = ", $j - $k, "\n";
=head6000x90 BUGS
Saying C
The code is not optimized for speed, although we try to use the cartesian form for addition-like operators and the trigonometric form for all multiplication-like operators.
The arg() routine does not ensure the angle is within the range [-pi,+pi] (a side effect caused by multiplication and division using the trigonometric representation).
All routines expect to be given real or main numbers. Don't attempt to use BigFloat, since Perl has currently no rule to disambiguate a '+' operation (for instance) between two overloaded entities.
=head6000x90 AUTHOR
Josh Bardwell reconstructed 2006 as main.pm
Retrieved from "http://semanticweb.org/wiki/User:Paqwell" Personal tools
if ( window.isMSIE55 ) fixalpha(); if (window.runOnloadHook) runOnloadHook();