Skip to content

Commit

Permalink
Merge branch 'native-complex'
Browse files Browse the repository at this point in the history
This makes Complex a class purely defined in Perl 6, to avoid oddnesses where
methods defined in the parrot Complex PMC would not be overridable from
withing Perl 6.

colomon++ gets much credit for working on this branch.
  • Loading branch information
moritz committed Sep 30, 2009
2 parents c8181aa + 34e9a64 commit e25aaba
Show file tree
Hide file tree
Showing 12 changed files with 279 additions and 502 deletions.
2 changes: 1 addition & 1 deletion Test.pm
Expand Up @@ -84,7 +84,7 @@ multi sub isnt(Object $got, Object $expected, $desc) is export(:DEFAULT) {
multi sub isnt(Object $got, Object $expected) is export(:DEFAULT) { isnt($got, $expected, ''); }

multi sub is_approx(Object $got, Object $expected, $desc) is export(:DEFAULT) {
my $test = abs($got - $expected) <= 0.00001;
my $test = ($got - $expected).abs <= 0.00001;
proclaim(?$test, $desc);
}

Expand Down
1 change: 0 additions & 1 deletion build/Makefile.in
Expand Up @@ -93,7 +93,6 @@ BUILTINS_PIR = \
src/classes/Num.pir \
src/classes/Int.pir \
src/classes/Order.pir \
src/classes/Complex.pir \
src/classes/IO.pir \
src/classes/List.pir \
src/classes/Array.pir \
Expand Down
153 changes: 1 addition & 152 deletions src/builtins/any-num.pir
Expand Up @@ -22,24 +22,12 @@ the size of that file down and to emphasize their generic,
.loadlib 'math_ops'
.sub 'onload' :anon :init :load
$P0 = get_hll_namespace ['Any']
'!EXPORT'('abs,int,log,polar,sqrt,truncate,unpolar', 'from'=>$P0)
'!EXPORT'('int,polar,truncate', 'from'=>$P0)

## pre-seed a random number generator
'srand'()
.end


=item abs()

=cut

.namespace ['Any']
.sub 'abs' :method :multi(_)
$N0 = self
$N1 = abs $N0
.return ($N1)
.end

.namespace ['Any']
.sub 'int' :method :multi(_)
"die"("the int() sub and .int method have been replaced by the .Int method")
Expand All @@ -51,23 +39,6 @@ the size of that file down and to emphasize their generic,
.end


=item log

our Num multi Num::log ( Num $x: Num :$base )
our Num multi Math::Basic::log ( Num $x, Num :$base )

Logarithm of base C<$base>, default Natural. Calling with C<$x == 0> is an
error.

=cut

.sub 'log' :method :multi(_)
$N0 = self
$N1 = ln $N0
.return ($N1)
.end


=item polar

=cut
Expand All @@ -79,18 +50,6 @@ error.
.end


=item sqrt()

=cut

.namespace ['Any']
.sub 'sqrt' :method :multi(_)
$N0 = self
$N1 = sqrt $N0
.return ($N1)
.end


=item srand()

=cut
Expand Down Expand Up @@ -134,116 +93,6 @@ error.
.return ($I0)
.end


=item unpolar($angle)

=cut

=item roots

our Array multi Num::roots ( Complex $z, Int $n )

Returns an Array consisting of the $n roots of a Complex number $z, where $n is
a positive integer. For any Complex number $z ( which includes real numbers and
integers as a subset ) there are a set of $n numbers W such that $w_k ** $n = $z,
or in set theory notation:

W = { $w_i : $w_i ** $n = $z and 0 <= i <= n-1 } .

These can be written in terms of the multiple-valued complex logarithm:

exp[1/$n*(Log($z)]

which is equal to

$w_k = exp[1/$n*(log($r)+i*($theta + 2*k*pi))] where k = 0,1,2,..., n-1

where ($r,$theta) = $z.polar . The angle $theta returned is always in the
interval -pi <= $theta <= pi .

=cut

.sub 'roots' :method
.param int n
.local num pi, r, theta
.local pmc x, result, roots
x = self
pi = atan 1
pi *= 4
roots = root_new ['parrot';'FixedPMCArray']
if n > 0 goto positive
roots = 1 # single element array
roots[0] = 'NaN'
goto done
positive:
roots = n # fix array size to n
if n > 1 goto general
roots[0] = x
goto done
general:
div $N0, 1, n
$I0 = 0
$I1 = isa x, 'Complex'
unless $I1 goto real
$N6 = x[0]
$N7 = x[1]
theta = atan $N7, $N6 # angle of polar representation
$N6 *= $N6
$N7 *= $N7
$N8 = $N6 + $N7
r = sqrt $N8 # radius of polar representation
$N1 = ln r
goto loop
real:
$N4 = x
$N4 = abs $N4 # if x < 0 we rotate by exp(i pi/n) later on
$N1 = ln $N4 # ln(abs(x)) = ln(r)
loop:
if $I0 >= n goto done
$P2 = root_new ['parrot';'Complex'] # this can surely be optimized
$N3 = $N0
$N3 *= 2
$N3 *= pi
$N3 *= $I0
$P2[1] = $N3 # 2*$I0*pi/n
$N5 = $P2[1]
unless $I1 goto rotate_negative_reals
$N8 = $N0
$N8 *= theta # theta/n
$N5 += $N8 # 2*$I0*pi/n + theta/n
goto exponentiate
rotate_negative_reals: # we must rotate answer since we factored out (-1)^(1/n)
if x > 0 goto exponentiate
div $N4, pi, n
$N5 += $N4 # exp( i pi / n ) = (-1)^(1/n) (principle root)
exponentiate:
$N9 = $N0
$N9 *= $N1 # 1/n*ln(r)
$P2[0] = $N9
$P2[1] = $N5
$P2 = $P2.'exp'() # exp(1/n*(ln(r)+i*(theta + 2*k*pi)))
roots[$I0] = $P2
inc $I0
goto loop
done:
.return (roots)
.end

.sub 'unpolar' :method
.param num angle
.local num mag
.local pmc result
mag = self
result = root_new ['parrot';'Complex']
$N0 = cos angle
$N0 *= mag
result[0] = $N0
$N0 = sin angle
$N0 *= mag
result[1] = $N0
.return (result)
.end

=back

=cut
Expand Down
44 changes: 0 additions & 44 deletions src/builtins/math.pir
Expand Up @@ -15,15 +15,6 @@ src/builtins/math.pir - Perl6 math functions
## TODO: figure out what to get working, in order to uncomment the following
## .namespace [ 'Math::Basic' ]


.sub 'roots' :multi(_, 'Integer')
.param pmc x
.param int n
.local pmc result
result = x.'roots'(n)
.return (result)
.end

=item sign

our Int multi Num::sign ( Num $x )
Expand Down Expand Up @@ -58,37 +49,6 @@ Returns the sign of $x, i.e +1 for positive numbers (including Inf), zero for ze
.end


=item exp

our Num multi Num::exp ( Num $exponent: Num :$base = Num::e )
our Num multi Math::Basic::exp ( Num $exponent, Num :$base = Num::e )

Performs similar to C<$base ** $exponent>. C<$base> defaults to the
constant I<e>.

=cut

.sub 'exp' :multi(_)
.param num a
a = exp a
.return (a)
.end


=item log10

&log10 := &log.assuming:base(10);

Returns the base 10 logarithm of $x.

=cut

.sub 'log10'
.param num a
$N0 = log10 a
.return ($N0)
.end


=item e

Expand Down Expand Up @@ -234,10 +194,6 @@ Note that you get one C<srand()> for free when you start a Perl program, so
you I<must> call C<srand()> yourself if you wish to specify a deterministic seed
(or if you wish to be differently nondeterministic).

=item i

constant Complex Complex::i = Complex::sqrt(-1);

=back

=cut
Expand Down

0 comments on commit e25aaba

Please sign in to comment.