spAllocate.c

Go to the documentation of this file.
00001 /*
00002  *  MATRIX SPALLOCATION MODULE
00003  *
00004  *  Author:                     Advising professor:
00005  *      Kenneth S. Kundert          Alberto Sangiovanni-Vincentelli
00006  *      UC Berkeley
00007  *
00008  *  This file contains the allocation and deallocation routines for the
00009  *  sparse matrix routines.
00010  *
00011  *  >>> User accessible functions contained in this file:
00012  *  spCreate
00013  *  spDestroy
00014  *  spError
00015  *  spWhereSingular
00016  *  spGetSize
00017  *  spSetReal
00018  *  spSetComplex
00019  *  spFillinCount
00020  *  spElementCount
00021  *
00022  *  >>> Other functions contained in this file:
00023  *  spcGetElement
00024  *  InitializeElementBlocks
00025  *  spcGetFillin
00026  *  RecordAllocation
00027  *  AllocateBlockOfAllocationList
00028  *  EnlargeMatrix
00029  *  ExpandTranslationArrays
00030  */
00031 
00032 
00033 /*
00034  *  Revision and copyright information.
00035  *
00036  *  Copyright (c) 1985,86,87,88
00037  *  by Kenneth S. Kundert and the University of California.
00038  *
00039  *  Permission to use, copy, modify, and distribute this software and
00040  *  its documentation for any purpose and without fee is hereby granted,
00041  *  provided that the copyright notices appear in all copies and
00042  *  supporting documentation and that the authors and the University of
00043  *  California are properly credited.  The authors and the University of
00044  *  California make no representations as to the suitability of this
00045  *  software for any purpose.  It is provided `as is', without express
00046  *  or implied warranty.
00047  */
00048 
00049 
00050 
00051 /*
00052  *  IMPORTS
00053  *
00054  *  >>> Import descriptions:
00055  *  spConfig.h
00056  *      Macros that customize the sparse matrix routines.
00057  *  spmatrix.h
00058  *      Macros and declarations to be imported by the user.
00059  *  spDefs.h
00060  *      Matrix type and macro definitions for the sparse matrix routines.
00061  */
00062 
00063 #define spINSIDE_SPARSE
00064 #include "spConfig.h"
00065 #include "spmatrix.h"
00066 #include "spDefs.h"
00067 #include "spmalloc.h"
00068 
00069 static InitializeElementBlocks();
00070 static RecordAllocation();
00071 static AllocateBlockOfAllocationList();
00072 
00073 
00074 
00075 
00076 /*
00077  *  MATRIX SPALLOCATION
00078  *
00079  *  Allocates and initializes the data structures associated with a matrix.
00080  *
00081  *  >>> Returned:
00082  *  A pointer to the matrix is returned cast into the form of a pointer to
00083  *  a character.  This pointer is then passed and used by the other matrix
00084  *  routines to refer to a particular matrix.  If an error occurs, the NULL
00085  *  pointer is returned.
00086  *
00087  *  >>> Arguments:
00088  *  Size  <input>  (int)
00089  *      Size of matrix or estimate of size of matrix if matrix is EXPANDABLE.
00090  *  Complex  <input>  (int)
00091  *      Type of matrix.  If Complex is 0 then the matrix is real, otherwise
00092  *      the matrix will be complex.  Note that if the routines are not set up
00093  *      to handle the type of matrix requested, then a spPANIC error will occur.
00094  *      Further note that if a matrix will be both real and complex, it must
00095  *      be specified here as being complex.
00096  *  pError  <output>  (int *)
00097  *      Returns error flag, needed because function spError() will not work
00098  *      correctly if spCreate() returns NULL.
00099  *
00100  *  >>> Local variables:
00101  *  AllocatedSize  (int)
00102  *      The size of the matrix being allocated.
00103  *  Matrix  (MatrixPtr)
00104  *      A pointer to the matrix frame being created.
00105  *
00106  *  >>> Possible errors:
00107  *  spNO_MEMORY
00108  *  spPANIC
00109  *  Error is cleared in this routine.
00110  */
00111 
00112 char *
00113 spCreate( Size, Complex, pError )
00114 
00115 int  Size, *pError;
00116 SPBOOLEAN  Complex;
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 }
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 /*
00284  *  ELEMENT SPALLOCATION
00285  *
00286  *  This routine allocates space for matrix elements. It requests large blocks
00287  *  of storage from the system and doles out individual elements as required.
00288  *  This technique, as opposed to allocating elements individually, tends to
00289  *  speed the allocation process.
00290  *
00291  *  >>> Returned:
00292  *  A pointer to an element.
00293  *
00294  *  >>> Arguments:
00295  *  Matrix  <input>  (MatrixPtr)
00296  *      Pointer to matrix.
00297  *
00298  *  >>> Local variables:
00299  *  pElement  (ElementPtr)
00300  *      A pointer to the first element in the group of elements being allocated.
00301  *
00302  *  >>> Possible errors:
00303  *  spNO_MEMORY
00304  */
00305 
00306 ElementPtr
00307 spcGetElement( Matrix )
00308 
00309 MatrixPtr Matrix;
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 }
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 /*
00338  *  ELEMENT SPALLOCATION INITIALIZATION
00339  *
00340  *  This routine allocates space for matrix fill-ins and an initial set of
00341  *  elements.  Besides being faster than allocating space for elements one
00342  *  at a time, it tends to keep the fill-ins physically close to the other
00343  *  matrix elements in the computer memory.  This keeps virtual memory paging
00344  *  to a minimum.
00345  *
00346  *  >>> Arguments:
00347  *  Matrix  <input>    (MatrixPtr)
00348  *      Pointer to the matrix.
00349  *  InitialNumberOfElements  <input> (int)
00350  *      This number is used as the size of the block of memory, in
00351  *      MatrixElements, reserved for elements. If more than this number of
00352  *      elements are generated, then more space is allocated later.
00353  *  NumberOfFillinsExpected  <input> (int)
00354  *      This number is used as the size of the block of memory, in
00355  *      MatrixElements, reserved for fill-ins. If more than this number of
00356  *      fill-ins are generated, then more space is allocated, but they may
00357  *      not be physically close in computer's memory.
00358  *
00359  *  >>> Local variables:
00360  *  pElement  (ElementPtr)
00361  *      A pointer to the first element in the group of elements being allocated.
00362  *
00363  *  >>> Possible errors:
00364  *  spNO_MEMORY
00365  */
00366 
00367 static
00368 InitializeElementBlocks( Matrix, InitialNumberOfElements,
00369                          NumberOfFillinsExpected )
00370 
00371 MatrixPtr Matrix;
00372 int  InitialNumberOfElements, NumberOfFillinsExpected;
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 }
00404 
00405 
00406 
00407 
00408 
00409 
00410 
00411 
00412 
00413 
00414 /*
00415  *  FILL-IN SPALLOCATION
00416  *
00417  *  This routine allocates space for matrix fill-ins. It requests large blocks
00418  *  of storage from the system and doles out individual elements as required.
00419  *  This technique, as opposed to allocating elements individually, tends to
00420  *  speed the allocation process.
00421  *
00422  *  >>> Returned:
00423  *  A pointer to the fill-in.
00424  *
00425  *  >>> Arguments:
00426  *  Matrix  <input>  (MatrixPtr)
00427  *      Pointer to matrix.
00428  *
00429  *  >>> Possible errors:
00430  *  spNO_MEMORY
00431  */
00432 
00433 ElementPtr
00434 spcGetFillin( Matrix )
00435 
00436 MatrixPtr Matrix;
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 }
00484 
00485 
00486 
00487 
00488 
00489 
00490 
00491 
00492 
00493 /*
00494  *  RECORD A MEMORY SPALLOCATION
00495  *
00496  *  This routine is used to record all memory allocations so that the memory
00497  *  can be freed later.
00498  *
00499  *  >>> Arguments:
00500  *  Matrix  <input>    (MatrixPtr)
00501  *      Pointer to the matrix.
00502  *  AllocatedPtr  <input>  (char *)
00503  *      The pointer returned by malloc or calloc.  These pointers are saved in
00504  *      a list so that they can be easily freed.
00505  *
00506  *  >>> Possible errors:
00507  *  spNO_MEMORY
00508  */
00509 
00510 static
00511 RecordAllocation( Matrix, AllocatedPtr )
00512 
00513 MatrixPtr Matrix;
00514 char  *AllocatedPtr;
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 }
00541 
00542 
00543 
00544 
00545 
00546 
00547 
00548 
00549 /*
00550  *  ADD A BLOCK OF SLOTS TO SPALLOCATION LIST     
00551  *
00552  *  This routine increases the size of the allocation list.
00553  *
00554  *  >>> Arguments:
00555  *  Matrix  <input>    (MatrixPtr)
00556  *      Pointer to the matrix.
00557  *
00558  *  >>> Local variables:
00559  *  ListPtr  (AllocationListPtr)
00560  *      Pointer to the list that contains the pointers to segments of memory
00561  *      that were allocated by the operating system for the current matrix.
00562  *
00563  *  >>> Possible errors:
00564  *  spNO_MEMORY
00565  */
00566 
00567 static
00568 AllocateBlockOfAllocationList( Matrix )
00569 
00570 MatrixPtr Matrix;
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 }
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 
00608 /*
00609  *  MATRIX DEALLOCATION
00610  *
00611  *  Deallocates pointers and elements of Matrix.
00612  *
00613  *  >>> Arguments:
00614  *  Matrix  <input>  (char *)
00615  *      Pointer to the matrix frame which is to be removed from memory.
00616  *
00617  *  >>> Local variables:
00618  *  ListPtr  (AllocationListPtr)
00619  *      Pointer into the linked list of pointers to allocated data structures.
00620  *      Points to pointer to structure to be freed.
00621  *  NextListPtr  (AllocationListPtr)
00622  *      Pointer into the linked list of pointers to allocated data structures.
00623  *      Points to the next pointer to structure to be freed.  This is needed
00624  *      because the data structure to be freed could include the current node
00625  *      in the allocation list.
00626  */
00627 
00628 void
00629 spDestroy( eMatrix )
00630 
00631 register char *eMatrix;
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 }
00681 
00682 
00683 
00684 
00685 
00686 
00687 
00688 /*
00689  *  RETURN MATRIX ERROR STATUS
00690  *
00691  *  This function is used to determine the error status of the given matrix.
00692  *
00693  *  >>> Returned:
00694  *      The error status of the given matrix.
00695  *
00696  *  >>> Arguments:
00697  *  eMatrix  <input>  (char *)
00698  *      The matrix for which the error status is desired.
00699  */
00700 
00701 int
00702 spError( eMatrix )
00703 
00704 char  *eMatrix;
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 }
00715 
00716 
00717 
00718 
00719 
00720 
00721 
00722 
00723 
00724 /*
00725  *  WHERE IS MATRIX SINGULAR
00726  *
00727  *  This function returns the row and column number where the matrix was
00728  *  detected as singular or where a zero was detected on the diagonal.
00729  *
00730  *  >>> Arguments:
00731  *  eMatrix  <input>  (char *)
00732  *      The matrix for which the error status is desired.
00733  *  pRow  <output>  (int *)
00734  *      The row number.
00735  *  pCol  <output>  (int *)
00736  *      The column number.
00737  */
00738 
00739 void
00740 spWhereSingular( eMatrix, pRow, pCol )
00741 
00742 char *eMatrix;
00743 int *pRow, *pCol;
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 }
00757 
00758 
00759 
00760 
00761 
00762 
00763 /*
00764  *  MATRIX SIZE
00765  *
00766  *  Returns the size of the matrix.  Either the internal or external size of
00767  *  the matrix is returned.
00768  *
00769  *  >>> Arguments:
00770  *  eMatrix  <input>  (char *)
00771  *      Pointer to matrix.
00772  *  External  <input>  (SPBOOLEAN)
00773  *      If External is set true, the external size , i.e., the value of the
00774  *      largest external row or column number encountered is returned.
00775  *      Otherwise the true size of the matrix is returned.  These two sizes
00776  *      may differ if the TRANSLATE option is set true.
00777  */
00778 
00779 int
00780 spGetSize( eMatrix, External )
00781 
00782 char  *eMatrix;
00783 SPBOOLEAN  External;
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 }
00799 
00800 
00801 
00802 
00803 
00804 
00805 
00806 
00807 /*
00808  *  SET MATRIX COMPLEX OR REAL
00809  *
00810  *  Forces matrix to be either real or complex.
00811  *
00812  *  >>> Arguments:
00813  *  eMatrix  <input>  (char *)
00814  *      Pointer to matrix.
00815  */
00816 
00817 void
00818 spSetReal( eMatrix )
00819 
00820 char *eMatrix;
00821 {
00822 /* Begin `spSetReal'. */
00823 
00824     ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) AND REAL);
00825     ((MatrixPtr)eMatrix)->Complex = NO;
00826     return;
00827 }
00828 
00829 
00830 void
00831 spSetComplex( eMatrix )
00832 
00833 char  *eMatrix;
00834 {
00835 /* Begin `spSetComplex'. */
00836 
00837     ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) AND spCOMPLEX);
00838     ((MatrixPtr)eMatrix)->Complex = YES;
00839     return;
00840 }
00841 
00842 
00843 
00844 
00845 
00846 
00847 
00848 
00849 
00850 /*
00851  *  ELEMENT OR FILL-IN COUNT
00852  *
00853  *  Two functions used to return simple statistics.  Either the number
00854  *  of total elements, or the number of fill-ins can be returned.
00855  *
00856  *  >>> Arguments:
00857  *  eMatrix  <input>  (char *)
00858  *      Pointer to matrix.
00859  */
00860 
00861 int
00862 spFillinCount( eMatrix )
00863 
00864 char *eMatrix;
00865 {
00866 /* Begin `spFillinCount'. */
00867 
00868     ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) );
00869     return ((MatrixPtr)eMatrix)->Fillins;
00870 }
00871 
00872 
00873 int
00874 spElementCount( eMatrix )
00875 
00876 char  *eMatrix;
00877 {
00878 /* Begin `spElementCount'. */
00879 
00880     ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) );
00881     return ((MatrixPtr)eMatrix)->Elements;
00882 }

Generated on Sun Mar 4 15:04:00 2007 for Scilab [trunk] by  doxygen 1.5.1