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.