⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spallocate.c

📁 DTMK软件开发包,此为开源软件,是一款很好的医学图像开发资源.
💻 C
📖 第 1 页 / 共 2 页
字号:
 *
 *  >>> Arguments:
 *  Matrix  <input>  (MatrixPtr)
 *      Pointer to matrix.
 *
 *  >>> Possible errors:
 *  spNO_MEMORY
 */

ElementPtr
spcGetFillin( MatrixPtr Matrix )
{
struct FillinListNodeStruct *pListNode;
ElementPtr  pFillins;

/* Begin `spcGetFillin'. */

#if NOT STRIP OR LINT
    if (Matrix->FillinsRemaining == 0)
        return spcGetElement( Matrix );
#endif
#if STRIP OR LINT

    if (Matrix->FillinsRemaining == 0)
    {   pListNode = Matrix->LastFillinListNode;

/* First see if there are any stripped fill-ins left. */
        if (pListNode->Next != NULL)
        {   Matrix->LastFillinListNode = pListNode = pListNode->Next;
            Matrix->FillinsRemaining = pListNode->NumberOfFillinsInList;
            Matrix->NextAvailFillin = pListNode->pFillinList;
        }
        else
        {
/* Allocate block of fill-ins. */
            pFillins = ALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
            RecordAllocation( Matrix, (void *)pFillins );
            if (Matrix->Error == spNO_MEMORY) return NULL;
            Matrix->FillinsRemaining = ELEMENTS_PER_ALLOCATION;
            Matrix->NextAvailFillin = pFillins;

/* Allocate a fill-in list structure. */
            pListNode->Next = ALLOC(struct FillinListNodeStruct,1);
            RecordAllocation( Matrix, (void *)pListNode->Next );
            if (Matrix->Error == spNO_MEMORY) return NULL;
            Matrix->LastFillinListNode = pListNode = pListNode->Next;

            pListNode->pFillinList = pFillins;
            pListNode->NumberOfFillinsInList = ELEMENTS_PER_ALLOCATION;
            pListNode->Next = NULL;
        }
    }
#endif

/* Update Fill-in counter and return pointer to Fill-in. */
    Matrix->FillinsRemaining--;
    return Matrix->NextAvailFillin++;
}









/*
 *  RECORD A MEMORY ALLOCATION
 *
 *  This routine is used to record all memory allocations so that the memory
 *  can be freed later.
 *
 *  >>> Arguments:
 *  Matrix  <input>    (MatrixPtr)
 *      Pointer to the matrix.
 *  AllocatedPtr  <input>  (void *)
 *      The pointer returned by malloc or calloc.  These pointers are saved in
 *      a list so that they can be easily freed.
 *
 *  >>> Possible errors:
 *  spNO_MEMORY
 */

static void
RecordAllocation(
    MatrixPtr Matrix,
    void *AllocatedPtr
)
{
/* Begin `RecordAllocation'. */
/*
 * If Allocated pointer is NULL, assume that malloc returned a NULL pointer,
 * which indicates a spNO_MEMORY error.
 */
    if (AllocatedPtr == NULL)
    {   Matrix->Error = spNO_MEMORY;
        return;
    }

/* Allocate block of MatrixElements if necessary. */
    if (Matrix->RecordsRemaining == 0)
    {   AllocateBlockOfAllocationList( Matrix );
        if (Matrix->Error == spNO_MEMORY)
        {   FREE(AllocatedPtr);
            return;
        }
    }

/* Add Allocated pointer to Allocation List. */
    (++Matrix->TopOfAllocationList)->AllocatedPtr = AllocatedPtr;
    Matrix->RecordsRemaining--;
    return;

}








/*
 *  ADD A BLOCK OF SLOTS TO ALLOCATION LIST     
 *
 *  This routine increases the size of the allocation list.
 *
 *  >>> Arguments:
 *  Matrix  <input>    (MatrixPtr)
 *      Pointer to the matrix.
 *
 *  >>> Local variables:
 *  ListPtr  (AllocationListPtr)
 *      Pointer to the list that contains the pointers to segments of memory
 *      that were allocated by the operating system for the current matrix.
 *
 *  >>> Possible errors:
 *  spNO_MEMORY
 */

static void
AllocateBlockOfAllocationList( MatrixPtr Matrix )
{
register  int  I;
register  AllocationListPtr  ListPtr;

/* Begin `AllocateBlockOfAllocationList'. */
/* Allocate block of records for allocation list. */
    ListPtr = ALLOC(struct AllocationRecord, (ELEMENTS_PER_ALLOCATION+1));
    if (ListPtr == NULL)
    {   Matrix->Error = spNO_MEMORY;
        return;
    }

/* String entries of allocation list into singly linked list.  List is linked
   such that any record points to the one before it. */

    ListPtr->NextRecord = Matrix->TopOfAllocationList;
    Matrix->TopOfAllocationList = ListPtr;
    ListPtr += ELEMENTS_PER_ALLOCATION;
    for (I = ELEMENTS_PER_ALLOCATION; I > 0; I--)
    {    ListPtr->NextRecord = ListPtr - 1;
         ListPtr--;
    }

/* Record allocation of space for allocation list on allocation list. */
    Matrix->TopOfAllocationList->AllocatedPtr = (void *)ListPtr;
    Matrix->RecordsRemaining = ELEMENTS_PER_ALLOCATION;

    return;
}








/*!
 *  Destroys a matrix and frees all memory associated with it.
 *
 *  \param eMatrix
 *      Pointer to the matrix frame which is to be destroyed.
 */
