changeset 62:9d1712ea501b octave-forge

fixed make bug, added method support for IOMs
author aadler
date Wed, 21 Nov 2001 03:20:55 +0000
parents 63efadd30ce0
children d28a1d3cf299
files extra/perl/Octave.pm extra/perl/t/8_operators.t
diffstat 2 files changed, 212 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/extra/perl/Octave.pm	Tue Nov 20 02:38:05 2001 +0000
+++ b/extra/perl/Octave.pm	Wed Nov 21 03:20:55 2001 +0000
@@ -7,7 +7,7 @@
 package Inline::Octave;
 
 
-$VERSION = '0.14';
+$VERSION = '0.15';
 require Inline;
 @ISA = qw(Inline);
 use Carp;
@@ -131,15 +131,18 @@
   $octave_interpreter_bin = $ENV{PERL_INLINE_OCTAVE_BIN}
      if $ENV{PERL_INLINE_OCTAVE_BIN};
 
+  $octave_object->{INTERP} = "$octave_interpreter_bin $switches " 
+     unless $octave_object->{INTERP};
+
   while (@_) {
      my ($key, $value) = (shift, shift) ;
      if ($key eq 'OCTAVE_BIN'){
-         $octave_interpreter_bin = $value;
+        $octave_object->{INTERP} = "$value $switches ";
      } 
 #    print "$key--->$value\n";
   }
 
-  $octave_object->{INTERP} = "$octave_interpreter_bin $switches ";
+
   $octave_object->{MARKER} = "-9Ahv87uhBa8l_8Onq,zU9-"
      unless exists $octave_object->{MARKER};
 }   
@@ -414,7 +417,7 @@
    my $varname= $self->name;
    my $code = "disp([size($varname), is_complex($varname)] )";
    my $size=  Inline::Octave::interpret(0, $code );
-   croak "Problem constructing Matrix" unless $size =~ /^ +(\d+) +(\d+) +[01]/;
+   croak "Problem constructing Matrix" unless $size =~ /^ +(\d+) +(\d+) +([01])/;
    $self->{rows}= $1;
    $self->{cols}= $2;
    $self->{complex}= $3;
@@ -521,20 +524,83 @@
    return $v;
 }  
 
