spBuild.c File Reference

#include "spConfig.h"
#include "spmatrix.h"
#include "spDefs.h"
#include "spmalloc.h"

Include dependency graph for spBuild.c:

Go to the source code of this file.

Defines

#define spINSIDE_SPARSE

Functions

static void Translate ()
static EnlargeMatrix ()
static ExpandTranslationArrays ()
void spClear (char *eMatrix)
RealNumberspGetElement (char *eMatrix, int Row, int Col)
ElementPtr spcFindElementInCol (MatrixPtr Matrix, ElementPtr *LastAddr, int Row, int Col, SPBOOLEAN CreateIfMissing)
ElementPtr spcCreateElement (MatrixPtr Matrix, int Row, int Col, ElementPtr *LastAddr, SPBOOLEAN Fillin)
 spcLinkRows (MatrixPtr Matrix)
static EnlargeMatrix (MatrixPtr Matrix, int NewSize)


Define Documentation

#define spINSIDE_SPARSE

Definition at line 62 of file spBuild.c.


Function Documentation

static EnlargeMatrix ( MatrixPtr  Matrix,
int  NewSize 
) [static]

Definition at line 910 of file spBuild.c.

References I, int, MAX, NO, NULL, SPFREE, spNO_MEMORY, and SPREALLOC.

00914 {
00915 register int I, OldAllocatedSize = Matrix->AllocatedSize;
00916 
00917 /* Begin `EnlargeMatrix'. */
00918     Matrix->Size = NewSize;
00919 
00920     if (NewSize <= OldAllocatedSize)
00921         return 0;
00922 
00923 /* Expand the matrix frame. */
00924     NewSize = (int) MAX( NewSize, EXPANSION_FACTOR * OldAllocatedSize );
00925     Matrix->AllocatedSize = NewSize;
00926 
00927     if (( SPREALLOC(Matrix->IntToExtColMap, int, NewSize+1)) == NULL)
00928     {   Matrix->Error = spNO_MEMORY;
00929         return 0;
00930     }
00931     if (( SPREALLOC(Matrix->IntToExtRowMap, int, NewSize+1)) == NULL)
00932     {   Matrix->Error = spNO_MEMORY;
00933         return 0;
00934     }
00935     if (( SPREALLOC(Matrix->Diag, ElementPtr, NewSize+1)) == NULL)
00936     {   Matrix->Error = spNO_MEMORY;
00937         return 0;
00938     }
00939     if (( SPREALLOC(Matrix->FirstInCol, ElementPtr, NewSize+1)) == NULL)
00940     {   Matrix->Error = spNO_MEMORY;
00941         return 0;
00942     }
00943     if (( SPREALLOC(Matrix->FirstInRow, ElementPtr, NewSize+1)) == NULL)
00944     {   Matrix->Error = spNO_MEMORY;
00945         return 0;
00946     }
00947 
00948 /*
00949  * Destroy the Markowitz and Intermediate vectors, they will be recreated
00950  * in spOrderAndFactor().
00951  */
00952     SPFREE( Matrix->MarkowitzRow );
00953     SPFREE( Matrix->MarkowitzCol );
00954     SPFREE( Matrix->MarkowitzProd );
00955     SPFREE( Matrix->DoRealDirect );
00956     SPFREE( Matrix->DoCmplxDirect );
00957     SPFREE( Matrix->Intermediate );
00958     Matrix->InternalVectorsAllocated = NO;
00959 
00960 /* Initialize the new portion of the vectors. */
00961     for (I = OldAllocatedSize+1; I <= NewSize; I++)
00962     {   Matrix->IntToExtColMap[I] = I;
00963         Matrix->IntToExtRowMap[I] = I;
00964         Matrix->Diag[I] = NULL;
00965         Matrix->FirstInRow[I] = NULL;
00966         Matrix->FirstInCol[I] = NULL;
00967     }
00968 
00969     return 0;
00970 }

