spAllocate.c File Reference

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

Include dependency graph for spAllocate.c:

Go to the source code of this file.

Defines

#define spINSIDE_SPARSE

Functions

static InitializeElementBlocks ()
static RecordAllocation ()
static AllocateBlockOfAllocationList ()
char * spCreate (int Size, SPBOOLEAN Complex, int *pError)
ElementPtr spcGetElement (MatrixPtr Matrix)
static InitializeElementBlocks (MatrixPtr Matrix, int InitialNumberOfElements, int NumberOfFillinsExpected)
ElementPtr spcGetFillin (MatrixPtr Matrix)
static RecordAllocation (MatrixPtr Matrix, char *AllocatedPtr)
static AllocateBlockOfAllocationList (MatrixPtr Matrix)
void spDestroy (char *eMatrix)
int spError (char *eMatrix)
void spWhereSingular (char *eMatrix, int *pRow, int *pCol)
int spGetSize (char *eMatrix, SPBOOLEAN External)
void spSetReal (char *eMatrix)
void spSetComplex (char *eMatrix)
int spFillinCount (char *eMatrix)
int spElementCount (char *eMatrix)


Define Documentation

#define spINSIDE_SPARSE

Definition at line 63 of file spAllocate.c.


Function Documentation

static AllocateBlockOfAllocationList ( MatrixPtr  Matrix  )  [static]

Definition at line 568 of file spAllocate.c.

References AllocationRecord::AllocatedPtr, I, AllocationRecord::NextRecord, NULL, SPALLOC, and spNO_MEMORY.

00571 {
00572 register  int  I;
00573 register  AllocationListPtr  ListPtr;
00574 
00575 /* Begin `AllocateBlockOfAllocationList'. */
00576 /* Allocate block of records for allocation list. */
00577     ListPtr = SPALLOC(struct AllocationRecord, (ELEMENTS_PER_ALLOCATION+1));
00578     if (ListPtr == NULL)
00579     {   Matrix->Error = spNO_MEMORY;
00580         return 0;
00581     }
00582 
00583 /* String entries of allocation list into singly linked list.  List is linked
00584    such that any record points to the one before it. */
00585 
00586     ListPtr->NextRecord = Matrix->TopOfAllocationList;
00587     Matrix->TopOfAllocationList = ListPtr;
00588     ListPtr += ELEMENTS_PER_ALLOCATION;
00589     for (I = ELEMENTS_PER_ALLOCATION; I > 0; I--)
00590     {    ListPtr->NextRecord = ListPtr - 1;
00591          ListPtr--;
00592     }
00593 
00594 /* Record allocation of space for allocation list on allocation list. */
00595     Matrix->TopOfAllocationList->AllocatedPtr = (char *)ListPtr;
00596     Matrix->RecordsRemaining = ELEMENTS_PER_ALLOCATION;
00597 
00598     return 0;
00599 }

static AllocateBlockOfAllocationList (  )  [static]

Referenced by RecordAllocation().

Here is the caller graph for this function:

static InitializeElementBlocks ( MatrixPtr  Matrix,
int  InitialNumberOfElements,
int  NumberOfFillinsExpected 
) [static]

Definition at line 368 of file spAllocate.c.

References NULL, RecordAllocation(), SPALLOC, and spNO_MEMORY.

00373 {
00374 ElementPtr  pElement;
00375 
00376 /* Begin `InitializeElementBlocks'. */
00377 
00378 /* Allocate block of MatrixElements for elements. */
00379     pElement = SPALLOC(struct MatrixElement, InitialNumberOfElements);
00380     RecordAllocation( Matrix, (char *)pElement );
00381     if (Matrix->Error == spNO_MEMORY) return 0;
00382     Matrix->ElementsRemaining = InitialNumberOfElements;
00383     Matrix->NextAvailElement = pElement;
00384 
00385 /* Allocate block of MatrixElements for fill-ins. */
00386     pElement = SPALLOC(struct MatrixElement, NumberOfFillinsExpected);
00387     RecordAllocation( Matrix, (char *)pElement );
00388     if (Matrix->Error == spNO_MEMORY) return 0;
00389     Matrix->FillinsRemaining = NumberOfFillinsExpected;
00390     Matrix->NextAvailFillin = pElement;
00391 
00392 /* Allocate a fill-in list structure. */
00393     Matrix->FirstFillinListNode = SPALLOC(struct FillinListNodeStruct,1);
00394     RecordAllocation( Matrix, (char *)Matrix->FirstFillinListNode );
00395     if (Matrix->Error == spNO_MEMORY) return 0;
00396     Matrix->LastFillinListNode = Matrix->FirstFillinListNode;
00397 
00398     Matrix->FirstFillinListNode->pFillinList = pElement;
00399     Matrix->FirstFillinListNode->NumberOfFillinsInList =NumberOfFillinsExpected;
00400     Matrix->FirstFillinListNode->Next = NULL;
00401 
00402     return 0;
00403 }

Here is the call graph for this function:

static InitializeElementBlocks (  )  [static]

Referenced by spCreate().

Here is the caller graph for this function:

static RecordAllocation ( MatrixPtr  Matrix,
char *  AllocatedPtr 
) [static]

Definition at line 511 of file spAllocate.c.

References AllocateBlockOfAllocationList(), NULL, SPFREE, and spNO_MEMORY.

00515 {
00516 /* Begin `RecordAllocation'. */
00517 /*
00518  * If Allocated pointer is NULL, assume that malloc returned a NULL pointer,
00519  * which indicates a spNO_MEMORY error.
00520  */
00521     if (AllocatedPtr == NULL)
00522     {   Matrix->Error = spNO_MEMORY;
00523         return 0;
00524     }
00525 
00526 /* Allocate block of MatrixElements if necessary. */
00527     if (Matrix->RecordsRemaining == 0)
00528     {   AllocateBlockOfAllocationList( Matrix );
00529         if (Matrix->Error == spNO_MEMORY)
00530         {   SPFREE(AllocatedPtr);
00531             return 0;
00532         }
00533     }
00534 
00535 /* Add Allocated pointer to Allocation List. */
00536     (++Matrix->TopOfAllocationList)->AllocatedPtr = AllocatedPtr;
00537     Matrix->RecordsRemaining--;
00538     return 0;
00539 
00540 }

Here is the call graph for this function:

static RecordAllocation (  )  [static]

Referenced by InitializeElementBlocks(), spcGetElement(), spcGetFillin(), and spCreate().

Here is the caller graph for this function:

ElementPtr spcGetElement ( MatrixPtr  Matrix  ) 

Definition at line 307 of file spAllocate.c.

References NULL, RecordAllocation(), SPALLOC, and spNO_MEMORY.

Referenced by spcCreateElement(), and spcGetFillin().

00310 {
00311 ElementPtr  pElement;
00312 
00313 /* Begin `spcGetElement'. */
00314 
00315 /* Allocate block of MatrixElements if necessary. */
00316     if (Matrix->ElementsRemaining == 0)
00317     {   pElement = SPALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
00318         RecordAllocation( Matrix, (char *)pElement );
00319         if (Matrix->Error == spNO_MEMORY) return NULL;
00320         Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION;
00321         Matrix->NextAvailElement = pElement;
00322     }
00323 
00324 /* Update Element counter and return pointer to Element. */
00325     Matrix->ElementsRemaining--;
00326     return Matrix->NextAvailElement++;
00327 
00328 }

Here is the call graph for this function:

Here is the caller graph for this function:

ElementPtr spcGetFillin ( MatrixPtr  Matrix  ) 

Definition at line 434 of file spAllocate.c.

References FillinListNodeStruct::Next, NULL, FillinListNodeStruct::NumberOfFillinsInList, FillinListNodeStruct::pFillinList, RecordAllocation(), SPALLOC, spcGetElement(), and spNO_MEMORY.

