#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) |
| RealNumber * | spGetElement (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) |
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] |
| 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] |
1.5.1