static EnlargeMatrix (  )  [static]

Referenced by spGetElement().

Here is the caller graph for this function:

static ExpandTranslationArrays (  )  [static]

ElementPtr spcCreateElement ( MatrixPtr  Matrix,
int  Row,
int  Col,
ElementPtr LastAddr,
SPBOOLEAN  Fillin 
)

Definition at line 713 of file spBuild.c.

References MatrixElement::Col, MatrixElement::NextInCol, MatrixElement::NextInRow, NULL, MatrixElement::Real, MatrixElement::Row, spcGetElement(), spcGetFillin(), and YES.

Referenced by CreateFillin(), and spcFindElementInCol().

00720 {
00721 register  ElementPtr  pElement, pLastElement;
00722 ElementPtr  pCreatedElement, spcGetElement(), spcGetFillin();
00723 
00724 /* Begin `spcCreateElement'. */
00725 
00726     if (Matrix->RowsLinked)
00727     {
00728 /* Row pointers cannot be ignored. */
00729         if (Fillin)
00730         {   pElement = spcGetFillin( Matrix );
00731             Matrix->Fillins++;
00732         }
00733         else
00734         {   pElement = spcGetElement( Matrix );
00735             Matrix->NeedsOrdering = YES;
00736         }
00737         if (pElement == NULL) return NULL;
00738 
00739 /* If element is on diagonal, store pointer in Diag. */
00740         if (Row == Col) Matrix->Diag[Row] = pElement;
00741 
00742 /* Initialize Element. */
00743         pCreatedElement = pElement;
00744         pElement->Row = Row;
00745         pElement->Col = Col;
00746         pElement->Real = 0.0;
00747 #if spCOMPLEX
00748         pElement->Imag = 0.0;
00749 #endif
00750 #if INITIALIZE
00751         pElement->pInitInfo = NULL;
00752 #endif
00753 
00754 /* Splice element into column. */
00755         pElement->NextInCol = *LastAddr;
00756         *LastAddr = pElement;
00757 
00758  /* Search row for proper element position. */
00759         pElement = Matrix->FirstInRow[Row];
00760         pLastElement = NULL;
00761         while (pElement != NULL)
00762         {
00763 /* Search for element row position. */
00764             if (pElement->Col < Col)
00765             {
00766 /* Have not reached desired element. */
00767                 pLastElement = pElement;
00768                 pElement = pElement->NextInRow;
00769             }
00770             else pElement = NULL;
00771         }
00772 
00773 /* Splice element into row. */
00774         pElement = pCreatedElement;
00775         if (pLastElement == NULL)
00776         {
00777 /* Element is first in row. */
00778             pElement->NextInRow = Matrix->FirstInRow[Row];
00779             Matrix->FirstInRow[Row] = pElement;
00780         }
00781         else
00782 /* Element is not first in row. */
00783         {
00784             pElement->NextInRow = pLastElement->NextInRow;
00785             pLastElement->NextInRow = pElement;
00786         }
00787 
00788     }
00789     else
00790     {
00791 /*
00792  * Matrix has not been factored yet.  Thus get element rather than fill-in.
00793  * Also, row pointers can be ignored.
00794  */
00795 
00796 /* Allocate memory for Element. */
00797         pElement = spcGetElement( Matrix );
00798         if (pElement == NULL) return NULL;
00799 
00800 /* If element is on diagonal, store pointer in Diag. */
00801         if (Row == Col) Matrix->Diag[Row] = pElement;
00802 
00803 /* Initialize Element. */
00804         pCreatedElement = pElement;
00805         pElement->Row = Row;
00806 #if DEBUG
00807         pElement->Col = Col;
00808 #endif
00809         pElement->Real = 0.0;
00810 #if spCOMPLEX
00811         pElement->Imag = 0.0;
00812 #endif
00813 #if INITIALIZE
00814         pElement->pInitInfo = NULL;
00815 #endif
00816 
00817 /* Splice element into column. */
00818         pElement->NextInCol = *LastAddr;
00819         *LastAddr = pElement;
00820     }
00821 
00822     Matrix->Elements++;
00823     return pCreatedElement;
00824 }