Referenced by spcCreateElement().

00437 {
00438 struct FillinListNodeStruct *pListNode;
00439 ElementPtr  pFillins;
00440 
00441 /* Begin `spcGetFillin'. */
00442 
00443 #if NOT STRIP OR LINT
00444     if (Matrix->FillinsRemaining == 0)
00445         return spcGetElement( Matrix );
00446 #endif
00447 #if STRIP OR LINT
00448 
00449     if (Matrix->FillinsRemaining == 0)
00450     {   pListNode = Matrix->LastFillinListNode;
00451 
00452 /* First see if there are any stripped fill-ins left. */
00453         if (pListNode->Next != NULL)
00454         {   Matrix->LastFillinListNode = pListNode = pListNode->Next;
00455             Matrix->FillinsRemaining = pListNode->NumberOfFillinsInList;
00456             Matrix->NextAvailFillin = pListNode->pFillinList;
00457         }
00458         else
00459         {
00460 /* Allocate block of fill-ins. */
00461             pFillins = SPALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
00462             RecordAllocation( Matrix, (char *)pFillins );
00463             if (Matrix->Error == spNO_MEMORY) return NULL;
00464             Matrix->FillinsRemaining = ELEMENTS_PER_ALLOCATION;
00465             Matrix->NextAvailFillin = pFillins;
00466 
00467 /* Allocate a fill-in list structure. */
00468             pListNode->Next = SPALLOC(struct FillinListNodeStruct,1);
00469             RecordAllocation( Matrix, (char *)pListNode->Next );
00470             if (Matrix->Error == spNO_MEMORY) return NULL;
00471             Matrix->LastFillinListNode = pListNode = pListNode->Next;
00472 
00473             pListNode->pFillinList = pFillins;
00474             pListNode->NumberOfFillinsInList = ELEMENTS_PER_ALLOCATION;
00475             pListNode->Next = NULL;
00476         }
00477     }
00478 #endif
00479 
00480 /* Update Fill-in counter and return pointer to Fill-in. */
00481     Matrix->FillinsRemaining--;
00482     return Matrix->NextAvailFillin++;
00483 }

Here is the call graph for this function:

Here is the caller graph for this function:

char* spCreate ( int  Size,
SPBOOLEAN  Complex,
int pError 
)

Definition at line 113 of file spAllocate.c.

References AND, I, InitializeElementBlocks(), MAX, NO, NOT, NULL, OR, RecordAllocation(), SPALLOC, SPARSE_ID, SPCALLOC, spDestroy(), spNO_MEMORY, spOKAY, spPANIC, and YES.

