# New Ticket Created by  Josef Höök 
# Please include the string:  [perl #15923]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=15923 >



Pjuh after 2 month of work i'm finally finished with a first release.
This patch adds matrices for Parrot. Current code handles dense and sparse
matrices. It also has a general interface that we can use
for multdim arrays ( interested ?:) ). 

Operations available:
        transp       Transpose
        det          Determinant you can also get determinant value by: 
                     set I0, P0 if P0 is a matrix thatis.
        ludcmp       ludecomposition needed for inverse, determinant and 
                     other operations
        plot_matrix 
Operations not yet available but in near future:
         inverse
         Probably some others too. I cant think of anyone right now.

Files included in patch:

matrix_core.c            basic framework.  
matrix.ops
cell.c                   this file contains the core logic. 
classes/matrix.pmc       lots of stuff todo here :)
include/parrot/matrix_core.h 
include/parrot/cell.h

Have fun with it.. 

/Josef  


-- attachment  1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/32583/26881/9ed7e1/parrot_matrix_020801.patch

diff -urN parrot.orig/MANIFEST parrot/MANIFEST
--- parrot.orig/MANIFEST        Thu Aug  1 16:49:51 2002
+++ parrot/MANIFEST     Thu Aug  1 16:53:12 2002
@@ -12,6 +12,7 @@
 VERSION
 assemble.pl
 byteorder.c
+cell.c
 chartype.c
 chartypes/unicode.c
 chartypes/usascii.c
@@ -20,6 +21,7 @@
 classes/default.pmc
 classes/genclass.pl
 classes/intqueue.pmc
+classes/matrix.pmc
 classes/perlarray.pmc
 classes/perlhash.pmc
 classes/perlint.pmc
@@ -179,6 +181,7 @@
 hash.c
 headers.c
 include/parrot/chartype.h
+include/parrot/cell.h
 include/parrot/debug.h
 include/parrot/dod.h
 include/parrot/embed.h
@@ -193,6 +196,7 @@
 include/parrot/io.h
 include/parrot/jit.h
 include/parrot/key.h
+include/parrot/matrix_core.h
 include/parrot/memory.h
 include/parrot/misc.h
 include/parrot/op.h
@@ -412,6 +416,8 @@
 lib/Text/Balanced.pm
 make.pl
 math.ops
+matrix.ops
+matrix_core.c
 memory.c
 misc.c
 obscure.ops
diff -urN parrot.orig/assemble.pl parrot/assemble.pl
--- parrot.orig/assemble.pl     Thu Aug  1 16:49:51 2002
+++ parrot/assemble.pl  Thu Aug  1 16:58:25 2002
@@ -138,6 +138,7 @@
   $self->{constants}{IntQueue} = 8;
   $self->{constants}{Sub} = 9;
   $self->{constants}{Coroutine} = 10;
+  $self->{constants}{Matrix} = 11;
   $self;
 }
 
diff -urN parrot.orig/cell.c parrot/cell.c
--- parrot.orig/cell.c  Thu Jan  1 01:00:00 1970
+++ parrot/cell.c       Thu Aug  1 17:38:02 2002
@@ -0,0 +1,112 @@
+/* cell.c
+ *  Copyright: (When this is determined...it will go here)
+ *  CVS Info
+ *    $Id: cell.c,v 1.2 2002/07/18 21:19:49 joh Exp joh $
+ *  Overview:
+ *     Represents a cell or a point in multidimensional space
+ *     this is used by matrix and hopefully soon also multidimensional arrays.
+ *
+ *  Data Structure and Algorithms:
+ *   This is one way for calculating offsets in 2 dimensional space.
+ *
+ *   (y-1)X0+x   
+ *
+ *   Where X0 is the length of X-base (fig 1.1). We use this equation in 
+ *   calc_offset to get offset from the buffer we store our data in. 
+ *   Lets say we want to store (2,2) in a buffer. We then take values and do:
+ *   (2-1)3 + 2 = 5. 
+ * 
+ *      ------------------------------------
+ *      base | 1 | 2 | 3 | 4 |*5*|  | ....
+ *      ------------------------------------- fig 1.0
+ *
+ *
+ *      Y                                                         
+ *      |  
+ *      | ---------------                                         
+ *      | [ 7 ][ 8 ][ 9 ] 
+ *      | [ 4 ][ 5 ][ 6 ]                                                     
+ *      | [ 1 ][ 2 ][ 3 ] <-------- a CELL                                
+ *      |------------------ X
+ *        |-------------|                                               
+ *            X0          fig 1.1   
+ *      virtual_addr is the return value from a calculation of CELL's position.
+ *      Changes:  2002/08/01    
+ *                Our cell_buffer starts from 0 equation is now y*x0+x.
+ *
+ *      Current code has complexity: 
+ *
+ *        O(1) writing.                                                  
+ *        O(1) reading, worst case O(N).
+ *
+ *  History:
+ *      by Josef Höök. 2002-07-18
+ *
+ *  Notes:
+ *        Future plan is to make calc_offset polymorphic 
+ *        and to make it handle multidimensions. 
+ *  References:
+ *     none yet 
+ */
+
+#include "parrot/parrot.h"
+
+/* 
+ * CALC OFFSET FOR MATRICES 
+ * We always store matrix size at base address
+ * $1 is addr of our CELL_BUFFER structure.
+ * $2 is a key pointer containing positions in 2 dimensional space 
+ */
+INTVAL calc_offset(void *base, KEY k) 
+{
+    
+    CELL_B *cell_data = (CELL_B *)base;
+    KEY *dim_key;
+    INTVAL offset = 0;
+    dim_key = cell_data->dimension;
+    
+    if(cell_data->cell_buffer != NULL && dim_key != NULL ) {
+       
+       offset =  (INTVAL) ((k.next->atom.val.int_val)*(dim_key->atom.val.int_val) + 
+k.atom.val.int_val );
+       
+    }
+    return offset;
+}
+
+/*
+ *  Expands the cell_buffer Buffer in a matrix or multi array
+ *  This doesnt grow the matrix itself 
+ *  see expand_matrix() for that.
+ */
+void expand_cell_buffer( struct Parrot_Interp *interpreter, void *data, INTVAL 
+new_size )
+{
+    CELL_B *b = data;
+    if(new_size > b->size) {
+       Parrot_reallocate(interpreter, b->cell_buffer, new_size * sizeof(CELL));
+       b->free_cell += (new_size - b->size);
+       b->size = new_size;
+    }
+    
+}
+
+
+/*
+ * expand data buffer with one cell 
+ */
+CELL *new_cell( struct Parrot_Interp *interpreter, void *data ) 
+{  
+    CELL *ret_cell;
+    INTVAL new_size = 0;
+    CELL_B *cell_b = data;
+    ret_cell = (CELL *)cell_b->cell_buffer->bufstart;
+    
+    if((cell_b->free_cell-1) > 0) {
+       cell_b->free_cell -= 1;
+    } else {
+       new_size = cell_b->size*2; 
+       expand_cell_buffer( interpreter, cell_b, new_size);
+       cell_b->free_cell -= 1;
+       ret_cell = (CELL *)cell_b->cell_buffer->bufstart;
+    }
+    return &ret_cell[cell_b->size - cell_b->free_cell-1]; // notice -1 because we 
+start at 0
+}
diff -urN parrot.orig/classes/matrix.pmc parrot/classes/matrix.pmc
--- parrot.orig/classes/matrix.pmc      Thu Jan  1 01:00:00 1970
+++ parrot/classes/matrix.pmc   Thu Aug  1 17:25:25 2002
@@ -0,0 +1,695 @@
+/* matrix.pmc
+ *  Copyright: (When this is determined...it will go here)
+ *  CVS Info
+ *     $Id: matrix.pmc,v 1.3 2002/08/01 08:47:44 joh Exp joh $
+ *  Overview:
+ *     Base matrix class yadi yadi yadi
+ *  Data Structure and Algorithms:
+ *  History: 
+ *          by Josef Höök <[EMAIL PROTECTED]>
+ *  Notes:
+ *  References:
+ *  Todo: Figure out how we are going handle INTVAL, NUM and BIGNUMS 
+ *        since functions like determinants must use double precision..    
+ */
+
+#include "parrot/parrot.h"
+
+pmclass Matrix {
+    
+    void init () {
+       SELF->flags |= (PMC_is_buffer_ptr_FLAG | PMC_is_PMC_ptr_FLAG);
+       SELF->data = NULL;
+       SELF->cache.int_val = 0;
+       
+    }
+    
+    void init_pmc (PMC* initializer) {
+       SELF->flags |= (PMC_is_buffer_ptr_FLAG | PMC_is_PMC_ptr_FLAG);
+       SELF->data = NULL;
+       SELF->cache.int_val = 0;
+       // I use a PMC key class  as wrapper to pass initialvalues to our matrix
+       //  OBS OBS OBS this dont work since we dont have a multidim key standard yet
+       /*if((initializer->vtable->type(INTERP, SELF)) == enum_class_Key) {
+         init_matrix(INTERP, SELF, initializer->data);
+         } else{*/
+           init_matrix(INTERP, SELF, NULL);
+           //}
+    }
+    
+    void morph (INTVAL type) {
+    }
+    
+    PMC* mark (PMC* end_of_used_list) {
+       return NULL;
+    }
+    
+    void destroy () {
+    }
+    
+    INTVAL type () {
+       return enum_class_Matrix;
+    }
+    
+    INTVAL type_keyed (KEY * key) {
+       return 0;
+    }
+    
+    UINTVAL subtype (INTVAL type) {
+       return 0;
+    }
+    
+    UINTVAL subtype_keyed (KEY * key, INTVAL type) {
+       return 0;
+    }
+    
+    STRING* name () {
+       return whoami;
+    }
+    
+    STRING* name_keyed (KEY * key) {
+       return NULL;
+    }
+    
+    PMC* clone () {
+       return NULL;
+    }
+    
+    PMC* clone_keyed (KEY * key) {
+       return NULL;
+    }
+    
+    PMC* find_method (STRING* method_name) {
+       return NULL;
+    }
+    
+    PMC* find_method_keyed (KEY * key, STRING* method_name) {
+       return NULL;  
+    }
+    /* return determinant of matrix */
+    INTVAL get_integer () {
+       return (INTVAL)matrix_det( INTERP, SELF->data ); 
+    }
+    
+    INTVAL get_integer_keyed (KEY * key) {
+       return  (INTVAL)get_matrix_keyed( INTERP, SELF->data, key );
+    }
+    
+    /* return determinant of matrix */
+    FLOATVAL get_number () {
+       return matrix_det( INTERP, SELF->data ); 
+    }
+    
+    FLOATVAL get_number_keyed (KEY * key) {
+       return  get_matrix_keyed( INTERP, SELF->data, key );
+    }
+    
+    BIGNUM* get_bignum () {
+       return NULL;
+    }
+    
+    BIGNUM* get_bignum_keyed (KEY * key) {
+       return NULL;
+    }
+    
+    STRING* get_string () {
+       return NULL;
+    }
+    
+    STRING* get_string_keyed (KEY * key) {
+       return NULL;
+    }
+    
+    INTVAL get_bool () {
+       return 0;
+    }
+    
+    INTVAL get_bool_keyed (KEY * key) {
+       return 0;
+    }
+    
+    INTVAL elements () {
+       return 0;
+    }
+    
+    INTVAL elements_keyed (KEY * key) {
+       return 0;
+    }
+    
+    PMC* get_pmc () {
+       return NULL;
+    }
+    
+    PMC* get_pmc_keyed (KEY * key) {
+       return NULL;
+    }
+    
+    INTVAL is_same (PMC* pmc2) {
+       return 0;
+    }
+    
+    INTVAL is_same_keyed (KEY * key, PMC* pmc2, KEY * pmc2_key) {
+       return 0;
+    }
+    
+    void set_integer (PMC * value) {
+       
+       // This code loops through our matrix an prints it output
+       // should be removed as soon as possible.
+       MATRIX *gi_matrix;
+       CELL *base;
+       CELL *ptr;
+       INTVAL size;
+       INTVAL stalker;
+       INTVAL x0;
+       
+       gi_matrix = SELF->data;
+       base = (CELL *)gi_matrix->cell_buffer->bufstart;
+       size = stalker = gi_matrix->size;
+       x0 = gi_matrix->dimension->atom.val.int_val;
+       while(stalker >= 0) {
+           ptr = &base[size-stalker];
+           
+           ptr->data.num_val = value->vtable->get_integer(INTERP, value);
+           
+           printf("%f\t", ptr->data.num_val);
+           if(!((size-stalker) % x0)) {
+               printf("\n");
+           }
+           
+           stalker--;
+       }
+       
+    }
+    
+    void set_integer_native (INTVAL value) {
+    }
+    
+    void set_integer_bignum (BIGNUM * value) {
+    }
+    
+    void set_integer_same (PMC * value) {
+    }
+    
+    void set_integer_keyed (KEY * key, INTVAL src_value) {
+       set_matrix_keyed( INTERP, SELF->data, key, src_value );     
+    }
+    
+    void set_number (PMC * value) {
+    }
+    
+    void set_number_native (FLOATVAL value) {
+    }
+    
+    void set_number_bignum (BIGNUM * value) {
+    }
+    
+    void set_number_same (PMC * value) {
+    }
+    
+    void set_number_keyed (KEY * key, FLOATVAL src_value) {
+    }
+    
+    void set_bignum (PMC * value) {
+    }
+    
+    void set_bignum_int (INTVAL value) {
+    }
+    
+    void set_bignum_native (BIGNUM * value) {
+    }
+    
+    void set_bignum_float (FLOATVAL value) {
+    }
+    
+    void set_bignum_same (PMC * value) {
+    }
+    
+    void set_bignum_keyed (KEY * key, BIGNUM* src_value) {
+    }
+    
+    void set_string (PMC * value) {
+    }
+    
+    void set_string_native (STRING * value) {
+    }
+    
+    void set_string_unicode (STRING * value) {
+    }
+    
+    void set_string_other (STRING * value) {
+    }
+    
+    void set_string_same (PMC * value) {
+    }
+    
+    void set_string_keyed (KEY * key, STRING* src_value) {
+    }
+    
+    void set_pmc (PMC* value) {
+    }
+    
+    void set_pmc_keyed (KEY * key, PMC* src_value, KEY * src_value_key) {
+    }
+    
+    void set_same (PMC* value) {
+    }
+    
+    void set_same_keyed (KEY * key, PMC* src_value, KEY * src_value_key) {
+    }
+    
+    void add (PMC * value, PMC* dest) {
+       
+       // should be replaced
+       MATRIX *gi_matrix;
+       CELL *base;
+       CELL *ptr;
+       INTVAL size;
+       INTVAL stalker;
+       INTVAL x0;
+       dest->vtable = &Parrot_base_vtables[enum_class_Matrix];    
+       gi_matrix = SELF->data;
+       base = (CELL *)gi_matrix->cell_buffer->bufstart;
+       size = stalker = gi_matrix->size;
+       x0 = gi_matrix->dimension->atom.val.int_val;
+       while(stalker >= 0) {
+           ptr = &base[size-stalker];
+           
+           ptr->data.num_val += value->vtable->get_integer(INTERP, value);
+           
+           printf("%f\t", ptr->data.num_val);
+           if(!((size-stalker) % x0)) {
+               printf("\n");
+           }
+           
+           stalker--;
+       }
+       
+    }
+    
+    void add_int (INTVAL value, PMC* dest) {
+       
+       // should be replaced
+       MATRIX *gi_matrix;
+       CELL *base;
+       CELL *ptr;
+       INTVAL size;
+       INTVAL stalker;
+       INTVAL x0;
+       
+       gi_matrix = SELF->data;
+       base = (CELL *)gi_matrix->cell_buffer->bufstart;
+       size = stalker = gi_matrix->size;
+       x0 = gi_matrix->dimension->atom.val.int_val;
+       while(stalker >= 0) {
+           ptr = &base[size-stalker];
+           ptr->data.num_val += value;
+           
+           stalker--;
+       }
+       
+       
+    }
+    
+    void add_bignum (BIGNUM * value, PMC* dest) {
+    }
+    
+    void add_float (FLOATVAL value, PMC* dest) {
+    }
+    
+    void add_same (PMC * value, PMC* dest) {
+    }
+    
+    void add_keyed (KEY * key, PMC* src_value, KEY * src_value_key, PMC* dest_value, 
+KEY * dest_value_key) {
+    }
+    
+    void subtract (PMC * value, PMC* dest) {
+    }
+    
+    void subtract_int (INTVAL value, PMC* dest) {
+       
+       
+       // should be replaced
+       MATRIX *gi_matrix;
+       CELL *base;
+       CELL *ptr;
+       INTVAL size;
+       INTVAL stalker;
+       INTVAL x0;
+       
+       gi_matrix = SELF->data;
+       base = (CELL *)gi_matrix->cell_buffer->bufstart;
+       size = stalker = gi_matrix->size;
+       x0 = gi_matrix->dimension->atom.val.int_val;
+       while(stalker >= 0) {
+           ptr = &base[size-stalker];
+           ptr->data.num_val -= value;
+           
+           stalker--;
+       }
+       
+       
+       
+       
+       
+       
+    }
+    
+    void subtract_bignum (BIGNUM * value, PMC* dest) {
+    }
+    
+    void subtract_float (FLOATVAL value, PMC* dest) {
+    }
+    
+    void subtract_same (PMC * value, PMC* dest) {
+    }
+    
+    void subtract_keyed (KEY * key, PMC* src_value, KEY * src_value_key, PMC* 
+dest_value, KEY * dest_value_key) {
+    }
+    
+    void multiply (PMC * value, PMC* dest) {
+       
+       // dot product 
+    }
+    
+    void multiply_int (INTVAL value, PMC* dest) {
+       
+       
+       // should be replace
+       MATRIX *gi_matrix;
+       CELL *base;
+       CELL *ptr;
+       INTVAL size;
+       INTVAL stalker;
+       INTVAL x0;
+       
+       gi_matrix = SELF->data;
+       base = (CELL *)gi_matrix->cell_buffer->bufstart;
+       size = stalker = gi_matrix->size;
+       x0 = gi_matrix->dimension->atom.val.int_val;
+       while(stalker >= 0) {
+           ptr = &base[size-stalker];
+           ptr->data.num_val *= value;
+           stalker--;
+       }
+       
+       
+       
+    }
+
+    void multiply_bignum (BIGNUM * value, PMC* dest) {
+    }
+    
+    void multiply_float (FLOATVAL value, PMC* dest) {
+    }
+    
+    void multiply_same (PMC * value, PMC* dest) {
+    }
+    
+    void multiply_keyed (KEY * key, PMC* src_value, KEY * src_value_key, PMC* 
+dest_value, KEY * dest_value_key) {
+    }
+    
+    void divide (PMC * value, PMC* dest) {
+    }
+    
+    void divide_int (INTVAL value, PMC* dest) {
+       
+       
+       // should be replaced
+       MATRIX *gi_matrix;
+       CELL *base;
+       CELL *ptr;
+       INTVAL size;
+       INTVAL stalker;
+       INTVAL x0;
+
+       gi_matrix = SELF->data;
+       base = (CELL *)gi_matrix->cell_buffer->bufstart;
+       size = stalker = gi_matrix->size;
+       x0 = gi_matrix->dimension->atom.val.int_val;
+       while(stalker >= 0) {
+           ptr = &base[size-stalker];
+           ptr->data.num_val = ptr->data.num_val / value;
+           stalker--;
+       }
+       
+       
+       
+       
+       
+    }
+    
+    void divide_bignum (BIGNUM * value, PMC* dest) {
+    }
+    
+    void divide_float (FLOATVAL value, PMC* dest) {
+    }
+    
+    void divide_same (PMC * value, PMC* dest) {
+    }
+    
+    void divide_keyed (KEY * key, PMC* src_value, KEY * src_value_key, PMC* 
+dest_value, KEY * dest_value_key) {
+    }
+    
+    void modulus (PMC * value, PMC* dest) {
+    }
+    
+    void modulus_int (INTVAL value, PMC* dest) {
+       
+       // should be replaced
+       MATRIX *gi_matrix;
+       CELL *base;
+       CELL *ptr;
+       INTVAL size;
+       INTVAL stalker;
+       INTVAL x0;
+       
+       gi_matrix = SELF->data;
+       base = (CELL *)gi_matrix->cell_buffer->bufstart;
+       size = stalker = gi_matrix->size;
+       x0 = gi_matrix->dimension->atom.val.int_val;
+       while(stalker >= 0) {
+           ptr = &base[size-stalker];
+           ptr->data.num_val = ((INTVAL)ptr->data.num_val) % value;
+           stalker--;
+       }
+       
+       
+    }
+    
+    void modulus_bignum (BIGNUM * value, PMC* dest) {
+    }
+    
+    void modulus_float (FLOATVAL value, PMC* dest) {
+    }
+    
+    void modulus_same (PMC * value, PMC* dest) {
+    }
+    
+    void modulus_keyed (KEY * key, PMC* src_value, KEY * src_value_key, PMC* 
+dest_value, KEY * dest_value_key) {
+    }
+    
+    void neg (PMC* dest) {
+    }
+    
+    void neg_keyed (KEY * key, PMC* dest_value, KEY * dest_value_key) {
+    }
+    
+    void bitwise_or (PMC * value, PMC* dest) {
+    }
+    
+    void bitwise_or_int (INTVAL value, PMC* dest) {
+    }
+    
+    void bitwise_or_same (PMC * value, PMC* dest) {
+    }
+    
+    void bitwise_or_keyed (KEY * key, PMC* src_value, KEY * src_value_key, PMC* 
+dest_value, KEY * dest_value_key) {
+    }
+    
+    void bitwise_and (PMC * value, PMC* dest) {
+    }
+
+    void bitwise_and_int (INTVAL value, PMC* dest) {
+    }
+
+    void bitwise_and_same (PMC * value, PMC* dest) {
+    }
+
+    void bitwise_and_keyed (KEY * key, PMC* src_value, KEY * src_value_key, PMC* 
+dest_value, KEY * dest_value_key) {
+    }
+
+    void bitwise_xor (PMC * value, PMC* dest) {
+    }
+
+    void bitwise_xor_int (INTVAL value, PMC* dest) {
+    }
+
+    void bitwise_xor_same (PMC * value, PMC* dest) {
+    }
+
+    void bitwise_xor_keyed (KEY * key, PMC* src_value, KEY * src_value_key, PMC* 
+dest_value, KEY * dest_value_key) {
+    }
+
+    void bitwise_not (PMC* dest) {
+    }
+
+    void bitwise_not_keyed (KEY * key, PMC* dest_value, KEY * dest_value_key) {
+    }
+
+    void bitwise_shr (PMC * value, PMC* dest) {
+    }
+
+    void bitwise_shr_int (INTVAL value, PMC* dest) {
+    }
+
+    void bitwise_shr_same (PMC * value, PMC* dest) {
+    }
+
+    void bitwise_shr_keyed (KEY * key, PMC* src_value, KEY * src_value_key, PMC* 
+dest_value, KEY * dest_value_key) {
+    }
+
+    void bitwise_shl (PMC * value, PMC* dest) {
+    }
+
+    void bitwise_shl_int (INTVAL value, PMC* dest) {
+    }
+
+    void bitwise_shl_same (PMC * value, PMC* dest) {
+    }
+
+    void bitwise_shl_keyed (KEY * key, PMC* src_value, KEY * src_value_key, PMC* 
+dest_value, KEY * dest_value_key) {
+    }
+
+    void concatenate (PMC * value, PMC* dest) {
+    }
+
+    void concatenate_native (STRING * value, PMC* dest) {
+    }
+
+    void concatenate_unicode (STRING * value, PMC* dest) {
+    }
+
+    void concatenate_other (STRING * value, PMC* dest) {
+    }
+
+    void concatenate_same (PMC * value, PMC* dest) {
+    }
+
+    void concatenate_keyed (KEY * key, PMC* src_value, KEY * src_value_key, PMC* 
+dest_value, KEY * dest_value_key) {
+    }
+
+    INTVAL is_equal (PMC* value) {
+       return 0;
+    }
+
+    INTVAL is_equal_keyed (KEY * key, PMC* src_value, KEY * src_value_key) {
+       return 0;
+    }
+
+    INTVAL cmp (PMC* value) {
+       return 0;
+    }
+
+    INTVAL cmp_keyed (KEY * key, PMC* src_value, KEY * src_value_key) {
+       return 0;
+    }
+
+    INTVAL cmp_num (PMC* value) {
+       return 0;
+    }
+
+    INTVAL cmp_num_keyed (KEY * key, PMC* src_value, KEY * src_value_key) {
+       return 0;
+    }
+
+    INTVAL cmp_string (PMC* value) {
+       return 0;
+    }
+
+    INTVAL cmp_string_keyed (KEY * key, PMC* src_value, KEY * src_value_key) {
+       return 0;
+    }
+
+    void logical_or (PMC* value, PMC* dest) {
+    }
+
+    void logical_or_keyed (KEY * key, PMC* src_value, KEY * src_value_key, PMC* 
+dest_value, KEY * dest_value_key) {
+    }
+
+    void logical_and (PMC* value, PMC* dest) {
+    }
+
+    void logical_and_keyed (KEY * key, PMC* src_value, KEY * src_value_key, PMC* 
+dest_value, KEY * dest_value_key) {
+    }
+
+    void logical_xor (PMC* value, PMC* dest) {
+    }
+
+    void logical_xor_keyed (KEY * key, PMC* src_value, KEY * src_value_key, PMC* 
+dest_value, KEY * dest_value_key) {
+    }
+
+    void logical_not (PMC* dest) {
+    }
+
+    void logical_not_keyed (KEY * key, PMC* dest_value, KEY * dest_value_key) {
+    }
+
+    void repeat (PMC* value, PMC* dest) {
+    }
+
+    void repeat_keyed (KEY * key, PMC* src_value, KEY * src_value_key, PMC* 
+dest_value, KEY * dest_value_key) {
+    }
+
+    void repeat_int (INTVAL value, PMC* dest) {
+    }
+
+    void repeat_int_keyed (KEY * key, INTVAL src_value, PMC* dest_value, KEY * 
+dest_value_key) {
+    }
+
+    void increment () {
+    }
+
+    void increment_keyed (KEY * key) {
+    }
+
+    void decrement () {
+    }
+
+    void decrement_keyed (KEY * key) {
+    }
+
+    INTVAL exists_keyed (KEY * key) {
+       return 0;
+    }
+
+    INTVAL defined () {
+       return 0;
+    }
+
+    INTVAL defined_keyed (KEY * key) {
+       return 0;
+    }
+
+    void delete_keyed (KEY * key) {
+    }
+
+    KEY* nextkey_keyed (KEY * key) {
+       return NULL;
+    }
+
+    void substr (INTVAL offset, INTVAL length, PMC* dest) {
+    }
+
+    void substr_keyed (KEY * key, INTVAL offset, INTVAL length, PMC* dest_value, KEY 
+* dest_value_key) {
+    }
+
+    STRING* substr_str (INTVAL offset, INTVAL length) {
+       return NULL;
+    }
+
+    STRING* substr_str_keyed (KEY * key, INTVAL offset, INTVAL length) {
+       return NULL;
+    }
+
+}
diff -urN parrot.orig/config/gen/makefiles/root.in parrot/config/gen/makefiles/root.in
--- parrot.orig/config/gen/makefiles/root.in    Thu Aug  1 16:49:51 2002
+++ parrot/config/gen/makefiles/root.in Thu Aug  1 17:36:30 2002
@@ -68,7 +68,8 @@
 $(INC)/pmc.h $(INC)/key.h $(INC)/hash.h $(INC)/resources.h $(INC)/platform.h ${cg_h} 
