# 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 ) {} +*/