00117 {
00118 register  unsigned  SizePlusOne;
00119 register  MatrixPtr  Matrix;
00120 register  int  I;
00121 int  AllocatedSize;
00122 
00123 /* Begin `spCreate'. */
00124 /* Clear error flag. */
00125     *pError = spOKAY;
00126 
00127 /* Test for valid size. */
00128     if ((Size < 0) OR (Size == 0 AND NOT EXPANDABLE))
00129     {   *pError = spPANIC;
00130         return NULL;
00131     }
00132 
00133 /* Test for valid type. */
00134 #if NOT spCOMPLEX
00135     if (Complex)
00136     {   *pError = spPANIC;
00137         return NULL;
00138     }
00139 #endif
00140 #if NOT REAL
00141     if (NOT Complex)
00142     {   *pError = spPANIC;
00143         return NULL;
00144     }
00145 #endif
00146 
00147 /* Create Matrix. */
00148     AllocatedSize = MAX( Size, MINIMUM_ALLOCATED_SIZE );
00149     SizePlusOne = (unsigned)(AllocatedSize + 1);
00150 
00151     if ((Matrix = SPALLOC(struct MatrixFrame, 1)) == NULL)
00152     {   *pError = spNO_MEMORY;
00153         return NULL;
00154     }
00155 
00156 /* Initialize matrix */
00157     Matrix->ID = SPARSE_ID;
00158     Matrix->Complex = Complex;
00159     Matrix->PreviousMatrixWasComplex = Complex;
00160     Matrix->Factored = NO;
00161     Matrix->Elements = 0;
00162     Matrix->Error = *pError;
00163     Matrix->Fillins = 0;
00164     Matrix->Reordered = NO;
00165     Matrix->NeedsOrdering = YES;
00166     Matrix->NumberOfInterchangesIsOdd = NO;
00167     Matrix->Partitioned = NO;
00168     Matrix->RowsLinked = NO;
00169     Matrix->InternalVectorsAllocated = NO;
00170     Matrix->SingularCol = 0;
00171     Matrix->SingularRow = 0;
00172     Matrix->Size = Size;
00173     Matrix->AllocatedSize = AllocatedSize;
00174     Matrix->ExtSize = Size;
00175     Matrix->AllocatedExtSize = AllocatedSize;
00176     Matrix->CurrentSize = 0;
00177     Matrix->ExtToIntColMap = NULL;
00178     Matrix->ExtToIntRowMap = NULL;
00179     Matrix->IntToExtColMap = NULL;
00180     Matrix->IntToExtRowMap = NULL;
00181     Matrix->MarkowitzRow = NULL;
00182     Matrix->MarkowitzCol = NULL;
00183     Matrix->MarkowitzProd = NULL;
00184     Matrix->DoCmplxDirect = NULL;
00185     Matrix->DoRealDirect = NULL;
00186     Matrix->Intermediate = NULL;
00187     Matrix->RelThreshold = DEFAULT_THRESHOLD;
00188     Matrix->AbsThreshold = 0.0;
00189 
00190     Matrix->TopOfAllocationList = NULL;
00191     Matrix->RecordsRemaining = 0;
00192     Matrix->ElementsRemaining = 0;
00193     Matrix->FillinsRemaining = 0;
00194 
00195     RecordAllocation( Matrix, (char *)Matrix );
00196     if (Matrix->Error == spNO_MEMORY) goto MemoryError; 
00197 
00198 /* Take out the trash. */
00199     Matrix->TrashCan.Real = 0.0;
00200 #if spCOMPLEX
00201     Matrix->TrashCan.Imag = 0.0;
00202 #endif
00203     Matrix->TrashCan.Row = 0;
00204     Matrix->TrashCan.Col = 0;
00205     Matrix->TrashCan.NextInRow = NULL;
00206     Matrix->TrashCan.NextInCol = NULL;
00207 #if INITIALIZE
00208     Matrix->TrashCan.pInitInfo = NULL;
00209 #endif
00210 
00211 /* Allocate space in memory for Diag pointer vector. */
00212     SPCALLOC( Matrix->Diag, ElementPtr, SizePlusOne);
00213     if (Matrix->Diag == NULL)
00214         goto MemoryError;
00215 
00216 /* Allocate space in memory for FirstInCol pointer vector. */
00217     SPCALLOC( Matrix->FirstInCol, ElementPtr, SizePlusOne);
00218     if (Matrix->FirstInCol == NULL)
00219         goto MemoryError;
00220 
00221 /* Allocate space in memory for FirstInRow pointer vector. */
00222     SPCALLOC( Matrix->FirstInRow, ElementPtr, SizePlusOne);
00223     if (Matrix->FirstInRow == NULL)
00224         goto MemoryError;
00225 
00226 /* Allocate space in memory for IntToExtColMap vector. */
00227     if (( Matrix->IntToExtColMap = SPALLOC(int, SizePlusOne)) == NULL)
00228         goto MemoryError;
00229 
00230 /* Allocate space in memory for IntToExtRowMap vector. */
00231     if (( Matrix->IntToExtRowMap = SPALLOC(int, SizePlusOne)) == NULL)
00232         goto MemoryError;
00233 
00234 /* Initialize MapIntToExt vectors. */
00235     for (I = 1; I <= AllocatedSize; I++)
00236     {   Matrix->IntToExtRowMap[I] = I;
00237         Matrix->IntToExtColMap[I] = I;
00238     }
00239 
00240 #if TRANSLATE
00241 /* Allocate space in memory for ExtToIntColMap vector. */
00242     if (( Matrix->ExtToIntColMap = SPALLOC(int, SizePlusOne)) == NULL)
00243         goto MemoryError;
00244 
00245 /* Allocate space in memory for ExtToIntRowMap vector. */
00246     if (( Matrix->ExtToIntRowMap = SPALLOC(int, SizePlusOne)) == NULL)
00247         goto MemoryError;
00248 
00249 /* Initialize MapExtToInt vectors. */
00250     for (I = 1; I <= AllocatedSize; I++)
00251     {   Matrix->ExtToIntColMap[I] = -1;
00252         Matrix->ExtToIntRowMap[I] = -1;
00253     }
00254     Matrix->ExtToIntColMap[0] = 0;
00255     Matrix->ExtToIntRowMap[0] = 0;
00256 #endif
00257 
00258 /* Allocate space for fill-ins and initial set of elements. */
00259     InitializeElementBlocks( Matrix, SPACE_FOR_ELEMENTS*AllocatedSize,
00260                                      SPACE_FOR_FILL_INS*AllocatedSize );
00261     if (Matrix->Error == spNO_MEMORY)
00262         goto MemoryError;
00263 
00264     return (char *)Matrix;
00265 
00266 MemoryError:
00267 
00268 /* Deallocate matrix and return no pointer to matrix if there is not enough
00269    memory. */
00270     *pError = spNO_MEMORY;
00271     spDestroy( (char *)Matrix);
00272     return NULL;
00273 }

