NAME

Inline::Octave - Inline octave code into your perl

SYNOPSIS

use Inline Octave => DATA;

$f = jnk1(3);
print "jnk1=",$f->disp(),"\n";

$c= new Inline::Octave([ [1.5,2,3],[4.5,1,-1] ]);

($b, $t)= jnk2( $c, [4,4],[5,6] );
print "t=",$t->as_list(),"\n";
use Data::Dumper; print Dumper( $b->as_matrix() );

print oct_sum( [1,2,3] )->disp();

oct_plot( [0..4], [3,2,1,2,3] );
sleep(2);

my $d= (2*$c) x $c->transpose;
print $d->disp;


__DATA__

__Octave__
function x=jnk1(u); x=u+1; endfunction

function [b,t]=jnk2(x,a,b);
   b=x+1+a'*b;
   t=6;
endfunction

## Inline::Octave::oct_sum (nargout=1)  => sum
## Inline::Octave::oct_plot (nargout=0)  => plot

WARNING

THIS IS ALPHA SOFTWARE. It is incomplete and possibly unreliable. It is also possible that some elements of the interface (API) will change in future releases.

DESCRIPTION

Inline::Octave gives you the power of the octave programming language from within your Perl programs.

Basically, I create an octave process with controlled stdin and stdout. Commands send by stdin. Data is send by stdin and read with fread(stdin, [dimx dimy], "double"), and read similarly.

Inline::Octave variables in perl are tied to the octave variable. When a destructor is called, it sends a "clear varname" command to octave.

Additionally, there are Inline::Octave::ComplexMatrix and Inline::Octave::String types for the corresponding variables.

I initially tried to bind the C++ and liboctave to perl, but it started to get really hard - so I took this route. I'm planning to get back to that eventually ...

INSTALLATION

Requirements

perl 5.005  or newer
Inline-0.40 or newer
octave 3.2  or newer

Platforms

I've succeded in getting this to work on win2k (activeperl), 
win2k cygwin (but Inline-0.43 can't install Inline::C)
and linux (Mandrake 8.0, Redhat 6.2, Debian 2.0).

Note that Inline-0.43 can't handle spaces in your path -
this is a big pain for windows users.

Please send me tales of success or failure on other platforms

Install Proceedure

You need to install the Inline module from CPAN. This provides the infrastructure to support all the Inline::* modules.

Then:

perl Makefile.PL
make 
make test
make install

This will search for an octave interpreter and give you the choice of giving the path to GNU Octave.

If you don't want this interactivity, then specify

perl Makefile.PL OCTAVE=/path/to/octave
   or
perl Makefile.PL OCTAVE='/path/to/octave -my -special -switches'

The path to the octave interpreter can be set in the following ways:

  - set OCTAVE_BIN option in the use line

     use Inline Octave => DATA => OCTAVE_BIN => /path/to/octave

  - set the PERL_INLINE_OCTAVE_BIN environment variable

Why would I use Inline::Octave

If you can't figure out a reason, don't!

I use it to grind through long logfiles (using perl), and then calculate mathematical results (using octave).

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.

Using Inline::Octave

The most basic form for using Inline is:

use Inline Octave => "octave source code";
          

The source code can be specified using any of the following syntaxes:

use Inline Octave => 'DATA';
...perl...                                                                    
__DATA__
__Octave__
...octave...

or,

use Inline Octave => <<'ENDOCTAVE';
...octave...
ENDOCTAVE
...perl...

or,

use Inline Octave => q{
...octave...
};
...perl...

Defining Functions

Inline::Octave lets you:

1) Talk to octave functions using the syntax

## Inline::Octave::oct_plot (nargout=0)  => plot

Here oct_plot in perl is bound to plot in octave. It is necessary to specify the nargouts required because we can't get this information from perl. (although it's promised in perl6)

If you need to use various nargouts for a function, then bind different functions to it:

## Inline::Octave::eig1 (nargout=1)  => eig
## Inline::Octave::eig2 (nargout=2)  => eig

2) Write new octave functions,

function s=add(a,b);
   s=a+b;
endfunction

will create a new function add in perl bound to this new function in octave.

Calling Functions

A function is called using

(list of Inline::Octave::Matrix) =
   function_name (list of Inline::Octave::Matrix)

Parameters which are not Inline::Octave::Matrix variables will be cast (if possible).

Values returned will need to be converted into perl values if they need to be used within the perl code. This can be accomplished using:

1. $oct_var->disp()

Returns a string of the disp output from octave This provides a formatted representation, and should mostly be useful for debugging.

2. $oct_var->as_list()

Returns a perl list, corresponding to the ColumnVector for octave "oct_var(:)"

