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