NAME

Vector - a perl scalar reference to a fixed packed array of doubles with arithmetic operations on the scalars, implemented in C.


SYNOPSIS

  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]


DESCRIPTION

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.


AUTHOR

Jim Mahoney, Marlboro College (mahoney@marlboro.edu)


COPYRIGHT

Copyright 2002 Jim Mahoney

This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself.


SEE ALSO

perl, PDL, Inline::C