\
 $(INC)/interp_guts.h ${jit_h} $(INC)/rx.h $(INC)/rxstacks.h \
 $(INC)/embed.h $(INC)/warnings.h $(INC)/misc.h $(INC)/debug.h $(INC)/pmc.h \
-$(INC)/key.h $(INC)/hash.h $(INC)/smallobject.h $(INC)/headers.h $(INC)/dod.h
+$(INC)/key.h $(INC)/hash.h $(INC)/smallobject.h $(INC)/headers.h $(INC)/dod.h \
+$(INC)/matrix_core.h $(INC)/cell.h
 
 ALL_H_FILES = $(GENERAL_H_FILES)
 
@@ -92,7 +93,7 @@
                                 platform$(O) ${jit_o} resources$(O) rx$(O) 
rxstacks$(O) \
                                 embed$(O) warnings$(O) misc$(O) ${cg_o} \
                                 packout$(O) byteorder$(O) debug$(O) smallobject$(O) \
-                                headers$(O) dod$(O)
+                                headers$(O) dod$(O) matrix_core$(O) cell$(O)
 
 O_FILES = $(INTERP_O_FILES) \
              $(IO_O_FILES) \
@@ -315,6 +316,10 @@
 
 hash$(O) : $(GENERAL_H_FILES)
 
+cell$(O) : $(GENERAL_H_FILES)
+
+matrix_core$(O) : $(GENERAL_H_FILES)
+
 jit$(O) : $(GENERAL_H_FILES)
 
 jit_cpu$(O): $(GENERAL_H_FILES) $(INC)/jit_emit.h
diff -urN parrot.orig/global_setup.c parrot/global_setup.c
--- parrot.orig/global_setup.c  Thu Aug  1 16:49:51 2002
+++ parrot/global_setup.c       Thu Aug  1 16:56:08 2002
@@ -32,6 +32,7 @@
     Parrot_IntQueue_class_init(enum_class_IntQueue);
     Parrot_Sub_class_init(enum_class_Sub);
     Parrot_Coroutine_class_init(enum_class_Coroutine);
+    Parrot_Matrix_class_init(enum_class_Matrix);
 
     /* Now register the names of the PMCs */
 
@@ -85,6 +86,10 @@
     Parrot_base_classname_hash->vtable->set_integer_keyed(NULL,
                                                           Parrot_base_classname_hash, 
&key, enum_class_Coroutine);
 
+    MAKE_KEY_STRING(key, Parrot_base_vtables[enum_class_Matrix].name(NULL, NULL));
+    Parrot_base_classname_hash->vtable->set_integer_keyed(NULL,
+                                                          Parrot_base_classname_hash, 
+&key, enum_class_Matrix);
+
 }
 
 /*
diff -urN parrot.orig/include/parrot/cell.h parrot/include/parrot/cell.h
--- parrot.orig/include/parrot/cell.h   Thu Jan  1 01:00:00 1970
+++ parrot/include/parrot/cell.h        Thu Aug  1 15:51:28 2002
@@ -0,0 +1,35 @@
+/* cell.h
+ *  Copyright: (When this is determined...it will go here)
+ *  CVS Info
+ *     $Id$
+ *  Overview:
+ *     header file for cell.c
+ *          by Josef Höök <[EMAIL PROTECTED]>
+ */
+
+#define CELL_H
+  
+
+typedef struct _cell CELL;
+typedef struct _cell_buffer CELL_B;
+
+/* 
+ * cell buffer representation
+ */
+struct _cell_buffer { 
+    Buffer *cell_buffer;
+    INTVAL size;
+    INTVAL free_cell;
+    KEY *dimension;
+};
+
+struct _cell {
+    UnionVal data;
+    //  INTVAL *data;
+    INTVAL virtual_addr; /* used to handle offsets */
+};
+
+
+INTVAL calc_offset( void *base, KEY k );
+void expand_cell_buffer( struct Parrot_Interp *interpreter, void *matrix, INTVAL 
+new_size );
+CELL *new_cell( struct Parrot_Interp *interpreter, void *data );
diff -urN parrot.orig/include/parrot/global_setup.h 
parrot/include/parrot/global_setup.h
--- parrot.orig/include/parrot/global_setup.h   Thu Aug  1 16:49:51 2002
+++ parrot/include/parrot/global_setup.h        Thu Aug  1 16:56:49 2002
@@ -28,6 +28,7 @@
 void Parrot_IntQueue_class_init(INTVAL);
 void Parrot_Sub_class_init(INTVAL);
 void Parrot_Coroutine_class_init(INTVAL);
+void Parrot_Matrix_class_init(INTVAL);
 void Parrot_Closure_class_init(INTVAL);
 void Parrot_Continuation_class_init(INTVAL);
 
diff -urN parrot.orig/include/parrot/matrix_core.h parrot/include/parrot/matrix_core.h
--- parrot.orig/include/parrot/matrix_core.h    Thu Jan  1 01:00:00 1970
+++ parrot/include/parrot/matrix_core.h Thu Aug  1 15:50:17 2002
@@ -0,0 +1,101 @@
+/* matrix_core.h
+ *
+ * 
+ * 
+ */
+
+#define MATRIX_CORE_H
+#define CELL_POOL_SIZE 16
+
+typedef FLOATVAL MATVAL;  // matrix data type, what we store our data in.
+
+#define MATROW(m) ((MATRIX *)(m))->dimension->atom.val.int_val
+#define MATCOL(m) ((MATRIX *)(m))->dimension->next->atom.val.int_val
+#define MATSIZ(m) MATROW(m)*MATCOL(m)
+#define ROW(c) c.atom.val.int_val
+#define COL(c) c.next->atom.val.int_val
+
+
+/* This is taken from SuperLU  hopefully get merged into our code */
+
+typedef enum {
+    NC,        /* column-wise, no supernode */
+    NR,        /* row-wize, no supernode */
+    SC,        /* column-wise, supernode */
+    SR,        /* row-wise, supernode */
+    NCP,       /* column-wise, column-permuted, no supernode 
+                  (The consecutive columns of nonzeros, after permutation,
+                 may not be stored  contiguously.) */
+    DN         /* Fortran style column-wise storage for dense matrix */
+} Stype_t;
+
+typedef enum {
+    _S,         /* single */
+    _D,         /* double */
+    _C,         /* single complex */
+    _Z          /* double complex */
+} Dtype_t;
+
+typedef enum {
+    GE,        /* general */
+    TRLU,      /* lower triangular, unit diagonal */
+    TRUU,      /* upper triangular, unit diagonal */
+    TRL,       /* lower triangular */
+    TRU,       /* upper triangular */
+    SYL,       /* symmetric, store lower half */
+    SYU,       /* symmetric, store upper half */
+    HEL,       /* Hermitian, store lower half */
+    HEU        /* Hermitian, store upper half */
+} Mtype_t;
+
+
+typedef struct {
+    Stype_t Stype; /* Storage type: interprets the storage structure 
+                     pointed to by *Store. */
+    Dtype_t Dtype; /* Data type. */
+    Mtype_t Mtype; /* Matrix type: describes the mathematical property of 
+                     the matrix. */
+    int  nrow;     /* number of rows */
+    int  ncol;     /* number of columns */
+    void *Store;   /* pointer to the actual storage of the matrix */
+} SuperMatrix;
+
+/* End of SuperLU */
+
+
+// I guess we should use superlu representation of different matrix types instead of 
+this..
+typedef enum {
+    enum_matrix_dense,
+    enum_matrix_sparse,
+    enum_matrix_diagonal
+} MATRIX_TYPE;
+
+
+typedef struct _matrix MATRIX;
+
+struct _matrix {
+    /* Cell header */
+    Buffer *cell_buffer; /* containing cells */ 
+    INTVAL size;  /* size of matrix */
+    INTVAL free_cell; /* numof free cells in cell_buffer */
+    KEY *dimension;  /* rows and columns */
+    /* Matrix */
+    MATRIX_TYPE type; /* type of matrix */
+    INTVAL pivsign; /* pivot sign either +1 or -1 */ 
+/*
+ *INTVAL sub_matrix[NUM_OF_ALLOWED_SUBS]; 
+ * i want to be able to expand
+ * our matrix, this could be done
+ * with glueing submatrices.
+ */
+};
+
+MATRIX *new_matrix( Interp *interpreter );
+void init_matrix( Interp *interpreter, PMC *self, KEY *key ); 
+void set_matrix_keyed( Interp *interpreter, MATRIX *sik_matrix, KEY *key, MATVAL 
+src_value );
+MATVAL get_matrix_keyed( Interp *interpreter, MATRIX *mg_matrix, KEY *key );
+void set_matrix( Interp *interpreter, MATRIX *sik_matrix, INTVAL row, INTVAL col, 
+MATVAL src_value );
+MATVAL get_matrix( Interp *interpreter, MATRIX *mg_matrix, INTVAL row, INTVAL col ) ;
+MATRIX *matrix_ludcmp( Interp *interpreter, MATRIX *A );
+MATVAL matrix_det( Interp *interpreter, MATRIX *A );
+void plot_matrix( Interp *interpreter, MATRIX *A );
diff -urN parrot.orig/include/parrot/parrot.h parrot/include/parrot/parrot.h
--- parrot.orig/include/parrot/parrot.h Thu Aug  1 16:49:51 2002
+++ parrot/include/parrot/parrot.h      Thu Aug  1 17:24:23 2002
@@ -137,6 +137,8 @@
 #include "parrot/misc.h"
 #include "parrot/debug.h"
 #include "parrot/sub.h"