Here is the call graph for this function:

void spDestroy ( char *  eMatrix  ) 

Definition at line 629 of file spAllocate.c.

References AllocationRecord::AllocatedPtr, ASSERT, free(), IS_SPARSE, AllocationRecord::NextRecord, NULL, and SPFREE.

00632 {
00633 MatrixPtr Matrix = (MatrixPtr)eMatrix;
00634 register  AllocationListPtr  ListPtr, NextListPtr;
00635 
00636 
00637 /* Begin `spDestroy'. */
00638     ASSERT( IS_SPARSE( Matrix ) );
00639 
00640 /* Deallocate the vectors that are located in the matrix frame. */
00641     SPFREE( Matrix->IntToExtColMap );
00642     SPFREE( Matrix->IntToExtRowMap );
00643     SPFREE( Matrix->ExtToIntColMap );
00644     SPFREE( Matrix->ExtToIntRowMap );
00645     SPFREE( Matrix->Diag );
00646     SPFREE( Matrix->FirstInRow );
00647     SPFREE( Matrix->FirstInCol );
00648     SPFREE( Matrix->MarkowitzRow );
00649     SPFREE( Matrix->MarkowitzCol );
00650     SPFREE( Matrix->MarkowitzProd );
00651     SPFREE( Matrix->DoCmplxDirect );
00652     SPFREE( Matrix->DoRealDirect );
00653     SPFREE( Matrix->Intermediate );
00654 
00655 
00656 /* Sequentially step through the list of allocated pointers freeing pointers
00657  * along the way. */
00658 
00659     ListPtr = Matrix->TopOfAllocationList;
00660     while (ListPtr != NULL )
00661     { 
00662       char *LocPtr;
00663       /* dans certain cas le pointeur ds la zone a desalouer
00664          se trouve lui meme ds la dite zone en fait quand 
00665          ( ListPtr ==  ListPtr->AllocatedPtr )
00666          donc un free(x) suivit de x=0 
00667          fait que l'on essaye d'ecrire ds une zone que l'on vient de desalouer
00668          ce qui plante sur linux 
00669          fprintf(stderr,"Warning bad SPFREE\n");
00670          je regle le probleme en mettant a zero avant le free !
00671          */
00672       NextListPtr = ListPtr->NextRecord;
00673       /* BUGUED : SPFREE( ListPtr->AllocatedPtr) */
00674       LocPtr=ListPtr->AllocatedPtr;
00675       ListPtr->AllocatedPtr= NULL;
00676       if ( LocPtr != NULL) free(LocPtr);
00677       ListPtr = NextListPtr;
00678     }
00679     return;
00680 }

