ngspice/src/maths/sparse/spdefs.h

811 lines
31 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef ngspice_SPDEFS_H
#define ngspice_SPDEFS_H
/*
* 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,89,90
* 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.
*/
/*
* IMPORTS
*/
#include <stdio.h>
#undef ABORT
#undef FREE
/*
* 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 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 ? -(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) \
do { \
type SWAP_macro_local = a; \
a = b; \
b = SWAP_macro_local; \
} while(0)
/* Real and Complex numbers definition */
#define spREAL double
/* Begin `realNumber'. */
typedef spREAL RealNumber, *RealVector;
/* Begin `ComplexNumber'. */
typedef struct
{ RealNumber Real;
RealNumber Imag;
} ComplexNumber, *ComplexVector;
/* Macro function that returns the approx absolute value of a complex
number. */
#define ELEMENT_MAG(ptr) (ABS((ptr)->Real) + ABS((ptr)->Imag))
#define CMPLX_ASSIGN_VALUE(cnum, vReal, vImag) \
{ (cnum).Real = vReal; \
(cnum).Imag = vImag; \
}
/* 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 CONJUGATE(a) (a).Imag = -(a).Imag
#define CMPLX_NEGATE(a) \
{ (a).Real = -(a).Real; \
(a).Imag = -(a).Imag; \
}
#define CMPLX_NEGATE_SELF(cnum) \
{ (cnum).Real = -(cnum).Real; \
(cnum).Imag = -(cnum).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) (hypot((a).Real, (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 addition of a complex and a scalar. */
#define CMPLX_ADD_SELF_SCALAR(cnum, scalar) \
{ (cnum).Real += scalar; \
}
/* 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 multiplies a complex number and a scalar. */
#define CMPLX_MULT_SCALAR(to,from, scalar) \
{ (to).Real = (from).Real * scalar; \
(to).Imag = (from).Imag * scalar; \
}
/* Macro function that implements *= for a complex and a scalar number. */
#define CMPLX_MULT_SELF_SCALAR(cnum, scalar) \
{ (cnum).Real *= scalar; \
(cnum).Imag *= scalar; \
}
/* 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 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 && (den).Real > -(den).Imag) || \
((den).Real < (den).Imag && (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 && (den).Real > -(den).Imag) || \
((den).Real < (den).Imag && (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 && (den).Real > -(den).Imag) || \
((den).Real < (den).Imag && (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));\
} \
}
/* Allocation */
extern void * tmalloc(size_t);
extern void txfree(void *);
extern void * trealloc(void *, size_t);
#define SP_MALLOC(type,number) (type *) tmalloc((size_t)(number) * sizeof(type))
#define SP_REALLOC(ptr,type,number) \
ptr = (type *) trealloc(ptr, (size_t)(number) * sizeof(type))
#define SP_FREE(ptr) { if ((ptr) != NULL) txfree(ptr); (ptr) = NULL; }
#include "ngspice/config.h"
/* A new calloc */
#ifndef HAVE_LIBGC
#define SP_CALLOC(ptr,type,number) \
{ ptr = (type *) calloc((size_t)(number), sizeof(type)); \
}
#else /* HAVE_LIBCG */
#define SP_CALLOC(ptr,type,number) \
{ ptr = (type *) tmalloc((size_t)(number) * sizeof(type)); \
}
#include <gc/gc.h>
#define tmalloc(m) GC_malloc(m)
#define trealloc(m, n) GC_realloc((m), (n))
#define tfree(m)
#define txfree(m)
#endif
#include "ngspice/defines.h"
/*
* 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 (void *)
* 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;
RealNumber Imag;
int Row;
int Col;
struct MatrixElement *NextInRow;
struct MatrixElement *NextInCol;
#if INITIALIZE
void *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 (void *)
* 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
{
void *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;
};
/* Similar to above, but keeps track of the original Elements */
/* Begin `ElementListNodeStruct'. */
struct ElementListNodeStruct
{
ElementPtr pElementList;
int NumberOfElementsInList;
struct ElementListNodeStruct *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 (int)
* 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 (int *)
* 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 (int *)
* 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 total number of elements 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 (int)
* 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 (int)
* A flag that indicates whether the Markowitz vectors and the
* Intermediate vector have been created.
* These vectors are created in spcCreateInternalVectors().
* 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 (int)
* 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 (int)
* Flag that indicates the sum of row and column interchange counts
* is an odd number. Used when determining the sign of the determinant.
* Originals (int)
* The number of original elements (total elements minus fill ins)
* present in matrix.
* Partitioned (int)
* 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 (int)
* 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 (int)
* 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 (int)
* 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;
int Complex;
int CurrentSize;
ArrayOfElementPtrs Diag;
int *DoCmplxDirect;
int *DoRealDirect;
int Elements;
int Error;
int ExtSize;
int *ExtToIntColMap;
int *ExtToIntRowMap;
int Factored;
int Fillins;
ArrayOfElementPtrs FirstInCol;
ArrayOfElementPtrs FirstInRow;
unsigned long ID;
RealVector Intermediate;
int InternalVectorsAllocated;
int *IntToExtColMap;
int *IntToExtRowMap;
int *MarkowitzRow;
int *MarkowitzCol;
long *MarkowitzProd;
int MaxRowCountInLowerTri;
int NeedsOrdering;
int NumberOfInterchangesIsOdd;
int Originals;
int Partitioned;
int PivotsOriginalCol;
int PivotsOriginalRow;
char PivotSelectionMethod;
int PreviousMatrixWasComplex;
RealNumber RelThreshold;
int Reordered;
int RowsLinked;
int SingularCol;
int SingularRow;
int Singletons;
int Size;
struct MatrixElement TrashCan;
AllocationListPtr TopOfAllocationList;
int RecordsRemaining;
ElementPtr NextAvailElement;
int ElementsRemaining;
struct ElementListNodeStruct *FirstElementListNode;
struct ElementListNodeStruct *LastElementListNode;
ElementPtr NextAvailFillin;
int FillinsRemaining;
struct FillinListNodeStruct *FirstFillinListNode;
struct FillinListNodeStruct *LastFillinListNode;
};
/*
* Function declarations
*/
extern ElementPtr spcGetElement( MatrixPtr );
extern ElementPtr spcGetFillin( MatrixPtr );
extern ElementPtr spcFindElementInCol( MatrixPtr, ElementPtr*, int, int, int );
extern ElementPtr spcCreateElement( MatrixPtr, int, int, ElementPtr*, int );
extern void spcCreateInternalVectors( MatrixPtr );
extern void spcLinkRows( MatrixPtr );
extern void spcColExchange( MatrixPtr, int, int );
extern void spcRowExchange( MatrixPtr, int, int );
void spErrorMessage(MatrixPtr, FILE *, char *);
#endif