Here is the call graph for this function:

Here is the caller graph for this function:

ElementPtr spcFindElementInCol ( MatrixPtr  Matrix,
ElementPtr LastAddr,
int  Row,
int  Col,
SPBOOLEAN  CreateIfMissing 
)

Definition at line 290 of file spBuild.c.

References MatrixElement::NextInCol, NO, NULL, MatrixElement::Row, and spcCreateElement().

Referenced by ExchangeRowsAndCols(), and spGetElement().

00297 {
00298 register  ElementPtr  pElement;
00299 ElementPtr  spcCreateElement();
00300 
00301 /* Begin `spcFindElementInCol'. */
00302     pElement = *LastAddr;
00303 
00304 /* Search for element. */
00305     while (pElement != NULL)
00306     {   if (pElement->Row < Row)
00307         {
00308 /* Have not reached element yet. */
00309             LastAddr = &(pElement->NextInCol);
00310             pElement = pElement->NextInCol;
00311         }
00312         else if (pElement->Row == Row)
00313         {
00314 /* Reached element. */
00315             return pElement;
00316         }
00317         else break;  /* while loop */
00318     }
00319 
00320 /* Element does not exist and must be created. */
00321     if (CreateIfMissing)
00322        return spcCreateElement( Matrix, Row, Col, LastAddr, NO );
00323     else return NULL;
00324 }

Here is the call graph for this function:

Here is the caller graph for this function:

void spClear ( char *  eMatrix  ) 

Definition at line 90 of file spBuild.c.

References ASSERT, I, IS_SPARSE, MatrixElement::NextInCol, NO, NULL, OR, MatrixElement::Real, and spOKAY.

00093 {
00094 MatrixPtr  Matrix = (MatrixPtr)eMatrix;
00095 register  ElementPtr  pElement;
00096 register  int  I;
00097 
00098 /* Begin `spClear'. */
00099     ASSERT( IS_SPARSE( Matrix ) );
00100 
00101 /* Clear matrix. */
00102 #if spCOMPLEX
00103     if (Matrix->PreviousMatrixWasComplex OR Matrix->Complex)
00104     {   for (I = Matrix->Size; I > 0; I--)
00105         {   pElement = Matrix->FirstInCol[I];
00106             while (pElement != NULL)
00107             {   pElement->Real = 0.0;
00108                 pElement->Imag = 0.0;
00109                 pElement = pElement->NextInCol;
00110             }
00111         }
00112     }
00113     else
00114 #endif
00115     {   for (I = Matrix->Size; I > 0; I--)
00116         {   pElement = Matrix->FirstInCol[I];
00117             while (pElement != NULL)
00118             {   pElement->Real = 0.0;
00119                 pElement = pElement->NextInCol;
00120             }
00121         }
00122     }
00123 
00124 /* Empty the trash. */
00125     Matrix->TrashCan.Real = 0.0;
00126 #if spCOMPLEX
00127     Matrix->TrashCan.Imag = 0.0;
00128 #endif
00129 
00130     Matrix->Error = spOKAY;
00131     Matrix->Factored = NO;
00132     Matrix->SingularCol = 0;
00133     Matrix->SingularRow = 0;
00134     Matrix->PreviousMatrixWasComplex = Matrix->Complex;
00135     return;
00136 }

spcLinkRows ( MatrixPtr  Matrix  ) 

Definition at line 859 of file spBuild.c.

References MatrixElement::Col, MatrixElement::NextInCol, MatrixElement::NextInRow, NULL, MatrixElement::Row, and YES.

Referenced by spOrderAndFactor().