Here is the call graph for this function:

int spElementCount ( char *  eMatrix  ) 

Definition at line 874 of file spAllocate.c.

References ASSERT, and IS_SPARSE.

00877 {
00878 /* Begin `spElementCount'. */
00879 
00880     ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) );
00881     return ((MatrixPtr)eMatrix)->Elements;
00882 }

int spError ( char *  eMatrix  ) 

Definition at line 702 of file spAllocate.c.

References ASSERT, NULL, SPARSE_ID, and spNO_MEMORY.

00705 {
00706 /* Begin `spError'. */
00707 
00708     if (eMatrix != NULL)
00709     {   ASSERT(((MatrixPtr)eMatrix)->ID == SPARSE_ID);
00710         return ((MatrixPtr)eMatrix)->Error;
00711     }
00712     else return spNO_MEMORY;   /* This error may actually be spPANIC,
00713                                 * no way to tell. */
00714 }

int spFillinCount ( char *  eMatrix  ) 

Definition at line 862 of file spAllocate.c.

References ASSERT, and IS_SPARSE.

00865 {
00866 /* Begin `spFillinCount'. */
00867 
00868     ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) );
00869     return ((MatrixPtr)eMatrix)->Fillins;
00870 }

int spGetSize ( char *  eMatrix,
SPBOOLEAN  External 
)

Definition at line 780 of file spAllocate.c.

References ASSERT, and IS_SPARSE.

00784 {
00785 MatrixPtr Matrix = (MatrixPtr)eMatrix;
00786 
00787 /* Begin `spGetSize'. */
00788     ASSERT( IS_SPARSE( Matrix ) );
00789 
00790 #if TRANSLATE
00791     if (External)
00792         return Matrix->ExtSize;
00793     else
00794         return Matrix->Size;
00795 #else
00796     return Matrix->Size;
00797 #endif
00798 }

void spSetComplex ( char *  eMatrix  ) 

Definition at line 831 of file spAllocate.c.

References AND, ASSERT, IS_SPARSE, spCOMPLEX, and YES.

00834 {
00835 /* Begin `spSetComplex'. */
00836 
00837     ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) AND spCOMPLEX);
00838     ((MatrixPtr)eMatrix)->Complex = YES;
00839     return;
00840 }

void spSetReal ( char *  eMatrix  ) 

Definition at line 818 of file spAllocate.c.

References AND, ASSERT, IS_SPARSE, NO, and REAL.

00821 {
00822 /* Begin `spSetReal'. */
00823 
00824     ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) AND REAL);
00825     ((MatrixPtr)eMatrix)->Complex = NO;
00826     return;
00827 }

void spWhereSingular ( char *  eMatrix,
int pRow,
int pCol 
)

Definition at line 740 of file spAllocate.c.

References ASSERT, IS_SPARSE, OR, spSINGULAR, and spZERO_DIAG.

00744 {
00745 MatrixPtr Matrix = (MatrixPtr)eMatrix;
00746 
00747 /* Begin `spWhereSingular'. */
00748     ASSERT( IS_SPARSE( Matrix ) );
00749 
00750     if (Matrix->Error == spSINGULAR OR Matrix->Error == spZERO_DIAG)
00751     {   *pRow = Matrix->SingularRow;
00752         *pCol = Matrix->SingularCol;
00753     }
00754     else *pRow = *pCol = 0;
00755     return;
00756 }


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