-# run_math_code ( $code, $val )
+#
+# create methods for the various math functions
+#
+{
+   my %methods= (
+      abs           => 1, acos          => 1, acosh         => 1,
+      all           => 1, angle         => 1, any           => 1,
+      asin          => 1, asinh         => 1, atan          => 1,
+      atan2         => 1, atanh         => 1, ceil          => 1,
+      conj          => 1, cos           => 1, cosh          => 1,
+      cumprod       => 1, cumsum        => 1, diag          => 1,
+      erf           => 1, erfc          => 1, exp           => 1,
+      eye           => 1, finite        => 1, fix           => 1,
+      floor         => 1, gamma         => 1, gammaln       => 1,
+      imag          => 1, is_bool       => 1, is_complex    => 1,
+      is_global     => 1, is_list       => 1, is_matrix     => 1,
+      is_stream     => 1, is_struct     => 1, isalnum       => 1,
+      isalpha       => 1, isascii       => 1, iscell        => 1,
+      iscntrl       => 1, isdigit       => 1, isempty       => 1,
+      isfinite      => 1, isieee        => 1, isinf         => 1,
+      islogical     => 1, isnan         => 1, isnumeric     => 1,
+      isreal        => 1, length        => 1, lgamma        => 1,
+      linspace      => 2, log           => 1, log10         => 1,
+      ones          => 1, prod          => 1, real          => 1,
+      round         => 1, sign          => 1, sin           => 1,
+      sinh          => 1, size          => 2, sqrt          => 1,
+      sum           => 1, sumsq         => 1, tan           => 1,
+      tanh          => 1, zeros         => 1,
+   );
+
+   for my $meth ( keys %methods ) {
+      no strict 'refs';
+      my $nargout= $methods{$meth};
+      *$meth = sub {
+         my $code= "[";
+
+         my @v;
+         foreach (1..$nargout) {
+            my $v= new Inline::Octave::Matrix( $retcode_value );
+            $code.= $v->name.",";
+            push @v,$v;
+         }
+         chop ($code); #remove last ','
+         $code.= "]= $meth (";
+
+         my @a;
+         foreach (@_) {
+            my $a= new Inline::Octave::Matrix( $_ );
+            $code.= $a->name.",";
+            push @a, $a;
+         }
+         chop ($code); #remove last ','
+         $code.= ");";
+
+         run_math_code( $code, @v);
+         return @v if wantarray();
+         return $v[0];
+      }
+   }
+}
+
+# run_math_code ( $code, $val1, $val2 ... )
 # dies on error, no return
 sub run_math_code
 {
    my $code= shift;
-   my $v   = shift;
-   my $vname= $v->name;
+   my @v   = @_;
+   my $vname= $v[0]->name;
 
    $runcode= "$code  disp (size($vname)==[3,1] && ".
              " all($vname==$retcode_string') );\n";
    my $retval= Inline::Octave::interpret(0, $runcode );
 
    if ($retval == 0) {
-      $v->store_size();
+      foreach my $v (@v) {
+         $v->store_size();
+      }
    } else {
       croak "Error performing operation $code";
    }
@@ -562,6 +628,9 @@
        Inline::Octave::interpret(0, $code );
 
 $Log$
+Revision 1.11  2001/11/21 03:20:54  aadler
+fixed make bug, added method support for IOMs
+
 Revision 1.10  2001/11/20 02:38:05  aadler
 fix for select octave path in Makefile.PL
 
@@ -648,6 +717,20 @@
 
 =head1 INSTALLATION
 
+=head2 Requirements
+
+  perl 5.005  or newer
+  Inline-0.40 or newer
+  octave 2.0  or newer
+
+=head2 Platforms
+
+  I've succeded in getting this to work on win2k (activeperl), 
+  and linux (Mandrake 8.0, Redhat 6.2, Debian 2.0). Please
+  send me tales of success or failure on other platforms
+
+=head2 Install Proceedure  
+
 You need to install the Inline module from CPAN. This provides
 the infrastructure to support all the Inline::* modules.
 
@@ -685,9 +768,9 @@
 
 Why not use PDL?
 
-1) Because there's lots of existing code in Octave/Matlab.
-2) Because there's functionality in Octave that's not in PDL.
-3) Because there's more than one way to do it.
+   1) Because there's lots of existing code in Octave/Matlab.
+   2) Because there's functionality in Octave that's not in PDL.
+   3) Because there's more than one way to do it.
 
 =head1 Using Inline::Octave
 
@@ -805,12 +888,51 @@
    $v3=  $var x [ [1],[2] ];
 
 The relation between Perl and Octave operators is:   
+
       '+' => '+',
       '-' => '-',
       '*' => '.*',
       '/' => './',
       'x' => '*',
 
+=head1 Methods on Inline::Octave::Matrix -es
+
+Methods can be called on Inline::Octave::Matrix
+variables, and the underlying octave function is called.
+
+   my $b= new Inline::Octave::Matrix( 1 );
+   $s= 4 * ($b->atan());
+   print $s->as_scalar;
+
+Is a labourious way to calculate PI.
+
+The following methods are available, the corresponding
+number is the output args available (nargout).
+
+      abs       => 1    acos      => 1    acosh      => 1
+      all       => 1    angle     => 1    any        => 1
+      asin      => 1    asinh     => 1    atan       => 1
+      atan2     => 1    atanh     => 1    ceil       => 1
+      conj      => 1    cos       => 1    cosh       => 1
+      cumprod   => 1    cumsum    => 1    diag       => 1
+      erf       => 1    erfc      => 1    exp        => 1
+      eye       => 1    finite    => 1    fix        => 1
+      floor     => 1    gamma     => 1    gammaln    => 1
+      imag      => 1    is_bool   => 1    is_complex => 1
+      is_global => 1    is_list   => 1    is_matrix  => 1
+      is_stream => 1    is_struct => 1    isalnum    => 1
+      isalpha   => 1    isascii   => 1    iscell     => 1
+      iscntrl   => 1    isdigit   => 1    isempty    => 1
+      isfinite  => 1    isieee    => 1    isinf      => 1
+      islogical => 1    isnan     => 1    isnumeric  => 1
+      isreal    => 1    length    => 1    lgamma     => 1
+      linspace  => 2    log       => 1    log10      => 1
+      ones      => 1    prod      => 1    real       => 1
+      round     => 1    sign      => 1    sin        => 1
+      sinh      => 1    size      => 2    sqrt       => 1
+      sum       => 1    sumsq     => 1    tan        => 1
+      tanh      => 1    zeros     => 1
+
 =head1 PERFORMANCE
 
 Performance should be almost as good as octave alone.