00862 {
00863 register  ElementPtr  pElement, *FirstInRowEntry;
00864 register  ArrayOfElementPtrs  FirstInRowArray;
00865 register  int  Col;
00866 
00867 /* Begin `spcLinkRows'. */
00868     FirstInRowArray = Matrix->FirstInRow;
00869     for (Col = Matrix->Size; Col >= 1; Col--)
00870     {
00871 /* Generate row links for the elements in the Col'th column. */
00872         pElement = Matrix->FirstInCol[Col];
00873 
00874         while (pElement != NULL)
00875         {   pElement->Col = Col;
00876             FirstInRowEntry = &FirstInRowArray[pElement->Row];
00877             pElement->NextInRow = *FirstInRowEntry;
00878             *FirstInRowEntry = pElement;
00879             pElement = pElement->NextInCol;
00880         }
00881     }
00882     Matrix->RowsLinked = YES;
00883     return 0;
00884 }

Here is the caller graph for this function:

RealNumber* spGetElement ( char *  eMatrix,
int  Row,
int  Col 
)

Definition at line 184 of file spBuild.c.

References AND, ASSERT, EnlargeMatrix(), IS_SPARSE, MAX, NULL, OR, spcFindElementInCol(), spNO_MEMORY, Translate(), and YES.

00188 {
00189 MatrixPtr  Matrix = (MatrixPtr)eMatrix;
00190 RealNumber  *pElement;
00191 ElementPtr spcFindElementInCol();
00192 
00193 
00194 /* Begin `spGetElement'. */
00195     ASSERT( IS_SPARSE( Matrix ) AND Row >= 0 AND Col >= 0 );
00196 
00197     if ((Row == 0) OR (Col == 0))
00198         return &Matrix->TrashCan.Real;
00199 
00200 #if NOT TRANSLATE
00201     ASSERT(Matrix->NeedsOrdering);
00202 #endif
00203 
00204 #if TRANSLATE
00205     Translate( Matrix, &Row, &Col );
00206     if (Matrix->Error == spNO_MEMORY) return NULL;
00207 #endif
00208 
00209 #if NOT TRANSLATE
00210 #if NOT EXPANDABLE
00211     ASSERT(Row <= Matrix->Size AND Col <= Matrix->Size);
00212 #endif
00213 
00214 #if EXPANDABLE
00215 /* Re-size Matrix if necessary. */
00216     if ((Row > Matrix->Size) OR (Col > Matrix->Size))
00217         EnlargeMatrix( Matrix, MAX(Row, Col) );
00218     if (Matrix->Error == spNO_MEMORY) return NULL;
00219 #endif
00220 #endif
00221 
00222 /*
00223  * The condition part of the following if statement tests to see if the
00224  * element resides along the diagonal, if it does then it tests to see
00225  * if the element has been created yet (Diag pointer not NULL).  The
00226  * pointer to the element is then assigned to Element after it is cast
00227  * into a pointer to a RealNumber.  This casting makes the pointer into
00228  * a pointer to Real.  This statement depends on the fact that Real
00229  * is the first record in the MatrixElement structure.
00230  */
00231 
00232     if ((Row != Col) OR ((pElement = (RealNumber *)Matrix->Diag[Row]) == NULL))
00233     {
00234 /*
00235  * Element does not exist or does not reside along diagonal.  Search
00236  * column for element.  As in the if statement above, the pointer to the
00237  * element which is returned by spcFindElementInCol is cast into a
00238  * pointer to Real, a RealNumber.
00239  */
00240         pElement = (RealNumber*)spcFindElementInCol( Matrix,
00241                                                      &(Matrix->FirstInCol[Col]),
00242                                                      Row, Col, YES );
00243     }
00244     return pElement;
00245 }

Here is the call graph for this function:

static void Translate (  )  [static]

Referenced by spGetElement().

Here is the caller graph for this function:


Generated on Sun Mar 4 16:12:58 2007 for Scilab [trunk] by  doxygen 1.5.1