3. $oct_var->as_matrix()

Returns a perl list of list, of the form

$var= [ [1,2,3],[4,5,6],[7,8,9] ];

4. $oct_var->as_scalar()

Returns a perl scalar if $oct_var is a 1x1 matrix, dies with an error otherwise

5. $oct_var->sub_matrix( $row_spec, $col_spec ) Returns the sub matrix specified

$x= Inline::Octave->new([1,2,3,4]);
$y=$x x $x->transpose();
$y->sub_matrix( [2,4], [2,3] )'

gives:  [ [4,6],[8,9] ]

Using Inline::Octave variables

Inline::Octave::Matrix is the matrix class that "ties" matrices held by octave to perl variables.

Values can be created explicitly, using the syntax:

$var= new Inline::Octave([ [1.5,2,3],[4.5,1,-1] ]);

or

$var= Inline::Octave->new([ [1.5,2,3],[4.5,1,-1] ]);

or values will be automatically created by calling octave functions.

If your code only uses matrixes, and does not need to define any octave functions, then the following initialization syntax may be useful:

use Inline Octave =>" ";

Operations on Inline::Octave::Matrix -es

Many math operations have been overloaded to work directly on Inline::Octave::Matrix values;

For example, given $var above, we can calculate:

$v1= ( $var x $var->transpose );
$v2=  2*$var + 1
$v3=  $var x [ [1],[2] ];

The relation between Perl and Octave operators is:

'+' => '+',
'-' => '-',
'*' => '.*',
'/' => './',
'x' => '*',

Methods on Inline::Octave::Matrix -es

Methods can be called on Inline::Octave::Matrix variables, and the underlying octave function is called.

for example:

my $b= new Inline::Octave( 1 );
$s= 4 * ($b->atan());
my $pi=  $s->as_scalar;

Is a labourious way to calculate PI.

Additionally, it is possible to call these as functions instead of methods

for example:

$c= Inline::Octave::rand(2,3);
print $c->disp();

gives:

0.23229  0.50674  0.25243
0.96019  0.17037  0.39687

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    => 1   log         => 1   log10       => 1  
logspace    => 1   ones        => 1   prod        => 1  
rand        => 1   randn       => 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  

Manipulating Inline::Octave::Matrix -es

If you would like to do the octave equivalent of

a=zeros(4);
a( [1,3] , :)= [ 1,2,3,4 ; 5,6,7,8 ];
a( : , [2,4])= [ 2,4; 2,4; 2,4; 2,4 ];
a( [1,4],[1,4])= [8,7;6,5];

Then these methods will make life more convenient.

$a = Inline::Octave::zeros(4);
$a->replace_rows( [1,3], [ [1,2,3,4],[5,6,7,8] ] );
$a->replace_cols( [2,4], [ [2,4],[2,4],[2,4],[2,4] ] );
$a->replace_matrix( [1,4], [1,4], [ [8,7],[6,5] ] );

Using Inline::Octave::ComplexMatrix

Inline::Octave::ComplexMatrix should work very similarly to Inline::Octave::Matrix's. The perl Math::Complex type is used to map octave complex numbers.

Note, however, that the Math::Complex type in perl is heavy - it takes lots of memory and time compared to the native implementation in Octave.

use Math::Complex;
my $x= Inline::Octave::ComplexMatrix->new([1,1,2,3 + 6*i,4]);
print $x->disp();

Using Inline::Octave::String

Inline::Octave::String is a subclass of Inline::Octave::Matrix used for octave strings. It is required because there is no way to explicity create a string from Inline::Octave::Matrix.

Example:

use Inline Octave => q{
   function out = countstr( str )
      out= "";
      for i=1:size(str,1)
         out= [out,sprintf("idx=%d row=(%s)\n",i, str(i,:) )];
      end
   endfunction
};

$str= new Inline::Octave::String([ "asdf","b","4523","end" ] );
$x=   countstr( $str );
print $x->disp();

PERFORMANCE

Performance should be almost as good as octave alone. The only slowdown is passing large variables across the pipe between perl and octave - but this should be much faster than any actual computations.

By using the strengths of both languages, it should be possible to run faster than in each. (ie using octave for matrix operations, and running loops and text stuff in perl)

One performance issue is Complex matrix math in perl. The perl Math::Complex type is quite heavy, and for large matrices this work is done for each element. You should try to do the complex stuff in octave, and only pull back small matrices into perl.

AUTHOR

Andy Adler adler at site dot uottawa dot ca

COPYRIGHT

(c) 2003-2011, Andy Adler with help from Andreas Krause

All Rights Reserved. This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.