/*  >>> Local variables:
 *  ListPtr  (AllocationListPtr)
 *      Pointer into the linked list of pointers to allocated data structures.
 *      Points to pointer to structure to be freed.
 *  NextListPtr  (AllocationListPtr)
 *      Pointer into the linked list of pointers to allocated data structures.
 *      Points to the next pointer to structure to be freed.  This is needed
 *      because the data structure to be freed could include the current node
 *      in the allocation list.
 */

void
spDestroy( spMatrix eMatrix )
{
MatrixPtr Matrix = (MatrixPtr)eMatrix;
register  AllocationListPtr  ListPtr, NextListPtr;

/* Begin `spDestroy'. */
    ASSERT_IS_SPARSE( Matrix );

/* Deallocate the vectors that are located in the matrix frame. */
    FREE( Matrix->IntToExtColMap );
    FREE( Matrix->IntToExtRowMap );
    FREE( Matrix->ExtToIntColMap );
    FREE( Matrix->ExtToIntRowMap );
    FREE( Matrix->Diag );
    FREE( Matrix->FirstInRow );
    FREE( Matrix->FirstInCol );
    FREE( Matrix->MarkowitzRow );
    FREE( Matrix->MarkowitzCol );
    FREE( Matrix->MarkowitzProd );
    FREE( Matrix->DoCmplxDirect );
    FREE( Matrix->DoRealDirect );
    FREE( Matrix->Intermediate );

/* Sequentially step through the list of allocated pointers freeing pointers
 * along the way. */
    ListPtr = Matrix->TopOfAllocationList;
    while (ListPtr != NULL)
    {   NextListPtr = ListPtr->NextRecord;
        free( ListPtr->AllocatedPtr );
        ListPtr = NextListPtr;
    }
    return;
}







/*!
 *  This function returns the error status of the given matrix.
 *
 *  \return
 *      The error status of the given matrix.
 *
 *  \param eMatrix
 *      The pointer to the matrix for which the error status is desired.
 */

spError
spErrorState( spMatrix eMatrix )
{
/* Begin `spErrorState'. */

    if (eMatrix != NULL)
    {   ASSERT_IS_SPARSE( (MatrixPtr)eMatrix );
        return ((MatrixPtr)eMatrix)->Error;
    }
    else return spNO_MEMORY;   /* This error may actually be spPANIC,
                                * no way to tell. */
}









/*!
 *  This function returns the row and column number where the matrix was
 *  detected as singular (if pivoting was allowed on the last factorization)
 *  or where a zero was detected on the diagonal (if pivoting was not
 *  allowed on the last factorization). Pivoting is performed only in
 *  spOrderAndFactor().
 *
 *  \param eMatrix
 *      The matrix for which the error status is desired.
 *  \param pRow
 *      The row number.
 *  \param pCol
 *      The column number.
 */

void
spWhereSingular(
    spMatrix eMatrix,
    int *pRow,
    int *pCol
)
{
MatrixPtr Matrix = (MatrixPtr)eMatrix;

/* Begin `spWhereSingular'. */
    ASSERT_IS_SPARSE( Matrix );

    if (Matrix->Error == spSINGULAR OR Matrix->Error == spZERO_DIAG)
    {   *pRow = Matrix->SingularRow;
        *pCol = Matrix->SingularCol;
    }
    else *pRow = *pCol = 0;
    return;
}






/*!
 *  Returns the size of the matrix.  Either the internal or external size of
 *  the matrix is returned.
 *
 *  \param eMatrix
 *      Pointer to matrix.
 *  \param External
 *      If \a External is set true, the external size , i.e., the value of the
 *      largest external row or column number encountered is returned.
 *      Otherwise the true size of the matrix is returned.  These two sizes
 *      may differ if the \a TRANSLATE option is set true.
 */

int
spGetSize(
    spMatrix eMatrix,
    int External
)
{
MatrixPtr Matrix = (MatrixPtr)eMatrix;

/* Begin `spGetSize'. */
    ASSERT_IS_SPARSE( Matrix );

#if TRANSLATE
    if (External)
        return Matrix->ExtSize;
    else
        return Matrix->Size;
#else
    return Matrix->Size;
#endif
}








/*!
 *  Forces matrix to be real.
 *
 *  \param eMatrix
 *      Pointer to matrix.
 */

void
spSetReal( spMatrix eMatrix )
{
/* Begin `spSetReal'. */

    ASSERT_IS_SPARSE( (MatrixPtr)eMatrix );
    vASSERT( REAL, "Sparse not compiled to handle real matrices" );
    ((MatrixPtr)eMatrix)->Complex = NO;
    return;
}


/*!
 *  Forces matrix to be complex.
 *
 *  \param eMatrix
 *      Pointer to matrix.
 */

void
spSetComplex( spMatrix eMatrix )
{
/* Begin `spSetComplex'. */

    ASSERT_IS_SPARSE( (MatrixPtr)eMatrix );
    vASSERT( spCOMPLEX, "Sparse not compiled to handle complex matrices" );
    ((MatrixPtr)eMatrix)->Complex = YES;
    return;
}









/*!
 *  This function returns the number of fill-ins that currently exists in a matrix.
 *
 *  \param eMatrix
 *      Pointer to matrix.
 */

int
spFillinCount( spMatrix eMatrix )
{
/* Begin `spFillinCount'. */

    ASSERT_IS_SPARSE( (MatrixPtr)eMatrix );
    return ((MatrixPtr)eMatrix)->Fillins;
}


/*!
 *  This function returns the total number of elements (including fill-ins) that currently exists in a matrix.
 *
 *  \param eMatrix
 *      Pointer to matrix.
 */

int
spElementCount( spMatrix eMatrix )
{
/* Begin `spElementCount'. */

    ASSERT_IS_SPARSE( (MatrixPtr)eMatrix );
    return ((MatrixPtr)eMatrix)->Elements;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -