00001
00009 #include<stdio.h>
00010 #include<stdlib.h>
00011 #include"numbers.h"
00012 #include"matrix.h"
00013
00020 static number addMatrix(const number x,const number y);
00027 static number multMatrix(const number x,const number y);
00032 static number getUnitMatrix(const number x);
00037 static number getZeroMatrix(const number x);
00041 static void displayMatrix(const number x);
00042
00043 enum matrix_mode{ ALLOC, FREE, FREEALL, INFO};
00044
00045 static matrix* manageMatrix(enum matrix_mode mode, int* n, number* p){
00046 static int count=0;
00047 static matrix** all=NULL;
00048 int i,j,t;
00049 number z;
00050 matrix *m;
00051 switch(mode){
00052 case ALLOC:
00053 t=*n;
00054 m=(matrix*)malloc(sizeof(matrix));
00055 m->tab =(value_type*)malloc(t * t *sizeof(value_type));
00056 m->prototype=*p;
00057 m->size=t;
00058 z=getZero(*p);
00059 for(i=0;i<t;i++)
00060 for(j=0;j<t;j++)
00061 m->tab[i+j*t]=z.val;
00062 if(all==NULL)
00063 all=(matrix**)malloc(4*sizeof(matrix*));
00064 else
00065 if(count%4==0)
00066 all=(matrix**)realloc(all,4*(count+1)*sizeof(matrix*));
00067 all[count++]=m;
00068 return m;
00069 case FREE:
00070 if(p->type!=MATRIX) return NULL;
00071 if(p->val.matval==NULL) return NULL;
00072 for(i=0; i<count && all[i]!=p->val.matval; i++);
00073 if(i==count) return NULL;
00074 free(p->val.matval->tab);
00075 free(p->val.matval);
00076 *p=error;
00077 all[i]=all[--count];
00078 return NULL;
00079 case FREEALL:
00080 if(p!=NULL){
00081 if(p->type!=MATRIX) return NULL;
00082 if(p->val.matval==NULL) return NULL;
00083 }
00084 j=count;
00085 count=0;
00086 for(i=0; i<j; i++){
00087 if(all[i]!=p->val.matval){
00088 free(all[i]->tab);
00089 free(all[i]);
00090 }
00091 else{
00092 all[0]=all[i];
00093 count=1;
00094 }
00095 }
00096 return NULL;
00097 case INFO:
00098 *n=count;
00099 return NULL;
00100 }
00101
00102 return NULL;
00103 }
00104
00105 int howManyMatrices(){
00106 int n;
00107 manageMatrix(INFO, &n, NULL);
00108 return n;
00109 }
00110
00111 void freeMatrix(number* p){
00112 manageMatrix(FREE, NULL, p);
00113 }
00114
00115 void freeAllMatricesExcept(number p){
00116 manageMatrix(FREEALL, NULL, &p);
00117 }
00118
00119 void freeAllMatrices(void){
00120 manageMatrix(FREEALL, NULL, NULL);
00121 }
00122
00123
00124
00130 number getMatrix(int n, number p){
00131 number t ={ MATRIX,
00132 {0},
00133 &addMatrix,
00134 &multMatrix,
00135 &getUnitMatrix,
00136 &getZeroMatrix,
00137 &displayMatrix};
00138 t.val.matval=manageMatrix(ALLOC, &n, &p);
00139 return t;
00140 }
00141
00142 number getComponent(number a,int i, int j){
00143 number c;
00144 int n;
00145 if (a.type!=MATRIX)
00146 return error;
00147 n=a.val.matval->size;
00148 if(i<0 || j<0 || i>=n || j>=n)
00149 return error;
00150 c=a.val.matval->prototype;
00151 c.val=a.val.matval->tab[i+n*j];
00152 return c;
00153 }
00154
00155 number setComponent(number a,int i, int j, number x){
00156 int n;
00157 if (a.type!=MATRIX)
00158 return error;
00159 n=a.val.matval->size;
00160 if(i<0 || j<0 || i>=n || j>=n)
00161 return error;
00162 if(x.type!=a.val.matval->prototype.type)
00163 return error;
00164 a.val.matval->tab[i+n*j]=x.val;
00165 return x;
00166 }
00167
00168 static number addMatrix(const number a, const number b){
00169 number c;
00170 int i,j,n;
00171 if (a.type!=MATRIX || b.type!=MATRIX)
00172 return error;
00173 if (a.val.matval->prototype.type!=b.val.matval->prototype.type ||
00174 a.val.matval->size!=b.val.matval->size)
00175 return error;
00176 n=a.val.matval->size;
00177 c=getMatrix(n, a.val.matval->prototype);
00178 for(i=0; i<n; i++)
00179 for(j=0; j<n; j++)
00180 setComponent(c,i,j, add(getComponent(a,i,j),getComponent(b,i,j)));
00181 return c;
00182 }
00183
00184 static number multMatrix(const number a, const number b){
00185 number c;
00186 int i,j,k,n;
00187 if (a.type!=MATRIX || b.type!=MATRIX)
00188 return error;
00189 if (a.val.matval->prototype.type!=b.val.matval->prototype.type ||
00190 a.val.matval->size!=b.val.matval->size)
00191 return error;
00192 n=a.val.matval->size;
00193 c=getMatrix(n, a.val.matval->prototype);
00194 for(i=0; i<n; i++)
00195 for(j=0; j<n; j++){
00196 number t=getZero(a.val.matval->prototype);
00197 for(k=0; k<n; k++)
00198 t=add(t, mult(getComponent(a,i,k),getComponent(b,k,j)));
00199 setComponent(c,i,j,t);
00200 }
00201 return c;
00202 }
00203
00204 static number getUnitMatrix(const number a){
00205 number c;
00206 int i,n;
00207 if (a.type!=MATRIX)
00208 return error;
00209 n=a.val.matval->size;
00210 c=getMatrix(n, a.val.matval->prototype);
00211 number un=getUnit(a.val.matval->prototype);
00212 display(un);
00213 for(i=0; i<n; i++)
00214 setComponent(c,i,i,un);
00215 return c;
00216 }
00217
00218 static number getZeroMatrix(const number a){
00219 number c;
00220 int n;
00221 if (a.type!=MATRIX)
00222 return error;
00223 n=a.val.matval->size;
00224 c=getMatrix(n, a.val.matval->prototype);
00225 return c;
00226 }
00227
00228 void displayMatrix(const number x){
00229 int i,j,n;
00230 if (x.type!=MATRIX)
00231 return;
00232 n=x.val.matval->size;
00233 for(i=0;i<n;i++){
00234 printf("[ ");
00235 for(j=0;j<n;j++){
00236 display(getComponent(x,i,j));
00237 putchar(' ');
00238 }
00239 printf("]\n");
00240 }
00241 }
00242