1 /*  EXPORTS for sparse matrix routines. */
2 /*!
3  *  \file
4  *
5  *  This file contains definitions that are useful to the calling
6  *  program.  In particular, this file contains error keyword
7  *  definitions, some macro functions that are used to quickly enter
8  *  data into the matrix and the type definition of a data structure
9  *  that acts as a template for entering admittances into the matrix.
10  *  Also included is the type definitions for the various functions
11  *  available to the user.
12  *
13  *  Objects that begin with the \a spc prefix are considered private
14  *  and should not be used.
15  *
16  *  \author
17  *  Kenneth S. Kundert <kundert@users.sourceforge.net>
18  */
19 
20 
21 /*
22  *  Revision and copyright information.
23  *
24  *  Copyright (c) 1985-2003 by Kenneth S. Kundert
25  *
26  */
27 
28 
29 #ifndef  spOKAY
30 
31 /*
32  *  IMPORTS
33  *
34  *  >>> Import descriptions:
35  *  spConfig.h
36  *      Macros that customize the sparse matrix routines.
37  */
38 
39 #include "spConfig.h"
40 
41 /*
42  *  ERROR KEYWORDS
43  *
44  *  The actual numbers used in the error codes are not sacred, they can be
45  *  changed under the condition that the codes for the nonfatal errors are
46  *  less than the code for spFATAL and similarly the codes for the fatal
47  *  errors are greater than that for spFATAL.
48  */
49 
50 /* Begin error macros. */
51 #define  spOKAY                0  /*!<
52                             * Error code that indicates that no error has
53                             * occurred.
54                             */
55 #define  spSMALL_PIVOT        1  /*!<
56                             * Non-fatal error code that indicates that, when
57                             * reordering the matrix, no element was found that
58                             * satisfies the absolute threshold criteria. The
59                             * largest element in the matrix was chosen as pivot.
60                             */
61 #define  spZERO_DIAG        2  /*!<
62                             * Fatal error code that indicates that, a zero was
63                             * encountered on the diagonal the matrix. This does
64                             * not necessarily imply that the matrix is singular.
65                             * When this error occurs, the matrix should be
66                             * reconstructed and factored using
67                             * spOrderAndFactor().
68                             */
69 #define  spSINGULAR        3  /*!<
70                             * Fatal error code that indicates that, matrix is
71                             * singular, so no unique solution exists.
72                             */
73 #define  spMANGLED        4  /*!<
74                             * Fatal error code that indicates that, matrix has
75                             * been mangled, results of requested operation are
76                             * garbage.
77                             */
78 #define  spNO_MEMORY        5  /*!<
79                             * Fatal error code that indicates that not enough
80                             * memory is available.
81                             */
82 #define  spPANIC        6  /*!<
83                             * Fatal error code that indicates that the routines
84                             * are not prepared to handle the matrix that has
85                             * been requested.  This may occur when the matrix
86                             * is specified to be real and the routines are not
87                             * compiled for real matrices, or when the matrix is
88                             * specified to be complex and the routines are not
89                             * compiled to handle complex matrices.
90                             */
91 #define  spFATAL        2  /*!<
92                             * Error code that is not an error flag, but rather
93                             * the dividing line between fatal errors and
94                             * warnings.
95                             */
96 
97 
98 /*
99  *  KEYWORD DEFINITIONS
100  */
101 
102 #define  spREAL double  /*!<
103                          * Defines the precision of the arithmetic used by
104                          * \a Sparse will use.  Double precision is suggested
105                          * as being most appropriate for circuit simulation
106                          * and for C.  However, it is possible to change spREAL
107                          * to a float for single precision arithmetic.  Note
108                          * that in C, single precision arithmetic is often
109                          * slower than double precision.  Sparse
110                          * internally refers to spREALs as RealNumbers.
111                          */
112 
113 
114 /*
115  *  PARTITION TYPES
116  *
117  *  When factoring a previously ordered matrix using spFactor(), Sparse
118  *  operates on a row-at-a-time basis.  For speed, on each step, the row
119  *  being updated is copied into a full vector and the operations are
120  *  performed on that vector.  This can be done one of two ways, either
121  *  using direct addressing or indirect addressing.  Direct addressing
122  *  is fastest when the matrix is relatively dense and indirect addressing
123  *  is quite sparse.  The user can select which partitioning mode is used.
124  *  The following keywords are passed to spPartition() and indicate that
125  *  Sparse should use only direct addressing, only indirect addressing, or
126  *  that it should choose the best mode on a row-by-row basis.  The time
127  *  required to choose a partition is of the same order of the cost to factor
128  *  the matrix.
129  *
130  *  If you plan to factor a large number of matrices with the same structure,
131  *  it is best to let Sparse choose the partition.  Otherwise, you should
132  *  choose the partition based on the predicted density of the matrix.
133  */
134 
135 /* Begin partition keywords. */
136 
137 #define spDEFAULT_PARTITION        0 /*!<
138                                    * Partition code for spPartition().
139                                    * Indicates that the default partitioning
140                                    * mode should be used.
141                                    * \see spPartition()
142                                    */
143 #define spDIRECT_PARTITION        1 /*!<
144                                    * Partition code for spPartition().
145                                    * Indicates that all rows should be placed
146                                    * in the direct addressing partition.
147                                    * \see spPartition()
148                                    */
149 #define spINDIRECT_PARTITION        2 /*!<
150                                    * Partition code for spPartition().
151                                    * Indicates that all rows should be placed
152                                    * in the indirect addressing partition.
153                                    * \see spPartition()
154                                    */
155 #define spAUTO_PARTITION        3 /*!<
156                                    * Partition code for spPartition().
157                                    * Indicates that \a Sparse should chose
158                                    * the best partition for each row based
159                                    * on some simple rules. This is generally
160                                    * preferred.
161                                    * \see spPartition()
162                                    */
163 
164 /*
165  *  MACRO FUNCTION DEFINITIONS
166  */
167 
168 /* Begin Macros. */
169 /*!
170  * Macro function that adds data to a real element in the matrix by a pointer.
171  */
172 #define  spADD_REAL_ELEMENT(element,real)       *(element) += real
173 
174 /*!
175  * Macro function that adds data to a imaginary element in the matrix by
176  * a pointer.
177  */
178 #define  spADD_IMAG_ELEMENT(element,imag)       *((element)+1) += imag
179 
180 /*!
181  * Macro function that adds data to a complex element in the matrix by
182  * a pointer.
183  */
184 #define  spADD_COMPLEX_ELEMENT(element,real,imag)       \
185 {   *(element) += (real);                                 \
186     *((element)+1) += (imag);                               \
187 }
188 
189 /*!
190  * Macro function that adds data to each of the four real matrix elements
191  * specified by the given template.
192  */
193 #define  spADD_REAL_QUAD(template,real)         \
194 {   *((template).Element1) += (real);             \
195     *((template).Element2) += (real);             \
196     *((template).Element3Negated) -= (real);      \
197     *((template).Element4Negated) -= (real);      \
198 }
199 
200 /*!
201  * Macro function that adds data to each of the four imaginary matrix
202  * elements specified by the given template.
203  */
204 #define  spADD_IMAG_QUAD(template,imag)         \
205 {   *((template).Element1+1) += (imag);           \
206     *((template).Element2+1) += (imag);           \
207     *((template).Element3Negated+1) -= (imag);    \
208     *((template).Element4Negated+1) -= (imag);    \
209 }
210 
211 /*!
212  * Macro function that adds data to each of the four complex matrix
213  * elements specified by the given template.
214  */
215 #define  spADD_COMPLEX_QUAD(template,real,imag) \
216 {   *((template).Element1) += (real);             \
217     *((template).Element2) += (real);             \
218     *((template).Element3Negated) -= (real);      \
219     *((template).Element4Negated) -= (real);      \
220     *((template).Element1+1) += (imag);           \
221     *((template).Element2+1) += (imag);           \
222     *((template).Element3Negated+1) -= (imag);    \
223     *((template).Element4Negated+1) -= (imag);    \
224 }
225 
226 /*
227  *   TYPE DEFINITION FOR EXTERNAL MATRIX ELEMENT REFERENCES
228  *
229  *   External type definitions for Sparse data objects.
230  */
231 
232 /*! Declares the type of the a pointer to a matrix. */
233 typedef spGenericPtr spMatrix;
234 
235 /*! Declares the type of the a pointer to a matrix element. */
236 typedef spREAL spElement;
237 
238 /*! Declares the type of the Sparse error codes. */
239 typedef int spError;
240 
241 /* TYPE DEFINITION FOR COMPONENT TEMPLATE */
242 /*!
243  *   This data structure is used to hold pointers to four related elements in
244  *   matrix.  It is used in conjunction with the routines spGetAdmittance(),
245  *   spGetQuad(), and spGetOnes().  These routines stuff the structure which
246  *   is later used by the \a spADD_QUAD macro functions above.  It is also
247  *   possible for the user to collect four pointers returned by spGetElement()
248  *   and stuff them into the template.  The \a spADD_QUAD routines stuff data
249  *   into the matrix in locations specified by \a Element1 and \a Element2
250  *   without changing the data.  The data is negated before being placed in
251  *   \a Element3 and \a Element4.
252  */
253 
254 /* Begin `spTemplate'. */
255 struct  spTemplate
256 {   spElement        *Element1;
257     spElement        *Element2;
258     spElement        *Element3Negated;
259     spElement        *Element4Negated;
260 };
261 
262 
263 /*
264  *   FUNCTION TYPE DEFINITIONS
265  *
266  *   The type of every user accessible function is declared here.
267  */
268 
269 /* Begin function declarations. */
270 
271 spcEXTERN  void       spClear( spMatrix );
272 spcEXTERN  spREAL     spCondition( spMatrix, spREAL, int* );
273 spcEXTERN  spMatrix   spCreate( int, int, spError* );
274 spcEXTERN  void       spDeleteRowAndCol( spMatrix, int, int );
275 spcEXTERN  void       spDestroy( spMatrix );
276 spcEXTERN  int        spElementCount( spMatrix );
277 spcEXTERN  spError    spErrorState( spMatrix );
278 
279 spcEXTERN  spError    spFactor( spMatrix );
280 /*  Remove file IO due to archaic fopen method which gives warnings in windoz
281 spcEXTERN  int        spFileMatrix( spMatrix, char*, char*, int, int, int );
282 spcEXTERN  int        spFileStats( spMatrix, char*, char* );
283 */
284 spcEXTERN  int        spFillinCount( spMatrix );
285 spcEXTERN  spElement *spFindElement( spMatrix, int, int );
286 spcEXTERN  spError    spGetAdmittance( spMatrix, int, int,
287                                 struct spTemplate* );
288 spcEXTERN  spElement *spGetElement( spMatrix, int, int );
289 spcEXTERN  spGenericPtr spGetInitInfo( spElement* );
290 spcEXTERN  spError    spGetOnes( spMatrix, int, int, int,
291                                 struct spTemplate* );
292 spcEXTERN  spError    spGetQuad( spMatrix, int, int, int, int,
293                                 struct spTemplate* );
294 spcEXTERN  int        spGetSize( spMatrix, int );
295 spcEXTERN  int        spInitialize( spMatrix, int (*pInit)(spElement *, spGenericPtr, int, int) );
296 spcEXTERN  void       spInstallInitInfo( spElement*, spGenericPtr );
297 spcEXTERN  spREAL     spLargestElement( spMatrix );
298 spcEXTERN  void       spMNA_Preorder( spMatrix );
299 spcEXTERN  spREAL     spNorm( spMatrix );
300 spcEXTERN  spError    spOrderAndFactor( spMatrix, spREAL[], spREAL,
301                                 spREAL, int );
302 spcEXTERN  void       spPartition( spMatrix, int );
303 spcEXTERN  void       spPrint( spMatrix, int, int, int );
304 spcEXTERN  void       spRowColOrder( spMatrix, int*, int*);
305 spcEXTERN  spREAL     spPseudoCondition( spMatrix );
306 spcEXTERN  spREAL     spRoundoff( spMatrix, spREAL );
307 spcEXTERN  void       spScale( spMatrix, spREAL[], spREAL[] );
308 spcEXTERN  void       spSetComplex( spMatrix );
309 spcEXTERN  void       spSetReal( spMatrix );
310 spcEXTERN  void       spStripFills( spMatrix );
311 spcEXTERN  void       spWhereSingular( spMatrix, int*, int* );
312 
313 /* Functions with argument lists that are dependent on options. */
314 
315 #if spCOMPLEX
316 spcEXTERN  void       spDeterminant( spMatrix, int*, spREAL*, spREAL* );
317 #else /* NOT spCOMPLEX */
318 spcEXTERN  void       spDeterminant( spMatrix, int*, spREAL* );
319 #endif /* NOT spCOMPLEX */
320 #if spCOMPLEX && spSEPARATED_COMPLEX_VECTORS
321 /* Get rid of arcaic file IO
322 spcEXTERN  int        spFileVector( spMatrix, char* ,
323                                 spREAL[], spREAL[]);
324 */
325 spcEXTERN  void       spMultiply( spMatrix, spREAL[], spREAL[],
326                                 spREAL[], spREAL[] );
327 spcEXTERN  void       spMultTransposed( spMatrix, spREAL[], spREAL[],
328                                 spREAL[], spREAL[] );
329 spcEXTERN  void       spSolve( spMatrix, spREAL[], spREAL[], spREAL[],
330                                 spREAL[] );
331 spcEXTERN  void       spSolveTransposed( spMatrix, spREAL[], spREAL[],
332                                 spREAL[], spREAL[] );
333 #else /* NOT  (spCOMPLEX && spSEPARATED_COMPLEX_VECTORS) */
334 /* Get rid of arcaic file IO
335 spcEXTERN  int        spFileVector( spMatrix, char* , spREAL[] );
336 */
337 spcEXTERN  void       spMultiply( spMatrix, spREAL[], spREAL[] );
338 spcEXTERN  void       spMultTransposed( spMatrix,
339                                 spREAL[], spREAL[] );
340 spcEXTERN  void       spSolve( spMatrix, spREAL[], spREAL[] );
341 spcEXTERN  void       spSolveTransposed( spMatrix,
342                                 spREAL[], spREAL[] );
343 #endif /* NOT  (spCOMPLEX && spSEPARATED_COMPLEX_VECTORS) */
344 #endif  /* spOKAY */
345