📄 spbuild.c
字号:
#if INITIALIZE
pCreatedElement->pInitInfo = NULL;
#endif
/* If element is on diagonal, store pointer in Diag. */
if (Row == Col) Matrix->Diag[Row] = pCreatedElement;
/* Splice element into column. */
pCreatedElement->NextInCol = *ppAbove;
*ppAbove = pCreatedElement;
/* Find Element immediately to the left of the fill-in. */
if (Matrix->RowsLinked)
{ pElement = *ppToLeft;
while (pElement != NULL)
{ if (pElement->Col < Col)
{ ppToLeft = &pElement->NextInRow;
pElement = *ppToLeft;
}
else break; /* while loop */
}
/* Splice element into row. */
pCreatedElement->NextInRow = *ppToLeft;
*ppToLeft = pCreatedElement;
}
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.
*/
void
spcLinkRows( MatrixPtr Matrix )
{
register ElementPtr pElement, *FirstInRowEntry;
register ArrayOfElementPtrs FirstInRowArray;
register int Col;
/* Begin `spcLinkRows'. */
FirstInRowArray = Matrix->FirstInRow;
for (Col = Matrix->Size; Col >= 1; Col--)
FirstInRowArray[Col] = NULL;
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 void
EnlargeMatrix(
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, (int)(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 void
ExpandTranslationArrays(
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, (int)(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 the matrix.
*
* With the \a 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 \a pInitInfo
* pointer (the user supplied pointer). If the \a pInitInfo is \a 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 \a 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, sets the error state of
* the matrix to be \a spMANGLED, and returns the error code.
*
* \return
* Returns the return value of the \a pInit() function.
* \param eMatrix
* Pointer to matrix.
* \param pInit
* Pointer to a function that initializes an element.
* \see spClear()
*/
int
spInitialize(
spMatrix eMatrix,
int (*pInit)(
spElement *pElement,
spGenericPtr pInitInfo,
int Row,
int Col
)
)
{
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 = spMANGLED;
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;
}
/*!
* This function installs a pointer to a data structure that is used
* to contain initialization information to a matrix element. It is
* is then used by spInitialize() to initialize the matrix.
*
* \param pElement
* Pointer to matrix element.
* \param pInitInfo
* Pointer to the data structure that will contain initialiation
* information.
* \see spInitialize()
*/
void
spInstallInitInfo(
spElement *pElement,
spGenericPtr pInitInfo
)
{
/* Begin `spInstallInitInfo'. */
vASSERT( pElement != NULL, "Invalid element pointer" );
((ElementPtr)pElement)->pInitInfo = pInitInfo;
}
/*!
* This function returns a pointer to a data structure that is used
* to contain initialization information to a matrix element.
*
* \return
* The pointer to the initialiation information data structure
* that is associated with a particular matrix element.
*
* \param pElement
* Pointer to the matrix element.
*
* \see spInitialize()
*/
spGenericPtr
spGetInitInfo(
spElement *pElement
)
{
/* Begin `spGetInitInfo'. */
vASSERT( pElement != NULL, "Invalid element pointer" );
return (spGenericPtr)((ElementPtr)pElement)->pInitInfo;
}
#endif /* INITIALIZE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -