lu.c

Go to the documentation of this file.
00001 
00002 /* README : 
00003  * The routines in this file use a pointer to a Matrix 
00004  * at the Fortran Level this pointer is stored as an integer 
00005  * so we cast  pointer to long int 
00006  * f_(fmat) 
00007  *  long *fmat 
00008  *  *fmat = (long)spCreate(*n,0,&error);
00009  * 
00010  * At fortran level the integer must be an integer *4 
00011  * in order to store a C long 
00012  * since we  are in scilab 
00013  * the pointer transmitted to f_ is an istk(il1) it can in fact contain 
00014  * something as long as a double 
00015  * Copyright ENPC (Chancelier)
00016  */
00017 
00018 
00019 /*
00020  *  IMPORTS
00021  *
00022  *  >>> Import descriptions:
00023  *  spConfig.h
00024  *     Macros that customize the sparse matrix routines.
00025  *  spmatrix.h
00026  *     Macros and declarations to be imported by the user.
00027  *  spDefs.h
00028  *     Matrix type and macro definitions for the sparse matrix routines.
00029  */
00030 
00031 #define spINSIDE_SPARSE
00032 #include "spConfig.h"
00033 #include "spmatrix.h"
00034 #include "spDefs.h"
00035 
00036 
00037 #include "machine.h"
00038 
00039 /*
00040  *
00041  * lufact1  >>> Creation and LU factorisation of a sparse matrix 
00042  * Entry << 
00043  *   val,rc 
00044  *       arrays of size k and kx2 a(rc(i),rc(*k+i))=val(i)
00045  *       for i=0,(*k-1)
00046  *   *n : size of the created square matrix 
00047  *   *k : number of given values 
00048  *   *eps : The machine precision number 
00049  *  Return >> 
00050  *   fmat : pointer to a long int which is a cast of an adress
00051  *   *nrank : The numerical rank 
00052  */
00053 
00054 
00055 static void 
00056 spFixThresold(eMatrix,eps,releps)
00057 char *eMatrix;
00058 double eps,releps;
00059 {
00060   MatrixPtr  Matrix = (MatrixPtr)eMatrix;
00061   Matrix->AbsThreshold = eps;
00062   Matrix->RelThreshold = releps;
00063 }
00064 
00065 
00066 static void 
00067 spGetNumRank(eMatrix,n)
00068 char *eMatrix;
00069 int *n;
00070 {
00071   MatrixPtr  Matrix = (MatrixPtr)eMatrix;
00072   *n = Matrix->NumRank;
00073 }
00074 
00075 extern void cerro();
00076 
00077 void 
00078 C2F(lufact1)(val,lln,col,n,nel,fmat,eps,releps,nrank,ierr)
00079 double *val,*eps,*releps;
00080 long *fmat;
00081 int *n,*nel,*nrank,*lln,*col,*ierr;
00082 {
00083   int error,i,i0,i1,k,j;
00084   spREAL *pelement;
00085   *ierr = 0;
00086   *fmat = (long)spCreate(*n,0,&error);
00087     if (error != spOKAY) {
00088         *ierr = 1;
00089         return;
00090     }
00091 
00092 
00093   i0=0;
00094   i1=i0;
00095   i=1;
00096   for (k = 0 ;k < *nel; k++) {
00097       i0=i0+1;
00098       while (i0-i1 > lln[i-1]) {
00099           i1=i0;
00100           i=i+1;
00101           i0=i0+1;
00102       }
00103       j=col[k];
00104       pelement = spGetElement((char*) *fmat,i,j);
00105       if (pelement == 0) {
00106           *ierr=2;
00107           return;
00108       }
00109       spADD_REAL_ELEMENT(pelement,(spREAL)(val[k]));
00110 
00111   }
00112   /* Fix the AbsThresold with scilex %eps */
00113   spFixThresold((char*) *fmat,*eps,*releps);
00114   /* spPrint((char *) *fmat,1,1,1); */
00115   error = spFactor((char*) *fmat);
00116   spGetNumRank((char *) *fmat,nrank);
00117   switch (error) {
00118   case spZERO_DIAG:
00119     cerro("zero_diag: A zero was encountered on the diagonal the matrix ");
00120     break;
00121   case spNO_MEMORY:
00122     *ierr=3;
00123     break;
00124   case spSINGULAR:
00125     *ierr=-1; /*Singular matrix" */
00126     break;
00127   case spSMALL_PIVOT:
00128     *ierr=-2; /* matrix is singular at precision level */
00129     break;
00130   }
00131 }
00132 
00133 /*
00134  * lusolve1  >>> Solves fmat*x=b 
00135  *   *fmat : a pointer to the sparse matrix factored by lufact 
00136  *   b,v 
00137  *      two arrays of size n the matrix size 
00138  */
00139 extern void Cout(char *str);
00140 
00141 void C2F(lusolve1)(fmat,b,x)
00142 double *b, *x;
00143 long *fmat;
00144 {
00145     spSolve((char*) *fmat,(spREAL*)b,(spREAL*)x);
00146 }
00147 
00148 /*
00149  * ludel1  >>> delete sparse matrix 
00150  *   *fmat : a pointer to the sparse matrix factored by lufact 
00151  */
00152 
00153 void C2F(ludel1)(fmat)
00154 long *fmat;
00155 {
00156   spDestroy((char*) *fmat);
00157 }
00158 
00159 /*
00160  * lusize  >>> returns in n the size of the sparse matrix 
00161  *   *fmat : a pointer to the sparse matrix factored by lufact 
00162  */
00163 
00164 static void 
00165 spSize(eMatrix,n)
00166 char *eMatrix;
00167 int *n;
00168 {
00169   MatrixPtr  Matrix = (MatrixPtr)eMatrix;
00170   *n=Matrix->Size;
00171 }
00172 
00173 void C2F(lusize)(fmat,n)
00174 long *fmat;
00175 int *n;
00176 {
00177   spSize((char *) *fmat,n);
00178 }
00179 
00180 /*
00181  * luget1   >>> extract the LU coded matrix into a full array 
00182  *   sigg,sigd :
00183  *     two arrays of size n which code permutations 
00184  *   lu :  
00185  *     an array coded matrix of size nxn where lu will be stored 
00186  */
00187 
00188 
00189 /* filling right permutation */
00190 void GetSigD(MatrixPtr Matrix,int indsigd[],double sigd[])
00191 {
00192   int I,J,mc=0,last=0;
00193   int Size=Matrix->Size;
00194 for (I = 1; I <= Size; I++)
00195   {
00196     indsigd[I-1]=1;
00197     indsigd[Size+I-1]=  Matrix->IntToExtColMap[I];
00198     sigd[I-1]=1.0;
00199   }
00200 /* counting missing colums */
00201 for (I = 1; I <= Size; I++) 
00202   if (Matrix->ExtToIntColMap[I]== -1) mc++;
00203 /* filling missing colums */
00204 if (mc != 0)
00205   {
00206     for (I = Size -(mc)+1  ; I <= Size; I++)
00207       {
00208         for ( J=last+1; J <=Size; J++)
00209           {
00210             if (Matrix->ExtToIntColMap[J]==-1) 
00211               { 
00212                 last=J;break;
00213               }
00214           }
00215         indsigd[I-1]=1;
00216         indsigd[Size+I-1]= last;
00217       }
00218   }
00219 }
00220 
00221 
00222 /* filling left permutation */
00223 
00224 void GetSigG(MatrixPtr Matrix,int indsigg[],double sigg[])
00225 {
00226   int Size=Matrix->Size;
00227   int I,J,mc=0,last=0;
00228   /* counting missing Rows*/
00229   for (I = 1; I <= Size; I++) 
00230     if (Matrix->ExtToIntRowMap[I]== -1) mc++;
00231 
00232   for (I = 1; I <= Size-mc ; I++)
00233   {
00234         indsigg[I-1]= 1;
00235         indsigg[Size+Matrix->IntToExtRowMap[I]-1]=I;
00236         sigg[I-1]=1;
00237   }
00238 /* filling missing Rows */
00239 if (mc != 0)
00240   {
00241     for (I = Size -(mc)+1  ; I <= Size; I++)
00242       {
00243         for ( J=last+1; J <=Size; J++)
00244           {
00245             if (Matrix->ExtToIntRowMap[J]==-1) 
00246               { 
00247 
00248                 last=J;break;
00249               }
00250           }
00251         indsigg[I-1]= 1;
00252         indsigg[Size+last-1]=I;
00253         sigg[I-1]=1;
00254       }
00255   }
00256 }
00257 
00258 
00259 static void 
00260 spLuget(eMatrix,indP,P,indl,l,indu,u,indQ,Q)
00261 char *eMatrix;
00262 int *indP,*indl,*indu,*indQ;
00263 double *P,*Q,*l,*u;
00264 {
00265 int I,J;
00266 int lsize,usize;
00267 
00268 MatrixPtr Matrix = (MatrixPtr) eMatrix;
00269 ElementPtr  pElement;
00270 int Size;
00271 Size = Matrix->Size;
00272 GetSigD(Matrix,indQ,Q);
00273 GetSigG(Matrix,indP,P);
00274 for (J = 1; J <= Size ; J++)
00275   {
00276     indl[J-1] = 0;
00277     indu[J-1] = 0;
00278 }
00279 lsize=0;
00280 usize=0;
00281 for (I = 1; I <= Size ; I++)
00282   {
00283     indu[I-1]=indu[I-1]+1;
00284     indu[Size+usize]=I;
00285     u[usize]=1.0;
00286     usize=usize+1;
00287 
00288     pElement = Matrix->FirstInRow[I];
00289     while ( pElement != NULL )
00290       {
00291           J = pElement->Col;
00292           if (I >= J) {
00293               indl[I-1] = indl[I-1]+1;
00294               indl[Size+lsize]=J;
00295               l[lsize]=(double) pElement->Real ;
00296               lsize=lsize+1;
00297 
00298           }
00299           else {
00300               indu[I-1] = indu[I-1]+1;
00301               indu[Size+usize]=J;
00302               u[usize]=(double) pElement->Real ;
00303               usize=usize+1;
00304 
00305           }
00306         pElement = pElement->NextInRow;
00307       };
00308   };
00309 }
00310 
00311 
00312 
00313 
00314 
00315 void C2F(luget1)(fmat,indP,P,indl,l,indu,u,indQ,Q)
00316 long *fmat;
00317 double *P,*Q,*l,*u;
00318 int *indP,*indl,*indu,*indQ;
00319 {
00320   spLuget((char *) *fmat,indP,P,indl,l,indu,u,indQ,Q);
00321 }
00322 
00323 
00324 /*
00325  * lusiz1   >>> extract the L and U  number of non zero elements
00326  * lsize and usize
00327  */
00328 
00329 
00330 static void 
00331 spLusiz(eMatrix,lsize,usize)
00332 char *eMatrix;
00333 int *lsize,*usize;
00334 {
00335 int J;
00336 MatrixPtr Matrix = (MatrixPtr) eMatrix;
00337 ElementPtr  pElement;
00338 int Size;
00339 Size = Matrix->Size;
00340 *lsize=0;
00341 *usize=Size;
00342 for (J = 1; J <= Size ; J++)
00343   {
00344     pElement = Matrix->FirstInCol[J];
00345     while ( pElement != NULL )
00346       {
00347         if (pElement->Row >= J) 
00348             *lsize=*lsize+1;
00349         else
00350             *usize=*usize+1;
00351         pElement = pElement->NextInCol;
00352     };
00353   };
00354 }  
00355 void C2F(lusiz1)(fmat,lsize,usize)
00356 long *fmat;
00357 int *lsize,*usize;
00358 {
00359   spLusiz((char *) *fmat,lsize,usize);
00360 }

Generated on Sun Mar 4 15:04:00 2007 for Scilab [trunk] by  doxygen 1.5.1