Vector - a perl scalar reference to a fixed packed array of doubles with arithmetic operations on the scalars, implemented in C.
use Vector;
my $a = new Vector size => 5000, value => 10.1 ; print " \$a is " . $a . "\n";
my $b = new Vector size => 5000, first => 1, by => 3 ; print " \$b is " . $b . "\n";
$a->[1] = 22; print " \$a->[1] is " . $a->[1] . "\n";
my $c = $a * $b + $a; print " \$a * \$b + \$a is " . $c . "\n";
# Or
use Vector qw( vector ); my $a = vector( size=>100, first=>10, by=>10 ); print $a; # [10,20,30,...,980,990,1000] print $a*$a + 1; # [101,401,901,...,960401,980101,1000001]
A perl Vector object for fast mathematical operations on large arrays of numbers. Unlike perl arrays, a Vector contains only one data type whose size is fixed at its creation. Internally, a Vector stores its data in a single block of memory.
To see a demo, type perl Vector.pm at the shell prompt in the directory that contains this file.
The currently implemented operations are
* Creating a constant array
$a = new Vector size=>10, value=>2;
or
use Vector qw(vector);
$a = vector( size=>10, value=>2 );
If the size is omitted it defaults to 1,
unless the 'values' parameter is passed, in which case
the size is taken to be the size of the given perl array.
If the value is omitted, then vector values are not initialized,
and reflect the state of the allocated memory - typically
smallish random-like numbers on my system.
* Creating a monotomic sequence of numbers
$b = new Vector size=>10, first=>1, by=>2
If the "by" keywork is omitted it defaults to 1.
* Creating a vector from a perl array reference
$a = new Vector values => [2,3,4];
or
$a = new Vector values => [1..10];
(These are convenient for small vectors, but
extremely inefficient for larger ones.)
* Some standard mathematical binary and unary operations
+ addition
- subtraction
* multiplication
/ division
** raising to a power
atan2 two argument arc tangent
sin sine
cos cosine
exp e**( )
sqrt sqaure root
Binary operations with perl scalars and array references
will convert the perl variable to a Vector automatically.
$a = new Vector size=>20, first => 100, by => 10 ;
$b = 2 * $a;
$a + 1;
$a ** $b;
sin($a);
$a - [2,3]; # this subtracts [2,3,2,3,2,3,...]
* Setting and fetching individual values
$a->[2] = $b->[5]
Indices run from 0..(size-1), as they do in perl.
However, array indeces outside the defined size range wrap
around, so that if $a=[5,6,7] then $a[-1] is 7 and $a[3] = 5.
Thus any index may be used while setting or fetching, without
changing the size of the array.
Once created, the size of a vector cannot be changed.
Binary operations between Vectors of different sizes
also follow this same convention. Thus the result of
of adding [1,2,3,4,5] + [1,2] is the same as adding
[1,2,3,4,5] + [1,2,1,2,1] which is [2,4,4,6,6].
The size of the binary operation is always the size of the
larger of the two Vectors.
* You may check to see if an index is within 0 .. (size-1) with
the typical perl syntax :
if ( exists $a->[101] ) { ... }
or by using the "size" function
$a->size
or by the perl idiom
$#$a or $#{$a}
* When converted to strings, Vectors show the first and
last few values only, to avoid too much screen verbiage.
Thus
$a = new Vector size=>100, first=>10, by=>7;
print " a = " . $a . "\n";
will output as
a = [10,17,24,...,689,696,703]
Features which are not included but might be eventually:
* various data types, i.e. int, byte, etc.
* table($a,$b) function for outputting all values
* some way to call plotting routines.
GD? PGPLOT? GnuPlot? Integrated
Perl/Tk with some mouse-click interaction???
* Some kind iteration,
i.e. functions (perl? C?)
applied to each element, including
by index. Something like
v[i] = ( x[i+1] - x[i-1] ) /2
Perhaps saved as new named subs
or subroutine-like objects?
Perhaps with generated inline C code
done at runtime.
* Save/restore state, including
defined functions above. Options
to do so as pure text or binary form.
* conditionals, probably as part of
the iteration above. Do-this-where-that
kind of syntax, since "if ($a==0)"
is effectively $a->size different tests.
* sequences like 1,3,5,... calculated as
needed rather than stored.
Perhaps as an option which can be turned off.
Perhaps option for arbitrary size.
Notation? Not sure how to get something
like "1..1e6 by 2" without having perl
barf and/or generating all the entries.
* Optional dynamic (arbitrary) sizes.
(access off the ends give zero;
setting values off the ends grow it.)
* Optional errors when setting vector indices
outside defined range.
* Optional return value of zero when fetching
vector indecides outside defined range.
* Better error testing and return values
* Complex number support.
* Optional duplication of object for
$a = new Vector values=>[2,3];
$b = $a;
$b->[0] = 100;
Right now this changes the single
underlying object that both $a and $b
refer to. Perhaps the default (or at
least an option) should be to duplicate
the object before the change. (May
need to look at refcounts to do this.)
* Matrices. (2 dimensions).
And at least three products: inner, outer,
element by element.
Probably '*', '.' (dot product),
and 'x' (cross product) - also kind of like
>< in |x><y|.
The real problem here is how to deal with slice notation and multiple indeces at the same time, which perl doesn't handle well. Perl supports $a->[1..10] (though it has to actually allocate an array 1..10 to do so) as well as $a->[2][3] ; however mixed versions like $a->[2,3][1..4] are illegal. Nor do entire rows and columns don't have a simple notation, $a->[*][3] or something similar.
Unfortunately, I think that do this kind of work with matrices and tensors we need to break out of perl notation, since its idea of index ranges just isn't powerful enough for these kind of numeric tasks.
* Tensors. (N dimensions).
Arbitrary contractions and products.
* Simpler Mat-lab-ish alternative language,
including one-line
function declarations, i.e.
x = 1..10 by 2;
x[2] # array index
f(x) # function call
Keep perl's x[i][j] I guess. (Optional?)
x[1..10] is going to be hard to keep
separate from x[1,2] vs x[1][2]
Need some consistent notatoin for
slicing up multi-dimension stuff.
Should a=b make a full copy of b?
Should include implicit mulitiplication
rather than perl's implicit function calls
i.e. y=2..10; f(x) = 2 x + 5; x = 2 a y**2.
Implicit defaults to '*' or '.' presumably
(inner product includes matrix and
matrix-vector multiplication ), perhaps
by type, perhaps by options set.
Perhaps embedded perl or C code blocks.
<perl>
</perl>
or
<c>
</c>
API for translating.
We'll see.
I want to keep it simple and fast, so the bells and whistles need to stay optional and keep a simple syntax - for at least some definition of simple.
Jim Mahoney, Marlboro College (mahoney@marlboro.edu)
Copyright 2002 Jim Mahoney
This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself.
perl, PDL, Inline::C