Author: jisom
Date: Fri Mar 17 06:35:28 2006
New Revision: 11915

Modified:
   trunk/src/pmc/complex.pmc
   trunk/t/pmc/complex.t

Log:
Update complex.pmc, added ln, pow, and exp so far
e^(pi * i) + 1 = 0 now


Modified: trunk/src/pmc/complex.pmc
==============================================================================
--- trunk/src/pmc/complex.pmc   (original)
+++ trunk/src/pmc/complex.pmc   Fri Mar 17 06:35:28 2006
@@ -445,6 +445,8 @@
 
 Set real or imag depending on key
 
+=cut
+
 */
 
     FLOATVAL get_number_keyed_int(INTVAL key) {
@@ -747,6 +749,7 @@
   TODO for better precision:
 
   (a+ib)(c+id)=(ac-bd)+i((a+b)(c+d)-ac-bd).
+  (a+bi)(c+di)=(ac-bd)+i(ad+bc)
 
 */
     PMC* multiply (PMC* value, PMC* dest) {
@@ -1017,6 +1020,97 @@
         VTABLE_morph(INTERP, SELF, enum_class_Float);   /* XXX */
         VTABLE_set_number_native(INTERP, SELF, d);
     }
+
+/*
+
+=item C<METHOD PMC* ln()>
+
+Returns the natural logorithm of SELF.
+
+=cut
+
+ln z = ln |z| + i arg(z)
+|x + iy| = sqrt(x^2 + y^2)
+arg(x + iy) = atan2(y, x)
+
+*/
+
+    METHOD PMC* ln() {
+        PMC *d = pmc_new(INTERP, SELF->vtable->base_type);
+        RE(d) = log(sqrt(RE(SELF)*RE(SELF) + IM(SELF)*IM(SELF)));
+        IM(d) = atan2(IM(SELF), RE(SELF));
+        return d;
+    }
+
+/*
+
+=item C<METHOD PMC* exp()>
+
+Returns e ^ SELF.
+
+=cut
+
+exp(a + bi) = exp(a) *(cos(b) + i * sin(b))
+
+*/
+
+    METHOD PMC* exp() {
+        PMC *d = pmc_new(INTERP, SELF->vtable->base_type);
+        FLOATVAL f = exp(RE(SELF));
+        RE(d) = f * cos(IM(SELF));
+        /* If only sin(pi) worked... */
+        if (IM(SELF) == 4 * atan(1))
+            IM(d) = 0;
+        else
+            IM(d) = f * sin(IM(SELF));
+        return d;
+    }
+
+
+/*
+
+=item C<PMC* pow(PMC* value, PMC* dest)>
+
+Return SELF to the C<value>th power and return result in C<dest>.
+
+=cut
+
+TODO: mmd in other pmc's to allow .Integer ^ .Complex, etc.
+and i_pow, and pow_(float|int), etc
+
+x ^ y = exp(y * ln x))
+
+*/
+
+    PMC* pow (PMC* value, PMC* dest) {
+MMD_Complex: {
+                 PMC *l = pmc_new(INTERP, SELF->vtable->base_type);
+                 if (dest)
+                     VTABLE_morph(INTERP, dest, SELF->vtable->base_type);
+                 else
+                     dest = pmc_new(INTERP, SELF->vtable->base_type);
+                 l = Parrot_Complex_multiply_Complex(INTERP, value,
+                     Parrot_Complex_ln(INTERP, SELF), l);
+                 dest = Parrot_Complex_exp(INTERP, l);
+                 return dest;
+             }
+MMD_DEFAULT: {
+                 PMC *l = pmc_new(INTERP, SELF->vtable->base_type);
+                 if (dest)
+                     VTABLE_morph(INTERP, dest, SELF->vtable->base_type);
+                 else
+                     dest = pmc_new(INTERP, SELF->vtable->base_type);
+                 l = Parrot_Complex_multiply(INTERP,
+                     Parrot_Complex_ln(INTERP, SELF),
+                     value,
+                     l);
+                 dest = Parrot_Complex_exp(INTERP, l);
+                 return dest;
+             }
+    }
+
+
+    
 }
 
 /*

Modified: trunk/t/pmc/complex.t
==============================================================================
--- trunk/t/pmc/complex.t       (original)
+++ trunk/t/pmc/complex.t       Fri Mar 17 06:35:28 2006
@@ -6,7 +6,7 @@
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 25;
+use Parrot::Test tests => 28;
 
 =head1 NAME
 
@@ -622,7 +622,7 @@
 
 .sub _main
     .local pmc pmc1
-    pmc1 = new Complex
+    pmc1 = new .Complex
     .local int bool1
     does bool1, pmc1, "scalar"
     print bool1
@@ -673,9 +673,9 @@
 
 .sub main
     $P0 = getclass "Complex"
-    $P1 = new Float
+    $P1 = new .Float
     $P1 = 2.0
-    $P2 = new Float
+    $P2 = new .Float
     $P2 = 3.0
     $P1 = $P0."instantiate"($P1, $P2)
     print $P1
@@ -747,9 +747,9 @@
 pir_output_is(<< 'CODE', << 'OUTPUT', "sub");
 .sub main :main
     .local pmc d, f, c
-    d = new Undef
-    f = new Float
-    c = new Complex
+    d = new .Undef
+    f = new .Float
+    c = new .Complex
     f = 2.2
     c = "5+2j"
     d = c - f
@@ -775,14 +775,14 @@
 pir_output_is(<< 'CODE', << 'OUTPUT', "i_sub");
 .sub main :main
     .local pmc f, c
-    f = new Float
+    f = new .Float
     f = 2.2
-    c = new Complex
+    c = new .Complex
     c = "5+2j"
     c -= f
     print c
     print "\n"
-    c = new Complex
+    c = new .Complex
     c = "5+2j"
     f -= c
     print f
@@ -792,3 +792,110 @@
 2.8+2i
 -2.8-2i
 OUTPUT
+
+pir_output_is(<< 'CODE', << 'OUTPUT', "ln of complex numbers");
+.macro DoIt(val)
+    c = .val
+       c2 = c.ln()
+    print c2
+    print "\n"
+.endm
+.sub main :main
+       .local pmc c, c2
+    c = new .Complex
+       .DoIt("i")
+       .DoIt("2i")
+       .DoIt("2+2i")
+       .DoIt("-1")
+.end
+CODE
+0+1.5708i
+0.693147+1.5708i
+1.03972+0.785398i
+0+3.14159i
+OUTPUT
+
+pir_output_is(<< 'CODE', << 'OUTPUT', "exp of complex numbers");
+.macro DoIt(val)
+    c = .val
+       c2 = c.exp()
+    print c2
+    print "\n"
+.endm
+.sub main :main
+       .local pmc c, c2
+    c = new .Complex
+       .DoIt("i")
+       .DoIt("2i")
+       .DoIt("2+2i")
+
+       # e^(pi * i) + 1 = 0
+       $N0 = atan 1
+       $N0 *= 4
+       c[0] = 0.0
+       c[1] = $N0
+       c2 = c.exp()
+       c2 += 1.0
+    print c2
+    print "\n"
+.end
+CODE
+0.540302+0.841471i
+-0.416147+0.909297i
+-3.07493+6.71885i
+0+0i
+OUTPUT
+
+pir_output_is(<< 'CODE', << 'OUTPUT', "pow with complex numbers");
+.macro DoIt(base, power)
+       c = .base
+       c2 = .power
+       c3 = pow c, c2
+       print c3
+       print "\n"
+.endm
+.sub main :main
+       .local pmc c, c2, c3
+       c = new .Complex
+       c2 = new .Complex
+       c3 = new .Complex
+       .DoIt("i", "i")
+       .DoIt("i", "2")
+       .DoIt("2i", "2")
+       .DoIt("2+2i", "2+2i")
+       .DoIt("i", "0.5i")
+       .DoIt(2, "2i")
+       c2 = new .Integer
+       .DoIt("2i", 2)
+       .DoIt("2", 4)
+       c2 = new .Float
+       .DoIt("2i", 0.5)
+
+       # another e^(pi * i) + 1 = 0
+       c = new .Complex
+       c2 = new .Complex
+       $N0 = exp 1
+       c[0] = $N0
+       c[1] = 0.0
+       $N0 = atan 1
+       $N0 *= 4
+       c2[0] = 0.0
+       c2[1] = $N0
+       c3 = pow c, c2
+       c3 += 1.0
+       print c3
+       print "\n"
+.end
+CODE
+0.20788+0i
+-1+0i
+-4+0i
+-1.4525-0.80989i
+0.455938+0i
+0.183457+0.983028i
+-4+0i
+16+0i
+1+1i
+0+0i
+OUTPUT
+

Reply via email to