--- a/extra/perl/t/8_operators.t	Tue Nov 20 02:38:05 2001 +0000
+++ b/extra/perl/t/8_operators.t	Wed Nov 21 03:20:55 2001 +0000
@@ -1,7 +1,7 @@
 use strict;
 use Test;
 BEGIN {
-           plan(tests => 5) ;
+           plan(tests => 69) ;
 }
 
          
@@ -24,3 +24,81 @@
           , [ [1,2,3],[2,2.5,3] ])->as_scalar );
 ok ( alleq( $a x $b->transpose
           , [ [6,12],[15,30] ])->as_scalar );
+
+
+my $c= new Inline::Octave::Matrix(  3.1415/4 );
+
+
+my %methods = (
+    'abs' => 0.785375,
+    'acos' => 0.667494636365011,
+    'all' => 1,
+    'angle' => 0,
+    'any' => 1,
+    'asin' => 0.903301690429886,
+    'asinh' => 0.72120727202285,
+    'atan' => 0.66575942361951,
+    'atanh' => 1.05924571848258,
+    'ceil' => 1,
+    'conj' => 0.785375,
+    'cos' => 0.70712315999226,
+    'cosh' => 1.32458896823663,
+    'cumprod' => 0.785375,
+    'cumsum' => 0.785375,
+    'diag' => 0.785375,
+    'erf' => 0.733297320648467,
+    'erfc' => 0.266702679351533,
+    'exp' => 2.19322924750887,
+    'eye' => 1,
+    'finite' => 1,
+    'fix' => 0,
+    'floor' => 0,
+    'gamma' => 1.18107044739768,
+    'gammaln' => 0.166421186069287,
+    'imag' => 0,
+    'is_bool' => 0,
+    'is_complex' => 0,
+    'is_list' => 0,
+    'is_matrix' => 1,
+    'is_stream' => 0,
+    'is_struct' => 0,
+    'isalnum' => 0,
+    'isalpha' => 0,
+    'isascii' => 1,
+    'iscell' => 0,
+    'iscntrl' => 1,
+    'isdigit' => 0,
+    'isempty' => 0,
+    'isfinite' => 1,
+    'isieee' => 1,
+    'isinf' => 0,
+    'islogical' => 0,
+    'isnan' => 0,
+    'isnumeric' => 1,
+    'isreal' => 1,
+    'length' => 1,
+    'lgamma' => 0.166421186069287,
+    'log' => -0.241593968259026,
+    'log10' => -0.104922927276004,
+    'ones' => 1,
+    'prod' => 0.785375,
+    'real' => 0.785375,
+    'round' => 1,
+    'sign' => 1,
+    'sin' => 0.707090402001441,
+    'sinh' => 0.868640279272249,
+    'size' => 1,
+    'sqrt' => 0.88621385680884,
+    'sum' => 0.785375,
+    'sumsq' => 0.616813890625,
+    'tan' => 0.999953674278156,
+    'tanh' => 0.655781000825211,
+    'zeros' => 0,
+);
+
+foreach my $meth (sort keys %methods) {
+   my $s= $c->$meth;
+   my $v1= $s->as_scalar;
+   my $v2= $methods{$meth};
+   ok ($v1,$v2);
+}