+#include "parrot/cell.h"
+#include "parrot/matrix_core.h"
 #endif
 
 /*
diff -urN parrot.orig/include/parrot/pmc.h parrot/include/parrot/pmc.h
--- parrot.orig/include/parrot/pmc.h    Thu Aug  1 16:49:51 2002
+++ parrot/include/parrot/pmc.h Thu Aug  1 16:54:38 2002
@@ -25,6 +25,7 @@
     enum_class_IntQueue,
     enum_class_Sub,
     enum_class_Coroutine,
+    enum_class_Matrix,
     enum_class_Closure,
     enum_class_Continuation,
     enum_class_max = 100
diff -urN parrot.orig/matrix.ops parrot/matrix.ops
--- parrot.orig/matrix.ops      Thu Jan  1 01:00:00 1970
+++ parrot/matrix.ops   Thu Aug  1 17:25:50 2002
@@ -0,0 +1,138 @@
+/*
+** matrix.ops
+*/
+
+VERSION = PARROT_VERSION;
+
+=head1 NAME
+
+math.ops
+
+=cut
+
+=head1 DESCRIPTION
+
+Parrot's library of matrix ops.
+
+=cut
+
+
+########################################
+
+=head2 Basic matrix operations
+
+Implementations of various matrix operations
+
+=over 4
+
+=cut
+
+########################################
+
+=item B<transp>( out PMC, in PMC )
+
+Transpose Matrix
+
+
+ 1 2 3        1 4 7 
+ 4 5 6 ---->  2 5 8
+ 7 8 9        3 6 9
+
+
+=cut
+
+
+inline op transp( out PMC, in PMC ) {
+
+ MATRIX *matrix;
+ INTVAL row = 0;
+ INTVAL col = 0;
+ INTVAL rowbase = 0; 
+ INTVAL colbase =  0;
+
+  KEY temp_key;
+  KEY foo;
+
+ temp_key.next = &foo;
+ matrix = $2->data;
+ rowbase = matrix->dimension->atom.val.int_val;
+ colbase = matrix->dimension->next->atom.val.int_val;
+
+     while(row < rowbase) {
+     col = 0;
+        while(col < colbase) {
+            temp_key.atom.val.int_val = row;
+            temp_key.next->atom.val.int_val = col;
+            $1->vtable->set_integer_keyed(interpreter, $1, &temp_key, 
+            $2->vtable->get_integer_keyed(interpreter, $2, &temp_key));
+        col++;
+        }
+     row++;
+    }
+   goto NEXT();
+}
+
+
+########################################
+
+=item B<det>( out INT, in PMC )
+
+Calculates the determinant of a matrix.
+This is the same as doing 
+set I0, P0 where P0 is a matrix PMC.
+
+=cut
+
+
+inline op det( out INT, in PMC ) {
+
+$1 = matrix_det( interpreter, $2->data );
+goto NEXT();
+
+}
+
+########################################
+
+=item B<ludcmp>( out PMC, in PMC )
+
+Calculates the LU decomposition of $2.
+JOH write some more here
+
+=cut
+
+
+inline op ludcmp( out PMC, in PMC ) {
+
+$1->data =  matrix_ludcmp( interpreter, $2->data );
+
+goto NEXT();
+}
+
+########################################
+
+=item B<plot_matrix>( in PMC )
+
+Plots matrix $1 to stdout.
+
+=cut
+
+inline op plot_matrix( in PMC )  {
+
+plot_matrix( interpreter, $1->data );
+
+goto NEXT();
+}
+
+########################################
+
+
+=head1 COPYRIGHT
+
+Copyright (C) 2001-2002 Yet Another Society. All rights reserved.
+
+=head1 LICENSE
+
+This program is free software. It is subject to the same license
+as the Parrot interpreter itself.
+
+=cut
diff -urN parrot.orig/matrix_core.c parrot/matrix_core.c
--- parrot.orig/matrix_core.c   Thu Jan  1 01:00:00 1970
+++ parrot/matrix_core.c        Thu Aug  1 17:27:47 2002
@@ -0,0 +1,317 @@
+/* matrix_core.c
+ *  Copyright: (When this is determined...it will go here)
+ *  CVS Info
+ *     $Id: matrix_core.c,v 1.5 2002/08/01 13:00:14 joh Exp joh $
+ *  Overview:
+ *     Core matrix code 
+ *  Data Structure and Algorithms:
+ *         see cell.c for documentation on data structure used
+ *  History: 
+ *          by Josef Höök <[EMAIL PROTECTED]> 2002-07-18
+ *  Notes:
+ *  References:
+ *  Todo: 
+ *         -Start looking at glue, unglue:
+ *        -Implement LUDecomposition: almost done
+ */
+#include "parrot/parrot.h"
+
+MATRIX *new_matrix( Interp *interpreter ) 
+{
+//  XXX
+//    MATRIX *m = (MATRIX *)new_tracked_header(interpreter, sizeof(*m));
+//    i guess this is outdated could someone confirm if its 
+//    correct to use buffer_like header instead        
+    MATRIX *m = (MATRIX *)new_bufferlike_header(interpreter, sizeof(*m));
+    m->size = CELL_POOL_SIZE;
+    m->free_cell = CELL_POOL_SIZE;
+    m->cell_buffer = new_buffer_header(interpreter);
+    m->dimension = NULL;
+    Parrot_allocate(interpreter, m->cell_buffer ,  CELL_POOL_SIZE*sizeof(CELL)); 
+    memset( m->cell_buffer->bufstart, 0,  CELL_POOL_SIZE*sizeof(CELL));
+    return m;
+    
+}
+
+
+void init_matrix( Interp *interpreter, PMC *self, KEY *key ) 
+{
+    
+    MATRIX *matrix;
+    INTVAL size = 0;
+    matrix = new_matrix(interpreter);
+    matrix->cell_buffer->flags |= PMC_is_buffer_ptr_FLAG;
+    matrix->cell_buffer->flags |= PMC_is_PMC_ptr_FLAG;
+    
+    self->data = (MATRIX *)matrix;
+    self->cache.int_val = 0;
+    
+    /* only change dimension if we have 2 keys... default is a 4x4 matrix */
+    if( key != NULL && key->next != NULL ) {
+       size = key->atom.val.int_val*key->next->atom.val.int_val;
+/*
+ * Allocate size/2 cells. If we need more then allocate more.
+ * This is done because if we have sparse matrix we dont want to 
+ * allocate more then necesary eg 4x4 matrix uses 16 CELLS
+ * while a sparse 4x4 maybe only uses 8 CELLS or less we dont know.
+ */
+       if((size/2) > matrix->size) {
+           matrix->size = (size/2);
+           matrix->free_cell = (size/2);
+           Parrot_reallocate(interpreter, matrix->cell_buffer, matrix->size * 
+sizeof(CELL));
+           memset(matrix->cell_buffer->bufstart, 0, matrix->size * sizeof(CELL));
+       } 
+       
+       /* store initial dimension */
+       matrix->dimension = key;
+    }
+    
+}
+
+
+
+void set_matrix( Interp *interpreter, MATRIX *sik_matrix, INTVAL row, INTVAL col, 
+MATVAL src_value ) 
+{
+    KEY tmp;
+    KEY tmp2;
+    tmp.next = &tmp2;
+    ROW(tmp) = row;
+    COL(tmp) = col;
+    set_matrix_keyed(interpreter, sik_matrix, &tmp, src_value);
+}
+
+void set_matrix_keyed( Interp *interpreter, MATRIX *sik_matrix, KEY *key, MATVAL 
+src_value ) 
+{
+    
+    CELL *my_cell;
+    CELL *base;
+    
+    /* overwrite current data if cell already exists else create a new one */
+    if(get_matrix_keyed(interpreter, sik_matrix, key) != 0) {
+       
+       base = (CELL *)sik_matrix->cell_buffer->bufstart;
+       my_cell = &base[calc_offset(sik_matrix, *key)];
+       
+    } else {
+       
+       my_cell = new_cell(interpreter, sik_matrix);
+       my_cell->virtual_addr = calc_offset( sik_matrix, *key);
+       
+    }
+    my_cell->data.num_val = src_value;
+}
+
+MATVAL get_matrix( Interp *interpreter, MATRIX *mg_matrix, INTVAL row, INTVAL col ) 
+{
+    
+    KEY tmp;
+    KEY tmp2;
+    tmp.next = &tmp2;
+    ROW(tmp) = row;
+    COL(tmp) = col;
+    
+    return get_matrix_keyed(interpreter, mg_matrix, &tmp);  
+}
+
+
+
+/* Todo: heavy optimisation */
+MATVAL get_matrix_keyed( Interp *interpreter, MATRIX *mg_matrix, KEY *key ) 
+{
+    
+    CELL *buffer_ptr;
+    CELL *buffer_ptr_virt;
+    CELL *base;
+    CELL *virtual_addr;  
+    
+    INTVAL offs = 0;
+    MATVAL ret_val = 0;
+    
+    offs = calc_offset(mg_matrix, *key);
+    base = (CELL *)mg_matrix->cell_buffer->bufstart;
+    buffer_ptr = &base[offs];
+    buffer_ptr_virt = buffer_ptr;
+    
+    if(!(buffer_ptr == NULL)) {
+/* 
+ *  fetch the virtual address from cell. 
+ *  Have to do it this way since base 
+ *  address of our buffer may have and most likely has changed.    
+ */
+       virtual_addr = &base[buffer_ptr->virtual_addr]; 
+       
+       if(virtual_addr == buffer_ptr_virt) {
+           
+           ret_val = buffer_ptr->data.num_val;
+           
+       } else {
+/* 
+ * If we have a sparse matrix we need to search 
+ * for our virtual addr this is slow :-(. 
+ * We're still faster then matlab for medium matrices.
+ * I havent tested this code on huge matrices yet. 
+ * It should be replaced with a polymorphic calc_offset 
+ * function that will be able to "bend" the offset accordingly 
+ * to the sparsity of the matrix.
+ */
+           /* linear search it */
+           while(base <= buffer_ptr) {
+               
+               virtual_addr = &base[buffer_ptr->virtual_addr]; 
+               if(virtual_addr == buffer_ptr_virt) {
+                   
+                   ret_val = buffer_ptr->data.num_val;
+                   break;
+                   
+               }
+               buffer_ptr--;
+               
+           }
+           
+       }
+       
+    }
+    
+    return ret_val;
+}
+
+/*
+ * LU Decomposition, computed by Gaussian elimination.
+ * This constructor computes L and U with the "daxpy"-based elimination
+ * algorithm used in LINPACK, MATLAB and JAMA. 
+ * This code is based on JAMA's LUDecomposition class
+ */
+
+MATRIX *matrix_ludcmp( Interp *interpreter, MATRIX *LU ) 
+{
+    
+    // MATRIX *LU;
+    INTVAL i;
+    INTVAL j;
+    INTVAL k;
+    INTVAL l;
+    INTVAL n = MATCOL(LU);
+    INTVAL m = MATROW(LU);
+    INTVAL piv[m];
+    INTVAL pivsign = 1;
+    INTVAL p;
+    MATVAL t; 
+    
+    /*
+      // make a copy of matrix A.    
+      LU =  new_matrix(interpreter);
+      LU->cell_buffer->flags |= PMC_is_buffer_ptr_FLAG;
+      LU->cell_buffer->flags |= PMC_is_PMC_ptr_FLAG;
+      memcpy(LU->cell_buffer, A->cell_buffer , A->size);  
+      LU->size = A->size;
+      LU->free_cell = A->free_cell;
+      LU->dimension = A->dimension;
+      //     memcpy(LU->dimension, A->dimension, 2);
+      //     MATROW(LU) = MATROW(A);
+      // MATCOL(LU) = MATCOL(A);
+      LU->type = A->type;
+    */
+    
+    for (i=0; i < m; i++) {
+       piv[i] = i;
+    }
+    /* main loop */
+    for (k = 0; k < n; k++) {
+       /* Find pivot. */
+       p = k;
+       for (i = k+1; i < m; i++) {
+           if( (INTVAL)get_matrix(interpreter, LU, i, k) > 
+(INTVAL)get_matrix(interpreter, LU, p, k) ) {
+               //   if( fabs(get_matrix(interpreter, LU, i, k)) > 
+fabs(get_matrix(interpreter, LU, p, k)) ) {
+               p = i;
+           }
+       }
+       /* Exchange if necessary. */
+       if (p != k) {
+           for (j = 0; j < n; j++) {
+               
+               t = get_matrix(interpreter, LU, p, j);
+               set_matrix(interpreter, LU, p, j, get_matrix(interpreter, LU, k, j));
+               set_matrix(interpreter, LU, k, j, t);
+               
+           }
+           t = piv[p]; 
+           piv[p] = piv[k]; 
+           piv[k] = t;
+           pivsign = -pivsign;
+       }
+       /* Compute multipliers and eliminate k-th column. */
+       if((MATVAL)get_matrix(interpreter,LU, k, k) != 0.0) { 
+           for (l = k+1; l < m; l++) {
+               set_matrix( interpreter, LU, l, k, get_matrix(interpreter, LU, l,k) / 
+get_matrix(interpreter, LU, k,k) );
+               for (j = k+1; j < n; j++) {
+                   set_matrix( interpreter,LU,l,j, ( get_matrix(interpreter,LU,l,j) - 
+(get_matrix(interpreter,LU,l,k)*get_matrix(interpreter,LU,k,j)) ));
+               }
+           }
+       }
+    }
+    LU->pivsign = pivsign;
+    return LU;
+}
+
+
+
+MATVAL matrix_det( Interp *interpreter, MATRIX *A )
+{
+    
+    INTVAL i = 0;
+    INTVAL n = 0;
+    MATVAL res = 1;
+    n = MATROW(A);
+    A = matrix_ludcmp( interpreter, A );
+    
+    while (i < n) {
+       
+       res *= get_matrix(interpreter, A, i, i);
+       i++;
+    }
+    
+    res *= (A->pivsign);
+    return res;  
+}
+
+void plot_matrix( Interp *interpreter, MATRIX *A ) 
+{
+    CELL *base;
+    CELL *ptr;
+    INTVAL size;
+    INTVAL stalker;
+    INTVAL x0;
+    
+    base = (CELL *)A->cell_buffer->bufstart;
+    size = stalker = A->size;
+    x0 = MATROW(A); 
+    while(stalker >= 0) {
+       ptr = &base[size-stalker];
+       if(((size-stalker) < MATSIZ(A))) {
+           printf("%f\t", ptr->data.num_val);
+           if(!((size-stalker+1) % x0)) {
+               printf("\n");
+           }
+       }
+       stalker--;
+    }
+    
+}
+
+
+/*
+  static void expand_matrix(){} 
+  This is different from cell_buffer since this function should glue matrices
+  toghether and morphe calc_offset function 
+*/
+
+/* 
+   JOH todo 
+   static void glue_matrix( MATRIX a, MATRIX b ) {}
+*/
+
+
+/* 
+   JOH todo 
+   static void unglue_matrix( MATRIX a, MATRIX b ) {}
+*/

Reply via email to