/* * DATA STRUCTURE AND MACRO DEFINITIONS for Sparse. * * Author: Advising professor: * Kenneth S. Kundert Alberto Sangiovanni-Vincentelli * UC Berkeley * * This file contains common type definitions and macros for the sparse * matrix routines. These definitions are of no interest to the user. */ /* * Revision and copyright information. * * Copyright (c) 1985,86,87,88 * by Kenneth S. Kundert and the University of California. * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby granted, * provided that the copyright notices appear in all copies and * supporting documentation and that the authors and the University of * California are properly credited. The authors and the University of * California make no representations as to the suitability of this * software for any purpose. It is provided `as is', without express * or implied warranty. * * $Date: 88/06/18 11:13:40 $ * $Revision: 1.2 $ */ /* * IMPORTS */ #include /* * If running lint, change some of the compiler options to get a more * complete inspection. */ #ifdef lint #undef REAL #undef spCOMPLEX #undef EXPANDABLE #undef TRANSLATE #undef INITIALIZE #undef DELETE #undef STRIP #undef MODIFIED_NODAL #undef QUAD_ELEMENT #undef TRANSPOSE #undef SCALING #undef DOCUMENTATION #undef MULTIPLICATION #undef DETERMINANT #undef CONDITION #undef PSEUDOCONDITION #undef FORTRAN #undef DEBUG #define REAL YES #define spCOMPLEX YES #define EXPANDABLE YES #define TRANSLATE YES #define INITIALIZE YES #define DELETE YES #define STRIP YES #define MODIFIED_NODAL YES #define QUAD_ELEMENT YES #define TRANSPOSE YES #define SCALING YES #define DOCUMENTATION YES #define MULTIPLICATION YES #define DETERMINANT YES #define CONDITION YES #define PSEUDOCONDITION YES #define FORTRAN YES #define DEBUG YES #define LINT YES #else /* not lint */ #define LINT NO #endif /* not lint */ /* * MACRO DEFINITIONS * * Macros are distinguished by using solely capital letters in their * identifiers. This contrasts with C defined identifiers which are strictly * lower case, and program variable and procedure names which use both upper * and lower case. */ /* Begin macros. */ /* Boolean data type */ #define BOOLEAN int #define NO 0 #define YES 1 #define NOT ! #define AND && #define OR || /* NULL pointer */ #ifndef NULL #define NULL 0 #endif #define SPARSE_ID 0x772773 /* Arbitrary (is Sparse on phone). */ #define IS_SPARSE(matrix) ((matrix) != NULL && \ (matrix)->ID == SPARSE_ID) #define IS_VALID(matrix) ((matrix) != NULL && \ (matrix)->ID == SPARSE_ID && \ (matrix)->Error >= spOKAY && \ (matrix)->Error < spFATAL) #define IS_FACTORED(matrix) ((matrix)->Factored && !(matrix)->NeedsOrdering) /* Macro commands */ /* Macro functions that return the maximum or minimum independent of type. */ #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) /* Macro function that returns the absolute value of a floating point number. */ #define ABS(a) ((a) < 0.0 ? -(a) : (a)) /* Macro function that returns the square of a number. */ #define SQR(a) ((a)*(a)) /* Macro procedure that swaps two entities. */ #define SWAP(type, a, b) {type swapx; swapx = a; a = b; b = swapx;} /* Macro function that returns the approx absolute value of a complex number. */ #if spCOMPLEX #define ELEMENT_MAG(ptr) (ABS((ptr)->Real) + ABS((ptr)->Imag)) #else #define ELEMENT_MAG(ptr) ((ptr)->Real < 0.0 ? -(ptr)->Real : (ptr)->Real) #endif /* Complex assignment statements. */ #define CMPLX_ASSIGN(to,from) \ { (to).Real = (from).Real; \ (to).Imag = (from).Imag; \ } #define CMPLX_CONJ_ASSIGN(to,from) \ { (to).Real = (from).Real; \ (to).Imag = -(from).Imag; \ } #define CMPLX_NEGATE_ASSIGN(to,from) \ { (to).Real = -(from).Real; \ (to).Imag = -(from).Imag; \ } #define CMPLX_CONJ_NEGATE_ASSIGN(to,from) \ { (to).Real = -(from).Real; \ (to).Imag = (from).Imag; \ } #define CMPLX_CONJ(a) (a).Imag = -(a).Imag #define CMPLX_NEGATE(a) \ { (a).Real = -(a).Real; \ (a).Imag = -(a).Imag; \ } /* Macro that returns the approx magnitude (L-1 norm) of a complex number. */ #define CMPLX_1_NORM(a) (ABS((a).Real) + ABS((a).Imag)) /* Macro that returns the approx magnitude (L-infinity norm) of a complex. */ #define CMPLX_INF_NORM(a) (MAX (ABS((a).Real),ABS((a).Imag))) /* Macro function that returns the magnitude (L-2 norm) of a complex number. */ #define CMPLX_2_NORM(a) (sqrt((a).Real*(a).Real + (a).Imag*(a).Imag)) /* Macro function that performs complex addition. */ #define CMPLX_ADD(to,from_a,from_b) \ { (to).Real = (from_a).Real + (from_b).Real; \ (to).Imag = (from_a).Imag + (from_b).Imag; \ } /* Macro function that performs complex subtraction. */ #define CMPLX_SUBT(to,from_a,from_b) \ { (to).Real = (from_a).Real - (from_b).Real; \ (to).Imag = (from_a).Imag - (from_b).Imag; \ } /* Macro function that is equivalent to += operator for complex numbers. */ #define CMPLX_ADD_ASSIGN(to,from) \ { (to).Real += (from).Real; \ (to).Imag += (from).Imag; \ } /* Macro function that is equivalent to -= operator for complex numbers. */ #define CMPLX_SUBT_ASSIGN(to,from) \ { (to).Real -= (from).Real; \ (to).Imag -= (from).Imag; \ } /* Macro function that multiplies a complex number by a scalar. */ #define SCLR_MULT(to,sclr,cmplx) \ { (to).Real = (sclr) * (cmplx).Real; \ (to).Imag = (sclr) * (cmplx).Imag; \ } /* Macro function that multiply-assigns a complex number by a scalar. */ #define SCLR_MULT_ASSIGN(to,sclr) \ { (to).Real *= (sclr); \ (to).Imag *= (sclr); \ } /* Macro function that multiplies two complex numbers. */ #define CMPLX_MULT(to,from_a,from_b) \ { (to).Real = (from_a).Real * (from_b).Real - \ (from_a).Imag * (from_b).Imag; \ (to).Imag = (from_a).Real * (from_b).Imag + \ (from_a).Imag * (from_b).Real; \ } /* Macro function that implements to *= from for complex numbers. */ #define CMPLX_MULT_ASSIGN(to,from) \ { RealNumber to_real_ = (to).Real; \ (to).Real = to_real_ * (from).Real - \ (to).Imag * (from).Imag; \ (to).Imag = to_real_ * (from).Imag + \ (to).Imag * (from).Real; \ } /* Macro function that multiplies two complex numbers, the first of which is * conjugated. */ #define CMPLX_CONJ_MULT(to,from_a,from_b) \ { (to).Real = (from_a).Real * (from_b).Real + \ (from_a).Imag * (from_b).Imag; \ (to).Imag = (from_a).Real * (from_b).Imag - \ (from_a).Imag * (from_b).Real; \ } /* Macro function that multiplies two complex numbers and then adds them * to another. to = add + mult_a * mult_b */ #define CMPLX_MULT_ADD(to,mult_a,mult_b,add) \ { (to).Real = (mult_a).Real * (mult_b).Real - \ (mult_a).Imag * (mult_b).Imag + (add).Real; \ (to).Imag = (mult_a).Real * (mult_b).Imag + \ (mult_a).Imag * (mult_b).Real + (add).Imag; \ } /* Macro function that subtracts the product of two complex numbers from * another. to = subt - mult_a * mult_b */ #define CMPLX_MULT_SUBT(to,mult_a,mult_b,subt) \ { (to).Real = (subt).Real - (mult_a).Real * (mult_b).Real + \ (mult_a).Imag * (mult_b).Imag; \ (to).Imag = (subt).Imag - (mult_a).Real * (mult_b).Imag - \ (mult_a).Imag * (mult_b).Real; \ } /* Macro function that multiplies two complex numbers and then adds them * to another. to = add + mult_a* * mult_b where mult_a* represents mult_a * conjugate. */ #define CMPLX_CONJ_MULT_ADD(to,mult_a,mult_b,add) \ { (to).Real = (mult_a).Real * (mult_b).Real + \ (mult_a).Imag * (mult_b).Imag + (add).Real; \ (to).Imag = (mult_a).Real * (mult_b).Imag - \ (mult_a).Imag * (mult_b).Real + (add).Imag; \ } /* Macro function that multiplies two complex numbers and then adds them * to another. to += mult_a * mult_b */ #define CMPLX_MULT_ADD_ASSIGN(to,from_a,from_b) \ { (to).Real += (from_a).Real * (from_b).Real - \ (from_a).Imag * (from_b).Imag; \ (to).Imag += (from_a).Real * (from_b).Imag + \ (from_a).Imag * (from_b).Real; \ } /* Macro function that multiplies two complex numbers and then subtracts them * from another. */ #define CMPLX_MULT_SUBT_ASSIGN(to,from_a,from_b) \ { (to).Real -= (from_a).Real * (from_b).Real - \ (from_a).Imag * (from_b).Imag; \ (to).Imag -= (from_a).Real * (from_b).Imag + \ (from_a).Imag * (from_b).Real; \ } /* Macro function that multiplies two complex numbers and then adds them * to the destination. to += from_a* * from_b where from_a* represents from_a * conjugate. */ #define CMPLX_CONJ_MULT_ADD_ASSIGN(to,from_a,from_b) \ { (to).Real += (from_a).Real * (from_b).Real + \ (from_a).Imag * (from_b).Imag; \ (to).Imag += (from_a).Real * (from_b).Imag - \ (from_a).Imag * (from_b).Real; \ } /* Macro function that multiplies two complex numbers and then subtracts them * from the destination. to -= from_a* * from_b where from_a* represents from_a * conjugate. */ #define CMPLX_CONJ_MULT_SUBT_ASSIGN(to,from_a,from_b) \ { (to).Real -= (from_a).Real * (from_b).Real + \ (from_a).Imag * (from_b).Imag; \ (to).Imag -= (from_a).Real * (from_b).Imag - \ (from_a).Imag * (from_b).Real; \ } /* * Macro functions that provide complex division. */ /* Complex division: to = num / den */ #define CMPLX_DIV(to,num,den) \ { RealNumber r_, s_; \ if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \ ((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \ { r_ = (den).Imag / (den).Real; \ s_ = (den).Real + r_*(den).Imag; \ (to).Real = ((num).Real + r_*(num).Imag)/s_; \ (to).Imag = ((num).Imag - r_*(num).Real)/s_; \ } \ else \ { r_ = (den).Real / (den).Imag; \ s_ = (den).Imag + r_*(den).Real; \ (to).Real = (r_*(num).Real + (num).Imag)/s_; \ (to).Imag = (r_*(num).Imag - (num).Real)/s_; \ } \ } /* Complex division and assignment: num /= den */ #define CMPLX_DIV_ASSIGN(num,den) \ { RealNumber r_, s_, t_; \ if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \ ((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \ { r_ = (den).Imag / (den).Real; \ s_ = (den).Real + r_*(den).Imag; \ t_ = ((num).Real + r_*(num).Imag)/s_; \ (num).Imag = ((num).Imag - r_*(num).Real)/s_; \ (num).Real = t_; \ } \ else \ { r_ = (den).Real / (den).Imag; \ s_ = (den).Imag + r_*(den).Real; \ t_ = (r_*(num).Real + (num).Imag)/s_; \ (num).Imag = (r_*(num).Imag - (num).Real)/s_; \ (num).Real = t_; \ } \ } /* Complex reciprocation: to = 1.0 / den */ #define CMPLX_RECIPROCAL(to,den) \ { RealNumber r_; \ if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \ ((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \ { r_ = (den).Imag / (den).Real; \ (to).Imag = -r_*((to).Real = 1.0/((den).Real + r_*(den).Imag)); \ } \ else \ { r_ = (den).Real / (den).Imag; \ (to).Real = -r_*((to).Imag = -1.0/((den).Imag + r_*(den).Real));\ } \ } /* * ASSERT and ABORT * * Macro used to assert that if the code is working correctly, then * a condition must be true. If not, then execution is terminated * and an error message is issued stating that there is an internal * error and giving the file and line number. These assertions are * not evaluated unless the DEBUG flag is true. */ #if DEBUG #define ASSERT(condition) if (NOT(condition)) ABORT() #else #define ASSERT(condition) #endif #if DEBUG #define ABORT() \ { (void)fflush(stdout); \ (void)fprintf(stderr, "sparse: panic in file `%s' at line %d.\n", \ __FILE__, __LINE__); \ (void)fflush(stderr); \ abort(); \ } #else #define ABORT() #endif /* * IMAGINARY VECTORS * * The imaginary vectors iRHS and iSolution are only needed when the * options spCOMPLEX and spSEPARATED_COMPLEX_VECTORS are set. The following * macro makes it easy to include or exclude these vectors as needed. */ #if spCOMPLEX AND spSEPARATED_COMPLEX_VECTORS #define IMAG_VECTORS , iRHS, iSolution #define IMAG_RHS , iRHS #else #define IMAG_VECTORS #define IMAG_RHS #endif /* * MEMORY ALLOCATION */ extern char *malloc(), *calloc(), *realloc(); #ifdef ultrix extern void free(); extern void abort(); #else extern free(); extern abort(); #endif #define ALLOC(type,number) ((type *)malloc((unsigned)(sizeof(type)*(number)))) #define REALLOC(ptr,type,number) \ ptr = (type *)realloc((char *)ptr,(unsigned)(sizeof(type)*(number))) #define FREE(ptr) { if ((ptr) != NULL) free((char *)(ptr)); (ptr) = NULL; } /* Calloc that properly handles allocating a cleared vector. */ #define CALLOC(ptr,type,number) \ { int i; ptr = ALLOC(type, number); \ if (ptr != (type *)NULL) \ for(i=(number)-1;i>=0; i--) ptr[i] = (type) 0; \ } /* * REAL NUMBER */ /* Begin `RealNumber'. */ typedef spREAL RealNumber, *RealVector; /* * COMPLEX NUMBER DATA STRUCTURE * * >>> Structure fields: * Real (RealNumber) * The real portion of the number. Real must be the first * field in this structure. * Imag (RealNumber) * The imaginary portion of the number. This field must follow * immediately after Real. */ /* Begin `ComplexNumber'. */ typedef struct { RealNumber Real; RealNumber Imag; } ComplexNumber, *ComplexVector; /* * MATRIX ELEMENT DATA STRUCTURE * * Every nonzero element in the matrix is stored in a dynamically allocated * MatrixElement structure. These structures are linked together in an * orthogonal linked list. Two different MatrixElement structures exist. * One is used when only real matrices are expected, it is missing an entry * for imaginary data. The other is used if complex matrices are expected. * It contains an entry for imaginary data. * * >>> Structure fields: * Real (RealNumber) * The real portion of the value of the element. Real must be the first * field in this structure. * Imag (RealNumber) * The imaginary portion of the value of the element. If the matrix * routines are not compiled to handle complex matrices, then this * field does not exist. If it exists, it must follow immediately after * Real. * Row (int) * The row number of the element. * Col (int) * The column number of the element. * NextInRow (struct MatrixElement *) * NextInRow contains a pointer to the next element in the row to the * right of this element. If this element is the last nonzero in the * row then NextInRow contains NULL. * NextInCol (struct MatrixElement *) * NextInCol contains a pointer to the next element in the column below * this element. If this element is the last nonzero in the column then * NextInCol contains NULL. * pInitInfo (char *) * Pointer to user data used for initialization of the matrix element. * Initialized to NULL. * * >>> Type definitions: * ElementPtr * A pointer to a MatrixElement. * ArrayOfElementPtrs * An array of ElementPtrs. Used for FirstInRow, FirstInCol and * Diag pointer arrays. */ /* Begin `MatrixElement'. */ struct MatrixElement { RealNumber Real; #if spCOMPLEX RealNumber Imag; #endif int Row; int Col; struct MatrixElement *NextInRow; struct MatrixElement *NextInCol; #if INITIALIZE char *pInitInfo; #endif }; typedef struct MatrixElement *ElementPtr; typedef ElementPtr *ArrayOfElementPtrs; /* * ALLOCATION DATA STRUCTURE * * The sparse matrix routines keep track of all memory that is allocated by * the operating system so the memory can later be freed. This is done by * saving the pointers to all the chunks of memory that are allocated to a * particular matrix in an allocation list. That list is organized as a * linked list so that it can grow without a priori bounds. * * >>> Structure fields: * AllocatedPtr (char *) * Pointer to chunk of memory that has been allocated for the matrix. * NextRecord (struct AllocationRecord *) * Pointer to the next allocation record. */ /* Begin `AllocationRecord'. */ struct AllocationRecord { char *AllocatedPtr; struct AllocationRecord *NextRecord; }; typedef struct AllocationRecord *AllocationListPtr; /* * FILL-IN LIST DATA STRUCTURE * * The sparse matrix routines keep track of all fill-ins separately from * user specified elements so they may be removed by spStripFills(). Fill-ins * are allocated in bunched in what is called a fill-in lists. The data * structure defined below is used to organize these fill-in lists into a * linked-list. * * >>> Structure fields: * pFillinList (ElementPtr) * Pointer to a fill-in list, or a bunch of fill-ins arranged contiguously * in memory. * NumberOfFillinsInList (int) * Seems pretty self explanatory to me. * Next (struct FillinListNodeStruct *) * Pointer to the next fill-in list structures. */ /* Begin `FillinListNodeStruct'. */ struct FillinListNodeStruct { ElementPtr pFillinList; int NumberOfFillinsInList; struct FillinListNodeStruct *Next; }; /* * MATRIX FRAME DATA STRUCTURE * * This structure contains all the pointers that support the orthogonal * linked list that contains the matrix elements. Also included in this * structure are other numbers and pointers that are used globally by the * sparse matrix routines and are associated with one particular matrix. * * >>> Type definitions: * MatrixPtr * A pointer to MatrixFrame. Essentially, a pointer to the matrix. * * >>> Structure fields: * AbsThreshold (RealNumber) * The absolute magnitude an element must have to be considered as a * pivot candidate, except as a last resort. * AllocatedExtSize (int) * The allocated size of the arrays used to translate external row and * column numbers to their internal values. * AllocatedSize (int) * The currently allocated size of the matrix; the size the matrix can * grow to when EXPANDABLE is set true and AllocatedSize is the largest * the matrix can get without requiring that the matrix frame be * reallocated. * Complex (BOOLEAN) * The flag which indicates whether the matrix is complex (true) or * real. * CurrentSize (int) * This number is used during the building of the matrix when the * TRANSLATE option is set true. It indicates the number of internal * rows and columns that have elements in them. * Diag (ArrayOfElementPtrs) * Array of pointers that points to the diagonal elements. * DoCmplxDirect (BOOLEAN *) * Array of flags, one for each column in matrix. If a flag is true * then corresponding column in a complex matrix should be eliminated * in spFactor() using direct addressing (rather than indirect * addressing). * DoRealDirect (BOOLEAN *) * Array of flags, one for each column in matrix. If a flag is true * then corresponding column in a real matrix should be eliminated * in spFactor() using direct addressing (rather than indirect * addressing). * Elements (int) * The number of original elements (total elements minus fill ins) * present in matrix. * Error (int) * The error status of the sparse matrix package. * ExtSize (int) * The value of the largest external row or column number encountered. * ExtToIntColMap (int []) * An array that is used to convert external columns number to internal * external column numbers. Present only if TRANSLATE option is set true. * ExtToIntRowMap (int []) * An array that is used to convert external row numbers to internal * external row numbers. Present only if TRANSLATE option is set true. * Factored (BOOLEAN) * Indicates if matrix has been factored. This flag is set true in * spFactor() and spOrderAndFactor() and set false in spCreate() * and spClear(). * Fillins (int) * The number of fill-ins created during the factorization the matrix. * FirstInCol (ArrayOfElementPtrs) * Array of pointers that point to the first nonzero element of the * column corresponding to the index. * FirstInRow (ArrayOfElementPtrs) * Array of pointers that point to the first nonzero element of the row * corresponding to the index. * ID (unsigned long int) * A constant that provides the sparse data structure with a signature. * When DEBUG is true, all externally available sparse routines check * this signature to assure they are operating on a valid matrix. * Intermediate (RealVector) * Temporary storage used in the spSolve routines. Intermediate is an * array used during forward and backward substitution. It is * commonly called y when the forward and backward substitution process is * denoted Ax = b => Ly = b and Ux = y. * InternalVectorsAllocated (BOOLEAN) * A flag that indicates whether the markowitz vectors and the * Intermediate vector have been created. * These vectors are created in CreateInternalVectors(). * IntToExtColMap (int []) * An array that is used to convert internal column numbers to external * external column numbers. * IntToExtRowMap (int []) * An array that is used to convert internal row numbers to external * external row numbers. * MarkowitzCol (int []) * An array that contains the count of the non-zero elements excluding * the pivots for each column. Used to generate and update MarkowitzProd. * MarkowitzProd (long []) * The array of the products of the Markowitz row and column counts. The * element with the smallest product is the best pivot to use to maintain * sparsity. * MarkowitzRow (int []) * An array that contains the count of the non-zero elements excluding * the pivots for each row. Used to generate and update MarkowitzProd. * MaxRowCountInLowerTri (int) * The maximum number of off-diagonal element in the rows of L, the * lower triangular matrix. This quantity is used when computing an * estimate of the roundoff error in the matrix. * NeedsOrdering (BOOLEAN) * This is a flag that signifies that the matrix needs to be ordered * or reordered. NeedsOrdering is set true in spCreate() and * spGetElement() or spGetAdmittance() if new elements are added to the * matrix after it has been previously factored. It is set false in * spOrderAndFactor(). * NumberOfInterchangesIsOdd (BOOLEAN) * Flag that indicates the sum of row and column interchange counts * is an odd number. Used when determining the sign of the determinant. * Partitioned (BOOLEAN) * This flag indicates that the columns of the matrix have been * partitioned into two groups. Those that will be addressed directly * and those that will be addressed indirectly in spFactor(). * PivotsOriginalCol (int) * Column pivot was chosen from. * PivotsOriginalRow (int) * Row pivot was chosen from. * PivotSelectionMethod (char) * Character that indicates which pivot search method was successful. * PreviousMatrixWasComplex (BOOLEAN) * This flag in needed to determine how to clear the matrix. When * dealing with real matrices, it is important that the imaginary terms * in the matrix elements be zero. Thus, if the previous matrix was * complex, then the current matrix will be cleared as if it were complex * even if it is real. * RelThreshold (RealNumber) * The magnitude an element must have relative to others in its row * to be considered as a pivot candidate, except as a last resort. * Reordered (BOOLEAN) * This flag signifies that the matrix has been reordered. It * is cleared in spCreate(), set in spMNA_Preorder() and * spOrderAndFactor() and is used in spPrint(). * RowsLinked (BOOLEAN) * A flag that indicates whether the row pointers exist. The AddByIndex * routines do not generate the row pointers, which are needed by some * of the other routines, such as spOrderAndFactor() and spScale(). * The row pointers are generated in the function spcLinkRows(). * SingularCol (int) * Normally zero, but if matrix is found to be singular, SingularCol is * assigned the external column number of pivot that was zero. * SingularRow (int) * Normally zero, but if matrix is found to be singular, SingularRow is * assigned the external row number of pivot that was zero. * Singletons (int) * The number of singletons available for pivoting. Note that if row I * and column I both contain singletons, only one of them is counted. * Size (int) * Number of rows and columns in the matrix. Does not change as matrix * is factored. * TrashCan (MatrixElement) * This is a dummy MatrixElement that is used to by the user to stuff * data related to the zero row or column. In other words, when the user * adds an element in row zero or column zero, then the matrix returns * a pointer to TrashCan. In this way the user can have a uniform way * data into the matrix independent of whether a component is connected * to ground. * * >>> The remaining fields are related to memory allocation. * TopOfAllocationList (AllocationListPtr) * Pointer which points to the top entry in a list. The list contains * all the pointers to the segments of memory that have been allocated * to this matrix. This is used when the memory is to be freed on * deallocation of the matrix. * RecordsRemaining (int) * Number of slots left in the list of allocations. * NextAvailElement (ElementPtr) * Pointer to the next available element which has been allocated but as * yet is unused. Matrix elements are allocated in groups of * ELEMENTS_PER_ALLOCATION in order to speed element allocation and * freeing. * ElementsRemaining (int) * Number of unused elements left in last block of elements allocated. * NextAvailFillin (ElementPtr) * Pointer to the next available fill-in which has been allocated but * as yet is unused. Fill-ins are allocated in a group in order to keep * them physically close in memory to the rest of the matrix. * FillinsRemaining (int) * Number of unused fill-ins left in the last block of fill-ins * allocated. * FirstFillinListNode (FillinListNodeStruct *) * A pointer to the head of the linked-list that keeps track of the * lists of fill-ins. * LastFillinListNode (FillinListNodeStruct *) * A pointer to the tail of the linked-list that keeps track of the * lists of fill-ins. */ /* Begin `MatrixFrame'. */ struct MatrixFrame { RealNumber AbsThreshold; int AllocatedSize; int AllocatedExtSize; BOOLEAN Complex; int CurrentSize; ArrayOfElementPtrs Diag; BOOLEAN *DoCmplxDirect; BOOLEAN *DoRealDirect; int Elements; int Error; int ExtSize; int *ExtToIntColMap; int *ExtToIntRowMap; BOOLEAN Factored; int Fillins; ArrayOfElementPtrs FirstInCol; ArrayOfElementPtrs FirstInRow; unsigned long ID; RealVector Intermediate; BOOLEAN InternalVectorsAllocated; int *IntToExtColMap; int *IntToExtRowMap; int *MarkowitzRow; int *MarkowitzCol; long *MarkowitzProd; int MaxRowCountInLowerTri; BOOLEAN NeedsOrdering; BOOLEAN NumberOfInterchangesIsOdd; BOOLEAN Partitioned; int PivotsOriginalCol; int PivotsOriginalRow; char PivotSelectionMethod; BOOLEAN PreviousMatrixWasComplex; RealNumber RelThreshold; BOOLEAN Reordered; BOOLEAN RowsLinked; int SingularCol; int SingularRow; int Singletons; int Size; struct MatrixElement TrashCan; AllocationListPtr TopOfAllocationList; int RecordsRemaining; ElementPtr NextAvailElement; int ElementsRemaining; ElementPtr NextAvailFillin; int FillinsRemaining; struct FillinListNodeStruct *FirstFillinListNode; struct FillinListNodeStruct *LastFillinListNode; }; typedef struct MatrixFrame *MatrixPtr;