📄 spbuild.c
字号:
pCreatedElement = pElement; pElement->Row = Row; pElement->Col = Col; pElement->Real = 0.0;#if spCOMPLEX pElement->Imag = 0.0;#endif#if INITIALIZE pElement->pInitInfo = NULL;#endif/* Splice element into column. */ pElement->NextInCol = *LastAddr; *LastAddr = pElement; /* Search row for proper element position. */ pElement = Matrix->FirstInRow[Row]; pLastElement = NULL; while (pElement != NULL) {/* Search for element row position. */ if (pElement->Col < Col) {/* Have not reached desired element. */ pLastElement = pElement; pElement = pElement->NextInRow; } else pElement = NULL; }/* Splice element into row. */ pElement = pCreatedElement; if (pLastElement == NULL) {/* Element is first in row. */ pElement->NextInRow = Matrix->FirstInRow[Row]; Matrix->FirstInRow[Row] = pElement; } else/* Element is not first in row. */ { pElement->NextInRow = pLastElement->NextInRow; pLastElement->NextInRow = pElement; } } else {/* * Matrix has not been factored yet. Thus get element rather than fill-in. * Also, row pointers can be ignored. *//* Allocate memory for Element. */ pElement = spcGetElement( Matrix ); Matrix->Originals++; if (pElement == NULL) return NULL;/* If element is on diagonal, store pointer in Diag. */ if (Row == Col) Matrix->Diag[Row] = pElement;/* Initialize Element. */ pCreatedElement = pElement; pElement->Row = Row;#if DEBUG pElement->Col = Col;#endif pElement->Real = 0.0;#if spCOMPLEX pElement->Imag = 0.0;#endif#if INITIALIZE pElement->pInitInfo = NULL;#endif/* Splice element into column. */ pElement->NextInCol = *LastAddr; *LastAddr = pElement; } Matrix->Elements++; return pCreatedElement;}/* * * LINK ROWS * * This routine is used to generate the row links. The spGetElement() * routines do not create row links, which are needed by the spFactor() * routines. * * >>> Arguments: * Matrix <input> (MatrixPtr) * Pointer to the matrix. * * >>> Local variables: * pElement (ElementPtr) * Pointer to an element in the matrix. * FirstInRowEntry (ElementPtr *) * A pointer into the FirstInRow array. Points to the FirstInRow entry * currently being operated upon. * FirstInRowArray (ArrayOfElementPtrs) * A pointer to the FirstInRow array. Same as Matrix->FirstInRow but * resides in a register and requires less indirection so is faster to * use. * Col (int) * Column currently being operated upon. */voidspcLinkRows( Matrix )MatrixPtr Matrix;{register ElementPtr pElement, *FirstInRowEntry;register ArrayOfElementPtrs FirstInRowArray;register int Col;/* Begin `spcLinkRows'. */ FirstInRowArray = Matrix->FirstInRow; for (Col = Matrix->Size; Col >= 1; Col--) {/* Generate row links for the elements in the Col'th column. */ pElement = Matrix->FirstInCol[Col]; while (pElement != NULL) { pElement->Col = Col; FirstInRowEntry = &FirstInRowArray[pElement->Row]; pElement->NextInRow = *FirstInRowEntry; *FirstInRowEntry = pElement; pElement = pElement->NextInCol; } } Matrix->RowsLinked = YES; return;}/* * ENLARGE MATRIX * * Increases the size of the matrix. * * >>> Arguments: * Matrix <input> (MatrixPtr) * Pointer to the matrix. * NewSize <input> (int) * The new size of the matrix. * * >>> Local variables: * OldAllocatedSize (int) * The allocated size of the matrix before it is expanded. */static voidEnlargeMatrix( Matrix, NewSize )MatrixPtr Matrix;register int NewSize;{register int I, OldAllocatedSize = Matrix->AllocatedSize;/* Begin `EnlargeMatrix'. */ Matrix->Size = NewSize; if (NewSize <= OldAllocatedSize) return;/* Expand the matrix frame. */ NewSize = MAX( NewSize, EXPANSION_FACTOR * OldAllocatedSize ); Matrix->AllocatedSize = NewSize; if (( REALLOC(Matrix->IntToExtColMap, int, NewSize+1)) == NULL) { Matrix->Error = spNO_MEMORY; return; } if (( REALLOC(Matrix->IntToExtRowMap, int, NewSize+1)) == NULL) { Matrix->Error = spNO_MEMORY; return; } if (( REALLOC(Matrix->Diag, ElementPtr, NewSize+1)) == NULL) { Matrix->Error = spNO_MEMORY; return; } if (( REALLOC(Matrix->FirstInCol, ElementPtr, NewSize+1)) == NULL) { Matrix->Error = spNO_MEMORY; return; } if (( REALLOC(Matrix->FirstInRow, ElementPtr, NewSize+1)) == NULL) { Matrix->Error = spNO_MEMORY; return; }/* * Destroy the Markowitz and Intermediate vectors, they will be recreated * in spOrderAndFactor(). */ FREE( Matrix->MarkowitzRow ); FREE( Matrix->MarkowitzCol ); FREE( Matrix->MarkowitzProd ); FREE( Matrix->DoRealDirect ); FREE( Matrix->DoCmplxDirect ); FREE( Matrix->Intermediate ); Matrix->InternalVectorsAllocated = NO;/* Initialize the new portion of the vectors. */ for (I = OldAllocatedSize+1; I <= NewSize; I++) { Matrix->IntToExtColMap[I] = I; Matrix->IntToExtRowMap[I] = I; Matrix->Diag[I] = NULL; Matrix->FirstInRow[I] = NULL; Matrix->FirstInCol[I] = NULL; } return;}#if TRANSLATE/* * EXPAND TRANSLATION ARRAYS * * Increases the size arrays that are used to translate external to internal * row and column numbers. * * >>> Arguments: * Matrix <input> (MatrixPtr) * Pointer to the matrix. * NewSize <input> (int) * The new size of the translation arrays. * * >>> Local variables: * OldAllocatedSize (int) * The allocated size of the translation arrays before being expanded. */static voidExpandTranslationArrays( Matrix, NewSize )MatrixPtr Matrix;register int NewSize;{register int I, OldAllocatedSize = Matrix->AllocatedExtSize;/* Begin `ExpandTranslationArrays'. */ Matrix->ExtSize = NewSize; if (NewSize <= OldAllocatedSize) return;/* Expand the translation arrays ExtToIntRowMap and ExtToIntColMap. */ NewSize = MAX( NewSize, EXPANSION_FACTOR * OldAllocatedSize ); Matrix->AllocatedExtSize = NewSize; if (( REALLOC(Matrix->ExtToIntRowMap, int, NewSize+1)) == NULL) { Matrix->Error = spNO_MEMORY; return; } if (( REALLOC(Matrix->ExtToIntColMap, int, NewSize+1)) == NULL) { Matrix->Error = spNO_MEMORY; return; }/* Initialize the new portion of the vectors. */ for (I = OldAllocatedSize+1; I <= NewSize; I++) { Matrix->ExtToIntRowMap[I] = -1; Matrix->ExtToIntColMap[I] = -1; } return;}#endif#if INITIALIZE/* * INITIALIZE MATRIX * * With the INITIALIZE compiler option (see spConfig.h) set true, * Sparse allows the user to keep initialization information with each * structurally nonzero matrix element. Each element has a pointer * that is set and used by the user. The user can set this pointer * using spInstallInitInfo and may be read using spGetInitInfo. Both * may be used only after the element exists. The function * spInitialize() is a user customizable way to initialize the matrix. * Passed to this routine is a function pointer. spInitialize() sweeps * through every element in the matrix and checks the pInitInfo * pointer (the user supplied pointer). If the pInitInfo is NULL, * which is true unless the user changes it (almost always true for * fill-ins), then the element is zeroed. Otherwise, the function * pointer is called and passed the pInitInfo pointer as well as the * element pointer and the external row and column numbers. If the * user sets the value of each element, then spInitialize() replaces * spClear(). * * The user function is expected to return a nonzero integer if there * is a fatal error and zero otherwise. Upon encountering a nonzero * return code, spInitialize() terminates and returns the error code. * * >>> Arguments: * Matrix <input> (char *) * Pointer to matrix. * * >>> Possible Errors: * Returns nonzero if error, zero otherwise. */voidspInstallInitInfo( pElement, pInitInfo )RealNumber *pElement;char *pInitInfo;{/* Begin `spInstallInitInfo'. */ ASSERT(pElement != NULL); ((ElementPtr)pElement)->pInitInfo = pInitInfo;}char *spGetInitInfo( pElement )RealNumber *pElement;{/* Begin `spGetInitInfo'. */ ASSERT(pElement != NULL); return (char *)((ElementPtr)pElement)->pInitInfo;}intspInitialize( eMatrix, pInit )char *eMatrix;int (*pInit)();{MatrixPtr Matrix = (MatrixPtr)eMatrix;register ElementPtr pElement;int J, Error, Col;/* Begin `spInitialize'. */ ASSERT( IS_SPARSE( Matrix ) );#if spCOMPLEX/* Clear imaginary part of matrix if matrix is real but was complex. */ if (Matrix->PreviousMatrixWasComplex AND NOT Matrix->Complex) { for (J = Matrix->Size; J > 0; J--) { pElement = Matrix->FirstInCol[J]; while (pElement != NULL) { pElement->Imag = 0.0; pElement = pElement->NextInCol; } } }#endif /* spCOMPLEX *//* Initialize the matrix. */ for (J = Matrix->Size; J > 0; J--) { pElement = Matrix->FirstInCol[J]; Col = Matrix->IntToExtColMap[J]; while (pElement != NULL) { if (pElement->pInitInfo == NULL) { pElement->Real = 0.0;# if spCOMPLEX pElement->Imag = 0.0;# endif } else { Error = (*pInit)((RealNumber *)pElement, pElement->pInitInfo, Matrix->IntToExtRowMap[pElement->Row], Col); if (Error) { Matrix->Error = spFATAL; return Error; } } pElement = pElement->NextInCol; } }/* Empty the trash. */ Matrix->TrashCan.Real = 0.0;#if spCOMPLEX Matrix->TrashCan.Imag = 0.0;#endif Matrix->Error = spOKAY; Matrix->Factored = NO; Matrix->SingularCol = 0; Matrix->SingularRow = 0; Matrix->PreviousMatrixWasComplex = Matrix->Complex; return 0;}#endif /* INITIALIZE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -