Spar - the Array interface

spar

To support sparse matrices and other specialized array implementations, Spar allows any class that implements the Array interface to use the array access syntax.

Definition

The Array interface is defined as follows (note that the interface implements multi-dimensional arrays, and uses vectors and parameterized types):
interface Array(| type t, int n |)
{
    t getElement( [int^n] index )
        throws IndexOutOfBoundsException;
    void storeElement( [int^n] index, t elm )
        throws IndexOutOfBoundsException,
               ArrayStoreException;
    [int^n] getSize();
}

If a class wants to allow growing and shrinking of its arrays, it should implement the ElasticArray interface:

interface ElasticArray(| type t, int n |)
    extends Array(| t, n |)
{
    void setSize( [int^n] sz )
        throws NegativeArraySizeException;
    int getRoom();
    void setRoom( int rm );
    void setRoom( [int^n] rm );
    void fitRoom();
}

Example - diagonal view

The following class defines a `view' on the diagonal of a two-dimensional array:
class DiagonalView(| type t |) implements Array(| t, 1 |)
{
    Array(| t, 2 |) ref;

DiagonalView( Array(| t, 2 |) a ){ ref = a; } t getElement( [int^1] ix ){ return ref[ix[0],ix[0]]; } void storeElement( [int^1] ix, t elm ) { ref[ix[0],ix[0]] = elm; } [int^1] getSize() { [int^2] dims = ref.getSize(); return [Math.min( dims[0], dims[1] )]; } }

This class can now be used as follows:
int[*,*] a = new double[5,5];
DiagonalView(| double |) v = DiagonalView(| double |)( a );
a[:,:] = 0;
v[:] = 1;
This will construct and fill `a' with the identity matrix (1 on the diagonal, 0 elsewhere).

Example - transpose view

As another example, the following class implements a transpose view on an array of arbitrary size.
class TransposeView(| type t, int n |)
    implements Array(| t, n |)
{
    Array(| t, n |) ref;

    TransposeView( Array(| t, n |) a ){ ref = a; }
    t getElement( [int^n] ix ){
        return ref revVector( n, ix );
    }
    void storeElement( [int^n] ix, t elm ){
        ref revVector( n, ix ) = elm;
    }
    [int^n] getSize(){
        return revVector( n, ref.getSize() );
    }
    static [int^n] revVector( int n, [int^n] v ){
        int ix;
        [int^n] res;

        macro for( ix :- 0:n; ix++ ){
            res[(n-ix)-1] = v[ix];
        }
        return res;
    }
}
Note that this class even works for 0-dimensional and 1-dimensional arrays. Also note that since this class allows a view on an arbitrary Array class it is possible to compose views. This is demonstrated below, where two transpose views are composed.

This could be used as follows:

int[*,*] a = new double[5,5];
TransposeView(|double|) v = TransposeView(|double|)( a );
TransposeView(|double|) w = TransposeView(|double|)( v );
a[:,:] = 0;
v[:,0] = 1;
w[:,0] = 2;
This results in a matrix `a' where all elements are set to 0, except that the first column (apart from a[0,0]) is set to 1 through the transpose view `v` on `a', and the first row is set to 2 through the transpose view `w' on `v'. Note that since `w' is a transpose view on a transpose view, it is in effect an identity view.

Last modified Sat May 13 15:50:56 2017 UT by Kees van Reeuwijk.