Main Page | Data Structures | File List | Data Fields | Globals

matrix.c

Go to the documentation of this file.
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   /* Inutile ! */
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 

Generated on Thu Dec 18 16:01:23 2008 for Numbers by  doxygen 1.3.9.1