NEURON
spalloc.c
Go to the documentation of this file.
1 #ifdef HAVE_CONFIG_H
2 #include <../../nrnconf.h>
3 #endif
4 /*
5  * MATRIX ALLOCATION MODULE
6  *
7  * Author: Advising professor:
8  * Kenneth S. Kundert Alberto Sangiovanni-Vincentelli
9  * UC Berkeley
10  *
11  * This file contains the allocation and deallocation routines for the
12  * sparse matrix routines.
13  *
14  * >>> User accessible functions contained in this file:
15  * spCreate
16  * spDestroy
17  * spError
18  * spWhereSingular
19  * spGetSize
20  * spSetReal
21  * spSetComplex
22  * spFillinCount
23  * spElementCount
24  *
25  * >>> Other functions contained in this file:
26  * spcGetElement
27  * InitializeElementBlocks
28  * spcGetFillin
29  * RecordAllocation
30  * AllocateBlockOfAllocationList
31  * EnlargeMatrix
32  * ExpandTranslationArrays
33  */
34 
35 
36 /*
37  * Revision and copyright information.
38  *
39  * Copyright (c) 1985,86,87,88
40  * by Kenneth S. Kundert and the University of California.
41  *
42  * Permission to use, copy, modify, and distribute this software and
43  * its documentation for any purpose and without fee is hereby granted,
44  * provided that the copyright notices appear in all copies and
45  * supporting documentation and that the authors and the University of
46  * California are properly credited. The authors and the University of
47  * California make no representations as to the suitability of this
48  * software for any purpose. It is provided `as is', without express
49  * or implied warranty.
50  */
51 
52 #ifndef lint
53 static char copyright[] =
54  "Sparse1.3: Copyright (c) 1985,86,87,88 by Kenneth S. Kundert";
55 static char RCSid[] =
56  "@(#)$Header$";
57 #endif
58 
59 
60 
61 /*
62  * IMPORTS
63  *
64  * >>> Import descriptions:
65  * spconfig.h
66  * Macros that customize the sparse matrix routines.
67  * spmatrix.h
68  * Macros and declarations to be imported by the user.
69  * spdefs.h
70  * Matrix type and macro definitions for the sparse matrix routines.
71  */
72 
73 #define spINSIDE_SPARSE
74 #include "spconfig.h"
75 #include "spmatrix.h"
76 #include "spdefs.h"
77 
78 
79 /* avoid "declared implicitly `extern' and later `static' " warnings. */
81 static void RecordAllocation();
83 
84 ␌
85 /*
86  * MATRIX ALLOCATION
87  *
88  * Allocates and initializes the data structures associated with a matrix.
89  *
90  * >>> Returned:
91  * A pointer to the matrix is returned cast into the form of a pointer to
92  * a character. This pointer is then passed and used by the other matrix
93  * routines to refer to a particular matrix. If an error occurs, the NULL
94  * pointer is returned.
95  *
96  * >>> Arguments:
97  * Size <input> (int)
98  * Size of matrix or estimate of size of matrix if matrix is EXPANDABLE.
99  * Complex <input> (int)
100  * Type of matrix. If Complex is 0 then the matrix is real, otherwise
101  * the matrix will be complex. Note that if the routines are not set up
102  * to handle the type of matrix requested, then a spPANIC error will occur.
103  * Further note that if a matrix will be both real and complex, it must
104  * be specified here as being complex.
105  * pError <output> (int *)
106  * Returns error flag, needed because function spError() will not work
107  * correctly if spCreate() returns NULL.
108  *
109  * >>> Local variables:
110  * AllocatedSize (int)
111  * The size of the matrix being allocated.
112  * Matrix (MatrixPtr)
113  * A pointer to the matrix frame being created.
114  *
115  * >>> Possible errors:
116  * spNO_MEMORY
117  * spPANIC
118  * Error is cleared in this routine.
119  */
120 
121 char *
122 spCreate( int Size, BOOLEAN Complex, int* pError )
123 {
124 register unsigned SizePlusOne;
125 register MatrixPtr Matrix;
126 register int I;
127 int AllocatedSize;
128 
129 /* Begin `spCreate'. */
130 /* Clear error flag. */
131  *pError = spOKAY;
132 
133 /* Test for valid size. */
134  if ((Size < 0) OR (Size == 0 AND NOT EXPANDABLE))
135  { *pError = spPANIC;
136  return NULL;
137  }
138 
139 /* Test for valid type. */
140 #if NOT spCOMPLEX
141  if (Complex)
142  { *pError = spPANIC;
143  return NULL;
144  }
145 #endif
146 #if NOT REAL
147  if (NOT Complex)
148  { *pError = spPANIC;
149  return NULL;
150  }
151 #endif
152 
153 /* Create Matrix. */
154  AllocatedSize = MAX( Size, MINIMUM_ALLOCATED_SIZE );
155  SizePlusOne = (unsigned)(AllocatedSize + 1);
156 
157  if ((Matrix = ALLOC(struct MatrixFrame, 1)) == NULL)
158  { *pError = spNO_MEMORY;
159  return NULL;
160  }
161 
162 /* Initialize matrix */
163  Matrix->ID = SPARSE_ID;
164  Matrix->Complex = Complex;
165  Matrix->PreviousMatrixWasComplex = Complex;
166  Matrix->Factored = NO;
167  Matrix->Elements = 0;
168  Matrix->Error = *pError;
169  Matrix->Fillins = 0;
170  Matrix->Reordered = NO;
173  Matrix->Partitioned = NO;
174  Matrix->RowsLinked = NO;
176  Matrix->SingularCol = 0;
177  Matrix->SingularRow = 0;
178  Matrix->Size = Size;
179  Matrix->AllocatedSize = AllocatedSize;
180  Matrix->ExtSize = Size;
181  Matrix->AllocatedExtSize = AllocatedSize;
182  Matrix->CurrentSize = 0;
193  Matrix->RelThreshold = DEFAULT_THRESHOLD;
194  Matrix->AbsThreshold = 0.0;
195 
200 
201  RecordAllocation( Matrix, (char *)Matrix );
202  if (Matrix->Error == spNO_MEMORY) goto MemoryError;
203 
204 /* Take out the trash. */
205  Matrix->TrashCan.Real = 0.0;
206 #if spCOMPLEX
207  Matrix->TrashCan.Imag = 0.0;
208 #endif
209  Matrix->TrashCan.Row = 0;
210  Matrix->TrashCan.Col = 0;
213 #if INITIALIZE
214  Matrix->TrashCan.pInitInfo = NULL;
215 #endif
216 
217 /* Allocate space in memory for Diag pointer vector. */
218  CALLOC( Matrix->Diag, ElementPtr, SizePlusOne);
219  if (Matrix->Diag == NULL)
220  goto MemoryError;
221 
222 /* Allocate space in memory for FirstInCol pointer vector. */
223  CALLOC( Matrix->FirstInCol, ElementPtr, SizePlusOne);
224  if (Matrix->FirstInCol == NULL)
225  goto MemoryError;
226 
227 /* Allocate space in memory for FirstInRow pointer vector. */
228  CALLOC( Matrix->FirstInRow, ElementPtr, SizePlusOne);
229  if (Matrix->FirstInRow == NULL)
230  goto MemoryError;
231 
232 /* Allocate space in memory for IntToExtColMap vector. */
233  if (( Matrix->IntToExtColMap = ALLOC(int, SizePlusOne)) == NULL)
234  goto MemoryError;
235 
236 /* Allocate space in memory for IntToExtRowMap vector. */
237  if (( Matrix->IntToExtRowMap = ALLOC(int, SizePlusOne)) == NULL)
238  goto MemoryError;
239 
240 /* Initialize MapIntToExt vectors. */
241  for (I = 1; I <= AllocatedSize; I++)
242  { Matrix->IntToExtRowMap[I] = I;
243  Matrix->IntToExtColMap[I] = I;
244  }
245 
246 #if TRANSLATE
247 /* Allocate space in memory for ExtToIntColMap vector. */
248  if (( Matrix->ExtToIntColMap = ALLOC(int, SizePlusOne)) == NULL)
249  goto MemoryError;
250 
251 /* Allocate space in memory for ExtToIntRowMap vector. */
252  if (( Matrix->ExtToIntRowMap = ALLOC(int, SizePlusOne)) == NULL)
253  goto MemoryError;
254 
255 /* Initialize MapExtToInt vectors. */
256  for (I = 1; I <= AllocatedSize; I++)
257  { Matrix->ExtToIntColMap[I] = -1;
258  Matrix->ExtToIntRowMap[I] = -1;
259  }
260  Matrix->ExtToIntColMap[0] = 0;
261  Matrix->ExtToIntRowMap[0] = 0;
262 #endif
263 
264 /* Allocate space for fill-ins and initial set of elements. */
265  InitializeElementBlocks( Matrix, SPACE_FOR_ELEMENTS*AllocatedSize,
266  SPACE_FOR_FILL_INS*AllocatedSize );
267  if (Matrix->Error == spNO_MEMORY)
268  goto MemoryError;
269 
270  return (char *)Matrix;
271 
272 MemoryError:
273 
274 /* Deallocate matrix and return no pointer to matrix if there is not enough
275  memory. */
276  *pError = spNO_MEMORY;
277  spDestroy( (char *)Matrix);
278  return NULL;
279 }
280 
281 
282 
283 
284 
285 
286 
287 
288 ␌
289 /*
290  * ELEMENT ALLOCATION
291  *
292  * This routine allocates space for matrix elements. It requests large blocks
293  * of storage from the system and doles out individual elements as required.
294  * This technique, as opposed to allocating elements individually, tends to
295  * speed the allocation process.
296  *
297  * >>> Returned:
298  * A pointer to an element.
299  *
300  * >>> Arguments:
301  * Matrix <input> (MatrixPtr)
302  * Pointer to matrix.
303  *
304  * >>> Local variables:
305  * pElement (ElementPtr)
306  * A pointer to the first element in the group of elements being allocated.
307  *
308  * >>> Possible errors:
309  * spNO_MEMORY
310  */
311 
314 
316 {
318 
319 /* Begin `spcGetElement'. */
320 
321 /* Allocate block of MatrixElements if necessary. */
322  if (Matrix->ElementsRemaining == 0)
323  { pElement = ALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
324  RecordAllocation( Matrix, (char *)pElement );
325  if (Matrix->Error == spNO_MEMORY) return NULL;
326  Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION;
328  }
329 
330 /* Update Element counter and return pointer to Element. */
332  return Matrix->NextAvailElement++;
333 
334 }
335 
336 
337 
338 
339 
340 
341 
342 ␌
343 /*
344  * ELEMENT ALLOCATION INITIALIZATION
345  *
346  * This routine allocates space for matrix fill-ins and an initial set of
347  * elements. Besides being faster than allocating space for elements one
348  * at a time, it tends to keep the fill-ins physically close to the other
349  * matrix elements in the computer memory. This keeps virtual memory paging
350  * to a minimum.
351  *
352  * >>> Arguments:
353  * Matrix <input> (MatrixPtr)
354  * Pointer to the matrix.
355  * InitialNumberOfElements <input> (int)
356  * This number is used as the size of the block of memory, in
357  * MatrixElements, reserved for elements. If more than this number of
358  * elements are generated, then more space is allocated later.
359  * NumberOfFillinsExpected <input> (int)
360  * This number is used as the size of the block of memory, in
361  * MatrixElements, reserved for fill-ins. If more than this number of
362  * fill-ins are generated, then more space is allocated, but they may
363  * not be physically close in computer's memory.
364  *
365  * >>> Local variables:
366  * pElement (ElementPtr)
367  * A pointer to the first element in the group of elements being allocated.
368  *
369  * >>> Possible errors:
370  * spNO_MEMORY
371  */
372 
373 static
374 void InitializeElementBlocks( Matrix, InitialNumberOfElements,
375  NumberOfFillinsExpected )
376 
378 int InitialNumberOfElements, NumberOfFillinsExpected;
379 {
381 
382 /* Begin `InitializeElementBlocks'. */
383 
384 /* Allocate block of MatrixElements for elements. */
385  pElement = ALLOC(struct MatrixElement, InitialNumberOfElements);
386  RecordAllocation( Matrix, (char *)pElement );
387  if (Matrix->Error == spNO_MEMORY) return;
388  Matrix->ElementsRemaining = InitialNumberOfElements;
390 
391 /* Allocate block of MatrixElements for fill-ins. */
392  pElement = ALLOC(struct MatrixElement, NumberOfFillinsExpected);
393  RecordAllocation( Matrix, (char *)pElement );
394  if (Matrix->Error == spNO_MEMORY) return;
395  Matrix->FillinsRemaining = NumberOfFillinsExpected;
397 
398 /* Allocate a fill-in list structure. */
401  if (Matrix->Error == spNO_MEMORY) return;
403 
405  Matrix->FirstFillinListNode->NumberOfFillinsInList =NumberOfFillinsExpected;
407 
408  return;
409 }
410 
411 
412 
413 
414 
415 
416 
417 
418 
419 ␌
420 /*
421  * FILL-IN ALLOCATION
422  *
423  * This routine allocates space for matrix fill-ins. It requests large blocks
424  * of storage from the system and doles out individual elements as required.
425  * This technique, as opposed to allocating elements individually, tends to
426  * speed the allocation process.
427  *
428  * >>> Returned:
429  * A pointer to the fill-in.
430  *
431  * >>> Arguments:
432  * Matrix <input> (MatrixPtr)
433  * Pointer to matrix.
434  *
435  * >>> Possible errors:
436  * spNO_MEMORY
437  */
438 
441 
443 {
444 struct FillinListNodeStruct *pListNode;
445 ElementPtr pFillins;
446 
447 /* Begin `spcGetFillin'. */
448 
449 #if NOT STRIP OR LINT
450  if (Matrix->FillinsRemaining == 0)
451  return spcGetElement( Matrix );
452 #endif
453 #if STRIP OR LINT
454 
455  if (Matrix->FillinsRemaining == 0)
456  { pListNode = Matrix->LastFillinListNode;
457 
458 /* First see if there are any stripped fill-ins left. */
459  if (pListNode->Next != NULL)
460  { Matrix->LastFillinListNode = pListNode = pListNode->Next;
462  Matrix->NextAvailFillin = pListNode->pFillinList;
463  }
464  else
465  {
466 /* Allocate block of fill-ins. */
467  pFillins = ALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
468  RecordAllocation( Matrix, (char *)pFillins );
469  if (Matrix->Error == spNO_MEMORY) return NULL;
470  Matrix->FillinsRemaining = ELEMENTS_PER_ALLOCATION;
471  Matrix->NextAvailFillin = pFillins;
472 
473 /* Allocate a fill-in list structure. */
474  pListNode->Next = ALLOC(struct FillinListNodeStruct,1);
475  RecordAllocation( Matrix, (char *)pListNode->Next );
476  if (Matrix->Error == spNO_MEMORY) return NULL;
477  Matrix->LastFillinListNode = pListNode = pListNode->Next;
478 
479  pListNode->pFillinList = pFillins;
480  pListNode->NumberOfFillinsInList = ELEMENTS_PER_ALLOCATION;
481  pListNode->Next = NULL;
482  }
483  }
484 #endif
485 
486 /* Update Fill-in counter and return pointer to Fill-in. */
488  return Matrix->NextAvailFillin++;
489 }
490 
491 
492 
493 
494 
495 
496 
497 
498 ␌
499 /*
500  * RECORD A MEMORY ALLOCATION
501  *
502  * This routine is used to record all memory allocations so that the memory
503  * can be freed later.
504  *
505  * >>> Arguments:
506  * Matrix <input> (MatrixPtr)
507  * Pointer to the matrix.
508  * AllocatedPtr <input> (char *)
509  * The pointer returned by malloc or calloc. These pointers are saved in
510  * a list so that they can be easily freed.
511  *
512  * >>> Possible errors:
513  * spNO_MEMORY
514  */
515 
516 static
517 void RecordAllocation( Matrix, AllocatedPtr )
518 
520 char *AllocatedPtr;
521 {
522 /* Begin `RecordAllocation'. */
523 /*
524  * If Allocated pointer is NULL, assume that malloc returned a NULL pointer,
525  * which indicates a spNO_MEMORY error.
526  */
527  if (AllocatedPtr == NULL)
528  { Matrix->Error = spNO_MEMORY;
529  return;
530  }
531 
532 /* Allocate block of MatrixElements if necessary. */
533  if (Matrix->RecordsRemaining == 0)
535  if (Matrix->Error == spNO_MEMORY)
536  { FREE(AllocatedPtr);
537  return;
538  }
539  }
540 
541 /* Add Allocated pointer to Allocation List. */
542  (++Matrix->TopOfAllocationList)->AllocatedPtr = AllocatedPtr;
544  return;
545 
546 }
547 
548 
549 
550 
551 
552 
553 
554 ␌
555 /*
556  * ADD A BLOCK OF SLOTS TO ALLOCATION LIST
557  *
558  * This routine increases the size of the allocation list.
559  *
560  * >>> Arguments:
561  * Matrix <input> (MatrixPtr)
562  * Pointer to the matrix.
563  *
564  * >>> Local variables:
565  * ListPtr (AllocationListPtr)
566  * Pointer to the list that contains the pointers to segments of memory
567  * that were allocated by the operating system for the current matrix.
568  *
569  * >>> Possible errors:
570  * spNO_MEMORY
571  */
572 
573 static
575 
577 {
578 register int I;
579 register AllocationListPtr ListPtr;
580 
581 /* Begin `AllocateBlockOfAllocationList'. */
582 /* Allocate block of records for allocation list. */
583  ListPtr = ALLOC(struct AllocationRecord, (ELEMENTS_PER_ALLOCATION+1));
584  if (ListPtr == NULL)
585  { Matrix->Error = spNO_MEMORY;
586  return;
587  }
588 
589 /* String entries of allocation list into singly linked list. List is linked
590  such that any record points to the one before it. */
591 
593  Matrix->TopOfAllocationList = ListPtr;
594  ListPtr += ELEMENTS_PER_ALLOCATION;
595  for (I = ELEMENTS_PER_ALLOCATION; I > 0; I--)
596  { ListPtr->NextRecord = ListPtr - 1;
597  ListPtr--;
598  }
599 
600 /* Record allocation of space for allocation list on allocation list. */
601  Matrix->TopOfAllocationList->AllocatedPtr = (char *)ListPtr;
602  Matrix->RecordsRemaining = ELEMENTS_PER_ALLOCATION;
603 
604  return;
605 }
606 
607 
608 
609 
610 
611 
612 
613 ␌
614 /*
615  * MATRIX DEALLOCATION
616  *
617  * Deallocates pointers and elements of Matrix.
618  *
619  * >>> Arguments:
620  * Matrix <input> (char *)
621  * Pointer to the matrix frame which is to be removed from memory.
622  *
623  * >>> Local variables:
624  * ListPtr (AllocationListPtr)
625  * Pointer into the linked list of pointers to allocated data structures.
626  * Points to pointer to structure to be freed.
627  * NextListPtr (AllocationListPtr)
628  * Pointer into the linked list of pointers to allocated data structures.
629  * Points to the next pointer to structure to be freed. This is needed
630  * because the data structure to be freed could include the current node
631  * in the allocation list.
632  */
633 
634 void
635 spDestroy( eMatrix )
636 
637 register char *eMatrix;
638 {
639 MatrixPtr Matrix = (MatrixPtr)eMatrix;
640 register AllocationListPtr ListPtr, NextListPtr;
641 
642 
643 /* Begin `spDestroy'. */
644  ASSERT( IS_SPARSE( Matrix ) );
645 
646 /* Deallocate the vectors that are located in the matrix frame. */
651  FREE( Matrix->Diag );
652  FREE( Matrix->FirstInRow );
653  FREE( Matrix->FirstInCol );
660 
661 /* Sequentially step through the list of allocated pointers freeing pointers
662  * along the way. */
663  ListPtr = Matrix->TopOfAllocationList;
664  while (ListPtr != NULL)
665  { NextListPtr = ListPtr->NextRecord;
666  FREE( ListPtr->AllocatedPtr );
667  ListPtr = NextListPtr;
668  }
669  return;
670 }
671 
672 
673 
674 
675 
676 
677 ␌
678 /*
679  * RETURN MATRIX ERROR STATUS
680  *
681  * This function is used to determine the error status of the given matrix.
682  *
683  * >>> Returned:
684  * The error status of the given matrix.
685  *
686  * >>> Arguments:
687  * eMatrix <input> (char *)
688  * The matrix for which the error status is desired.
689  */
690 
691 int
692 spError( eMatrix )
693 
694 char *eMatrix;
695 {
696 /* Begin `spError'. */
697 
698  if (eMatrix != NULL)
699  { ASSERT(((MatrixPtr)eMatrix)->ID == SPARSE_ID);
700  return ((MatrixPtr)eMatrix)->Error;
701  }
702  else return spNO_MEMORY; /* This error may actually be spPANIC,
703  * no way to tell. */
704 }
705 
706 
707 
708 
709 
710 
711 
712 
713 ␌
714 /*
715  * WHERE IS MATRIX SINGULAR
716  *
717  * This function returns the row and column number where the matrix was
718  * detected as singular or where a zero was detected on the diagonal.
719  *
720  * >>> Arguments:
721  * eMatrix <input> (char *)
722  * The matrix for which the error status is desired.
723  * pRow <output> (int *)
724  * The row number.
725  * pCol <output> (int *)
726  * The column number.
727  */
728 
729 void
730 spWhereSingular( eMatrix, pRow, pCol )
731 
732 char *eMatrix;
733 int *pRow, *pCol;
734 {
735 MatrixPtr Matrix = (MatrixPtr)eMatrix;
736 
737 /* Begin `spWhereSingular'. */
738  ASSERT( IS_SPARSE( Matrix ) );
739 
741  { *pRow = Matrix->SingularRow;
742  *pCol = Matrix->SingularCol;
743  }
744  else *pRow = *pCol = 0;
745  return;
746 }
747 
748 
749 
750 
751 
752 ␌
753 /*
754  * MATRIX SIZE
755  *
756  * Returns the size of the matrix. Either the internal or external size of
757  * the matrix is returned.
758  *
759  * >>> Arguments:
760  * eMatrix <input> (char *)
761  * Pointer to matrix.
762  * External <input> (BOOLEAN)
763  * If External is set true, the external size , i.e., the value of the
764  * largest external row or column number encountered is returned.
765  * Otherwise the true size of the matrix is returned. These two sizes
766  * may differ if the TRANSLATE option is set true.
767  */
768 
769 int
770 spGetSize( eMatrix, External )
771 
772 char *eMatrix;
773 BOOLEAN External;
774 {
775 MatrixPtr Matrix = (MatrixPtr)eMatrix;
776 
777 /* Begin `spGetSize'. */
778  ASSERT( IS_SPARSE( Matrix ) );
779 
780 #if TRANSLATE
781  if (External)
782  return Matrix->ExtSize;
783  else
784  return Matrix->Size;
785 #else
786  return Matrix->Size;
787 #endif
788 }
789 
790 
791 
792 
793 
794 
795 
796 ␌
797 /*
798  * SET MATRIX COMPLEX OR REAL
799  *
800  * Forces matrix to be either real or complex.
801  *
802  * >>> Arguments:
803  * eMatrix <input> (char *)
804  * Pointer to matrix.
805  */
806 
807 void
808 spSetReal( eMatrix )
809 
810 char *eMatrix;
811 {
812 /* Begin `spSetReal'. */
813 
814  ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) AND REAL);
815  ((MatrixPtr)eMatrix)->Complex = NO;
816  return;
817 }
818 
819 
820 void
821 spSetComplex( eMatrix )
822 
823 char *eMatrix;
824 {
825 /* Begin `spSetComplex'. */
826 
827  ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) AND spCOMPLEX);
828  ((MatrixPtr)eMatrix)->Complex = YES;
829  return;
830 }
831 
832 
833 
834 
835 
836 
837 
838 
839 ␌
840 /*
841  * ELEMENT OR FILL-IN COUNT
842  *
843  * Two functions used to return simple statistics. Either the number
844  * of total elements, or the number of fill-ins can be returned.
845  *
846  * >>> Arguments:
847  * eMatrix <input> (char *)
848  * Pointer to matrix.
849  */
850 
851 int
852 spFillinCount( eMatrix )
853 
854 char *eMatrix;
855 {
856 /* Begin `spFillinCount'. */
857 
858  ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) );
859  return ((MatrixPtr)eMatrix)->Fillins;
860 }
861 
862 
863 int
864 spElementCount( eMatrix )
865 
866 char *eMatrix;
867 {
868 /* Begin `spElementCount'. */
869 
870  ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) );
871  return ((MatrixPtr)eMatrix)->Elements;
872 }
#define MAX(a, b)
Definition: grids.h:35
#define REAL
Definition: machine.h:191
static char RCSid[]
Definition: spalloc.c:55
int spGetSize(char *eMatrix, BOOLEAN External)
Definition: spalloc.c:770
static void AllocateBlockOfAllocationList()
void spWhereSingular(char *eMatrix, int *pRow, int *pCol)
Definition: spalloc.c:730
ElementPtr spcGetFillin(MatrixPtr Matrix)
Definition: spalloc.c:440
ElementPtr spcGetElement(MatrixPtr Matrix)
Definition: spalloc.c:313
void spSetComplex(char *eMatrix)
Definition: spalloc.c:821
char * spCreate(int Size, BOOLEAN Complex, int *pError)
Definition: spalloc.c:122
void spDestroy(char *eMatrix)
Definition: spalloc.c:635
static void RecordAllocation()
void spSetReal(char *eMatrix)
Definition: spalloc.c:808
int spElementCount(char *eMatrix)
Definition: spalloc.c:864
static char copyright[]
Definition: spalloc.c:53
static void InitializeElementBlocks()
int spFillinCount(char *eMatrix)
Definition: spalloc.c:852
int spError(char *eMatrix)
Definition: spalloc.c:692
#define spCOMPLEX
Definition: spconfig.h:285
#define FREE(ptr)
Definition: spdefs.h:446
#define SPARSE_ID
Definition: spdefs.h:119
#define ALLOC(type, number)
Definition: spdefs.h:442
#define OR
Definition: spdefs.h:112
#define BOOLEAN
Definition: spdefs.h:107
struct MatrixFrame * MatrixPtr
Definition: spdefs.h:880
#define YES
Definition: spdefs.h:109
#define CALLOC(ptr, type, number)
Definition: spdefs.h:450
#define NO
Definition: spdefs.h:108
#define ASSERT(condition)
Definition: spdefs.h:383
#define AND
Definition: spdefs.h:111
#define NOT
Definition: spdefs.h:110
#define IS_SPARSE(matrix)
Definition: spdefs.h:120
#define spNO_MEMORY
Definition: spmatrix.h:101
#define spZERO_DIAG
Definition: spmatrix.h:99
#define spPANIC
Definition: spmatrix.h:102
#define spSINGULAR
Definition: spmatrix.h:100
#define spOKAY
Definition: spmatrix.h:97
register int Size
Definition: spoutput.c:572
register int I
Definition: spoutput.c:570
register ElementPtr pElement
Definition: spsolve.c:139
#define NULL
Definition: sptree.h:16
MatrixPtr Matrix
Definition: sputils.c:601
char * AllocatedPtr
Definition: spdefs.h:590
struct AllocationRecord * NextRecord
Definition: spdefs.h:591
int NumberOfFillinsInList
Definition: spdefs.h:626
ElementPtr pFillinList
Definition: spdefs.h:625
struct FillinListNodeStruct * Next
Definition: spdefs.h:627
RealNumber Real
Definition: spdefs.h:549
struct MatrixElement * NextInCol
Definition: spdefs.h:556
struct MatrixElement * NextInRow
Definition: spdefs.h:555
int SingularCol
Definition: spdefs.h:865
BOOLEAN Partitioned
Definition: spdefs.h:857
int ExtSize
Definition: spdefs.h:839
int SingularRow
Definition: spdefs.h:866
int * IntToExtRowMap
Definition: spdefs.h:850
BOOLEAN * DoRealDirect
Definition: spdefs.h:836
BOOLEAN Complex
Definition: spdefs.h:832
ElementPtr NextAvailFillin
Definition: spdefs.h:875
BOOLEAN InternalVectorsAllocated
Definition: spdefs.h:848
int Fillins
Definition: spdefs.h:843
BOOLEAN PreviousMatrixWasComplex
Definition: spdefs.h:861
struct FillinListNodeStruct * FirstFillinListNode
Definition: spdefs.h:877
BOOLEAN NumberOfInterchangesIsOdd
Definition: spdefs.h:856
struct FillinListNodeStruct * LastFillinListNode
Definition: spdefs.h:878
int AllocatedSize
Definition: spdefs.h:830
BOOLEAN * DoCmplxDirect
Definition: spdefs.h:835
ArrayOfElementPtrs FirstInCol
Definition: spdefs.h:844
RealNumber AbsThreshold
Definition: spdefs.h:829
int ElementsRemaining
Definition: spdefs.h:874
int Elements
Definition: spdefs.h:837
int CurrentSize
Definition: spdefs.h:833
int AllocatedExtSize
Definition: spdefs.h:831
int * ExtToIntColMap
Definition: spdefs.h:840
BOOLEAN RowsLinked
Definition: spdefs.h:864
int * IntToExtColMap
Definition: spdefs.h:849
ArrayOfElementPtrs FirstInRow
Definition: spdefs.h:845
BOOLEAN Factored
Definition: spdefs.h:842
long * MarkowitzProd
Definition: spdefs.h:853
int Error
Definition: spdefs.h:838
RealNumber RelThreshold
Definition: spdefs.h:862
unsigned long ID
Definition: spdefs.h:846
int FillinsRemaining
Definition: spdefs.h:876
AllocationListPtr TopOfAllocationList
Definition: spdefs.h:871
BOOLEAN NeedsOrdering
Definition: spdefs.h:855
ElementPtr NextAvailElement
Definition: spdefs.h:873
int Size
Definition: spdefs.h:868
int RecordsRemaining
Definition: spdefs.h:872
int * ExtToIntRowMap
Definition: spdefs.h:841
int * MarkowitzRow
Definition: spdefs.h:851
ArrayOfElementPtrs Diag
Definition: spdefs.h:834
RealVector Intermediate
Definition: spdefs.h:847
int * MarkowitzCol
Definition: spdefs.h:852
BOOLEAN Reordered
Definition: spdefs.h:863
struct MatrixElement TrashCan
Definition: spdefs.h:869