1 /*
2  *  EXPORTS for sparse matrix routines with SPICE3.
3  *
4  *  Author:                     Advising professor:
5  *      Kenneth S. Kundert          Alberto Sangiovanni-Vincentelli
6  *      UC Berkeley
7  *
8  *  This file contains definitions that are useful to the calling
9  *  program.  In particular, this file contains error keyword
10  *  definitions, some macro functions that are used to quickly enter
11  *  data into the matrix and the type definition of a data structure
12  *  that acts as a template for entering admittances into the matrix.
13  *  Also included is the type definitions for the various functions
14  *  available to the user.
15  *
16  *  This file is a modified version of spMatrix.h that is used when
17  *  interfacing to Spice3.
18  */
19 
20 
21 /*
22  *  Revision and copyright information.
23  *
24  *  Copyright (c) 1985,86,87,88,89,90
25  *  by Kenneth S. Kundert and the University of California.
26  *
27  *  Permission to use, copy, modify, and distribute this software and
28  *  its documentation for any purpose and without fee is hereby granted,
29  *  provided that the copyright notices appear in all copies and
30  *  supporting documentation and that the authors and the University of
31  *  California are properly credited.  The authors and the University of
32  *  California make no representations as to the suitability of this
33  *  software for any purpose.  It is provided `as is', without express
34  *  or implied warranty.
35  *
36  *  $Date: 88/06/24 05:03:01 $
37  *  $Revision: 1.1 $
38  */
39 
40 
41 
42 
43 #ifndef  spOKAY
44 
45 /*
46  *  IMPORTS
47  *
48  *  >>> Import descriptions:
49  *  spConfig.h
50  *      Macros that customize the sparse matrix routines.
51  */
52 
53 #include "spconfig.h"
54 
55 
56 
57 
58 
59 
60 /*
61  *  ERROR KEYWORDS
62  *
63  *  The actual numbers used in the error codes are not sacred, they can be
64  *  changed under the condition that the codes for the nonfatal errors are
65  *  less than the code for spFATAL and similarly the codes for the fatal
66  *  errors are greater than that for spFATAL.
67  *
68  *  >>> Error descriptions:
69  *  spOKAY
70  *      No error has occurred.
71  *  spSMALL_PIVOT
72  *      When reordering the matrix, no element was found which satisfies the
73  *      threshold criteria.  The largest element in the matrix was chosen
74  *      as pivot.  Non-fatal.
75  *  spZERO_DIAG
76  *      Fatal error.  A zero was encountered on the diagonal the matrix.  This
77  *      does not necessarily imply that the matrix is singular.  When this
78  *      error occurs, the matrix should be reconstructed and factored using
79  *      spOrderAndFactor().  In spCOMPATIBILITY mode, spZERO_DIAG is
80  *      indistinguishable from spSINGULAR.
81  *  spSINGULAR
82  *      Fatal error.  Matrix is singular, so no unique solution exists.
83  *  spNO_MEMORY
84  *      Fatal error.  Indicates that not enough memory is available to handle
85  *      the matrix.
86  *  spPANIC
87  *      Fatal error indicating that the routines are not prepared to
88  *      handle the matrix that has been requested.  This may occur when
89  *      the matrix is specified to be real and the routines are not
90  *      compiled for real matrices, or when the matrix is specified to
91  *      be complex and the routines are not compiled to handle complex
92  *      matrices.
93  *  spFATAL
94  *      Not an error flag, but rather the dividing line between fatal errors
95  *      and warnings.
96  */
97 
98 #include "sperror.h"  /* Spice error definitions. */
99 
100 /* Begin error macros. */
101 #define  spOKAY                 OK
102 #define  spSMALL_PIVOT          OK
103 #define  spZERO_DIAG            E_SINGULAR
104 #define  spSINGULAR             E_SINGULAR
105 #define  spNO_MEMORY            E_NOMEM
106 #define  spPANIC                E_BADMATRIX
107 
108 #define  spFATAL                E_BADMATRIX
109 
110 
111 #if spCOMPATIBILITY
112 #define  NO_ERROR               spOKAY
113 #define  UNDER_FLOW             spOKAY
114 #define  OVER_FLOW              spOKAY
115 #define  ILL_CONDITIONED        spSMALL_PIVOT
116 #define  SINGULAR               spSINGULAR
117 #define  NO_MEMORY              spNO_MEMORY
118 #define  RANGE                  spPANIC
119 
120 #define  FATAL                  spFATAL
121 
122 #undef   spZERO_DIAG
123 #define  spZERO_DIAG            spSINGULAR
124 #endif /* spCOMPATIBILITY */
125 
126 
127 
128 
129 
130 /*
131  *  KEYWORD DEFINITIONS
132  *
133  *  Here we define what precision arithmetic Sparse will use.  Double
134  *  precision is suggested as being most appropriate for circuit
135  *  simulation and for C.  However, it is possible to change spREAL
136  *  to a float for single precision arithmetic.  Note that in C, single
137  *  precision arithmetic is often slower than double precision.  Sparse
138  *  internally refers to spREALs as RealNumbers.
139  *
140  *  Some C compilers, notably the old VMS compiler, do not handle the keyword
141  *  "void" correctly.  If this is true for your compiler, remove the
142  *  comment delimiters from the redefinition of void to int below.
143  */
144 
145 #define  spREAL double
146 /* #define  void    int   */
147 
148 #if spCOMPATIBILITY
149 #define SPARSE_REAL     spREAL
150 #endif
151 
152 
153 
154 /*
155  *  PARTITION TYPES
156  *
157  *  When factoring a previously ordered matrix using spFactor(), Sparse
158  *  operates on a row-at-a-time basis.  For speed, on each step, the row
159  *  being updated is copied into a full vector and the operations are
160  *  performed on that vector.  This can be done one of two ways, either
161  *  using direct addressing or indirect addressing.  Direct addressing
162  *  is fastest when the matrix is relatively dense and indirect addressing
163  *  is quite sparse.  The user can select which partitioning mode is used.
164  *  The following keywords are passed to spPartition() and indicate that
165  *  Sparse should use only direct addressing, only indirect addressing, or
166  *  that it should choose the best mode on a row-by-row basis.  The time
167  *  required to choose a partition is of the same order of the cost to factor
168  *  the matrix.
169  *
170  *  If you plan to factor a large number of matrices with the same structure,
171  *  it is best to let Sparse choose the partition.  Otherwise, you should
172  *  choose the partition based on the predicted density of the matrix.
173  */
174 
175 /* Begin partition keywords. */
176 
177 #define spDEFAULT_PARTITION     0
178 #define spDIRECT_PARTITION      1
179 #define spINDIRECT_PARTITION    2
180 #define spAUTO_PARTITION        3
181 
182 
183 
184 
185 
186 /*
187  *  MACRO FUNCTION DEFINITIONS
188  *
189  *  >>> Macro descriptions:
190  *  spADD_REAL_ELEMENT
191  *      Macro function that adds data to a real element in the matrix by a
192  *      pointer.
193  *  spADD_IMAG_ELEMENT
194  *      Macro function that adds data to a imaginary element in the matrix by
195  *      a pointer.
196  *  spADD_COMPLEX_ELEMENT
197  *      Macro function that adds data to a complex element in the matrix by a
198  *      pointer.
199  *  spADD_REAL_QUAD
200  *      Macro function that adds data to each of the four real matrix elements
201  *      specified by the given template.
202  *  spADD_IMAG_QUAD
203  *      Macro function that adds data to each of the four imaginary matrix
204  *      elements specified by the given template.
205  *  spADD_COMPLEX_QUAD
206  *      Macro function that adds data to each of the four complex matrix
207  *      elements specified by the given template.
208  */
209 
210 /* Begin Macros. */
211 #define  spADD_REAL_ELEMENT(element,real)       *(element) += real
212 
213 #define  spADD_IMAG_ELEMENT(element,imag)       *(element+1) += imag
214 
215 #define  spADD_COMPLEX_ELEMENT(element,real,imag)       \
216 {   *(element) += real;                                 \
217     *(element+1) += imag;                               \
218 }
219 
220 #define  spADD_REAL_QUAD(template,real)         \
221 {   *((template).Element1) += real;             \
222     *((template).Element2) += real;             \
223     *((template).Element3Negated) -= real;      \
224     *((template).Element4Negated) -= real;      \
225 }
226 
227 #define  spADD_IMAG_QUAD(template,imag)         \
228 {   *((template).Element1+1) += imag;           \
229     *((template).Element2+1) += imag;           \
230     *((template).Element3Negated+1) -= imag;    \
231     *((template).Element4Negated+1) -= imag;    \
232 }
233 
234 #define  spADD_COMPLEX_QUAD(template,real,imag) \
235 {   *((template).Element1) += real;             \
236     *((template).Element2) += real;             \
237     *((template).Element3Negated) -= real;      \
238     *((template).Element4Negated) -= real;      \
239     *((template).Element1+1) += imag;           \
240     *((template).Element2+1) += imag;           \
241     *((template).Element3Negated+1) -= imag;    \
242     *((template).Element4Negated+1) -= imag;    \
243 }
244 
245 #if spCOMPATIBILITY
246 #define  ADD_REAL_ELEMENT_TO_MATRIX             spADD_REAL_ELEMENT
247 #define  ADD_IMAG_ELEMENT_TO_MATRIX             spADD_IMAG_ELEMENT
248 #define  ADD_COMPLEX_ELEMENT_TO_MATRIX          spADD_COMPLEX_ELEMENT
249 #define  ADD_REAL_QUAD_ELEMENT_TO_MATRIX        spADD_REAL_ELEMENT
250 #define  ADD_IMAG_QUAD_ELEMENT_TO_MATRIX        spADD_IMAG_ELEMENT
251 #define  ADD_COMPLEX_QUAD_ELEMENT_TO_MATRIX     spADD_COMPLEX_ELEMENT
252 #endif
253 
254 
255 
256 
257 
258 
259 /*
260  *   TYPE DEFINITION FOR COMPONENT TEMPLATE
261  *
262  *   This data structure is used to hold pointers to four related elements in
263  *   matrix.  It is used in conjunction with the routines
264  *       spGetAdmittance
265  *       spGetQuad
266  *       spGetOnes
267  *   These routines stuff the structure which is later used by the spADD_QUAD
268  *   macro functions above.  It is also possible for the user to collect four
269  *   pointers returned by spGetElement and stuff them into the template.
270  *   The spADD_QUAD routines stuff data into the matrix in locations specified
271  *   by Element1 and Element2 without changing the data.  The data is negated
272  *   before being placed in Element3 and Element4.
273  */
274 
275 #if spCOMPATIBILITY
276 #define spTemplate TemplateStruct
277 #endif
278 
279 /* Begin `spTemplate'. */
280 struct  spTemplate
281 {   spREAL    *Element1       ;
282     spREAL    *Element2       ;
283     spREAL    *Element3Negated;
284     spREAL    *Element4Negated;
285 };
286 
287 
288 
289 
290 
291 /*
292  *   FUNCTION TYPE DEFINITIONS
293  *
294  *   The type of every user accessible function is declared here.
295  */
296 
297 /* Begin function declarations. */
298 
299 #ifdef __STDC__
300 
301 /* For compilers that understand function prototypes. */
302 
303 extern  int      spAddCol( char*, int, int );
304 extern  void     spClear( char* );
305 extern  spREAL   spCondition( char*, spREAL, int* );
306 extern  void     spConstMult( char*, spREAL);
307 extern  char    *spCreate( int, int, int* );
308 extern  void     spDeleteRowAndCol( char*, int, int );
309 extern  void     spDestroy( char* );
310 extern  int      spDProd( char*, spREAL*, spREAL*, int* );
311 extern  int      spElementCount( char* );
312 extern  int      spError( char* );
313 extern  int      spFactor( char* );
314 extern  int      spFileMatrix( char*, char*, char*, int, int, int );
315 extern  int      spFileStats( char*, char*, char* );
316 extern  int      spFillinCount( char* );
317 extern  int      spGetAdmittance( char*, int, int, struct spTemplate* );
318 extern  spREAL  *spGetElement( char*, int, int );
319 extern  char    *spGetInitInfo( spREAL* );
320 extern  int      spGetOnes( char*, int, int, int, struct spTemplate* );
321 extern  int      spGetQuad( char*, int, int, int, int, struct spTemplate* );
322 extern  int      spGetSize( char*, int );
323 extern  void     spGetStat( char*, int*, int*, int* );
324 extern  int      spInitialize( char*, int (*)() );
325 extern  void     spInstallInitInfo( spREAL*, char* );
326 extern  void     spItoR( char* );
327 extern  spREAL   spLargestElement( char* );
328 extern  void     spLoadGmin( char*, spREAL );
329 extern  void     spMNA_Preorder( char* );
330 extern  spREAL   spNorm( char* );
331 extern  int      spOrderAndFactor( char*, spREAL[], spREAL, spREAL, int );
332 extern  void     spPartition( char*, int );
333 extern  void     spPrint( char*, int, int, int );
334 extern  spREAL   spPseudoCondition( char* );
335 extern  spREAL   spRoundoff( char*, spREAL );
336 extern  void     spRtoI( char* );
337 extern  void     spScale( char*, spREAL[], spREAL[] );
338 extern  void     spSetComplex( char* );
339 extern  void     spSetReal( char* );
340 extern  void     spStripFills( char* );
341 extern  void     spWhereSingular( char*, int*, int* );
342 extern  int      spZeroCol( char*, int );
343 
344 /* Functions with argument lists that are dependent on options. */
345 
346 #if spCOMPLEX
347 extern  void     spDeterminant ( char*, int*, spREAL*, spREAL* );
348 #else /* NOT spCOMPLEX */
349 extern  void     spDeterminant ( char*, int*, spREAL* );
350 #endif /* NOT spCOMPLEX */
351 #if spCOMPLEX && spSEPARATED_COMPLEX_VECTORS
352 extern  int      spFileVector( char*, char* , spREAL[], spREAL[]);
353 extern  void     spMultiply( char*, spREAL[], spREAL[], spREAL[], spREAL[] );
354 extern  void     spMultTransposed(char*,spREAL[],spREAL[],spREAL[],spREAL[]);
355 extern  void     spSolve( char*, spREAL[], spREAL[], spREAL[], spREAL[] );
356 extern  void     spSolveTransposed(char*,spREAL[],spREAL[],spREAL[],spREAL[]);
357 #else /* NOT (spCOMPLEX && spSEPARATED_COMPLEX_VECTORS) */
358 extern  int      spFileVector( char*, char* , spREAL[] );
359 extern  void     spMultiply( char*, spREAL[], spREAL[] );
360 extern  void     spMultTransposed( char*, spREAL[], spREAL[] );
361 extern  void     spSolve( char*, spREAL[], spREAL[] );
362 extern  void     spSolveTransposed( char*, spREAL[], spREAL[] );
363 #endif /* NOT (spCOMPLEX && spSEPARATED_COMPLEX_VECTORS) */
364 
365 #else /* NOT defined(__STDC__) */
366 
367 /* For compilers that do not understand function prototypes. */
368 
369 extern  int      spAddCol();
370 extern  void     spClear();
371 extern  spREAL   spCondition();
372 extern  void     spConstMult();
373 extern  char    *spCreate();
374 extern  void     spDeleteRowAndCol();
375 extern  void     spDestroy();
376 extern  void     spDeterminant ();
377 extern  int      spDProd();
378 extern  int      spElementCount();
379 extern  int      spError();
380 extern  int      spFactor();
381 extern  int      spFileMatrix();
382 extern  int      spFileStats();
383 extern  int      spFileVector();
384 extern  int      spFillinCount();
385 extern  int      spGetAdmittance();
386 extern  spREAL  *spGetElement();
387 extern  char    *spGetInitInfo();
388 extern  int      spGetOnes();
389 extern  int      spGetQuad();
390 extern  int      spGetSize();
391 extern  void     spGetStat();
392 extern  int      spInitialize();
393 extern  void     spInstallInitInfo();
394 extern  void     spItoR();
395 extern  spREAL   spLargestElement();
396 extern  void     spLoadGmin();
397 extern  void     spMNA_Preorder();
398 extern  void     spMultiply();
399 extern  void     spMultTransposed();
400 extern  spREAL   spNorm();
401 extern  int      spOrderAndFactor();
402 extern  void     spPartition();
403 extern  void     spPrint();
404 extern  spREAL   spPseudoCondition();
405 extern  spREAL   spRoundoff();
406 extern  void     spRtoI();
407 extern  void     spScale();
408 extern  void     spSetComplex();
409 extern  void     spSetReal();
410 extern  void     spSolve();
411 extern  void     spSolveTransposed();
412 extern  void     spStripFills();
413 extern  void     spWhereSingular();
414 extern  int      spZeroCol();
415 #endif /* defined(__STDC__) */
416 
417 #if spCOMPATIBILITY
418 extern  char    *AllocateMatrix();
419 extern  spREAL  *AddElementToMatrix();
420 extern  void     AddRealElementToMatrix();
421 extern  void     AddImagElementToMatrix();
422 extern  void     AddComplexElementToMatrix();
423 extern  void     AddAdmittanceToMatrix();
424 extern  void     AddOnesToMatrix();
425 extern  void     AddQuadToMatrix();
426 extern  void     AddRealQuadElementToMatrix();
427 extern  void     AddImagQuadElementToMatrix();
428 extern  void     AddComplexQuadElementToMatrix();
429 extern  void     CleanMatrix();
430 extern  void     ClearMatrix();
431 extern  int      ClearMatrixError();
432 extern  void     DeallocateMatrix();
433 extern  void     DeleteRowAndColFromMatrix();
434 extern  void     Determinant();
435 extern  int      DecomposeMatrix();
436 extern  int      GetMatrixSize();
437 extern  int      MatrixElementCount();
438 extern  int      MatrixFillinCount();
439 extern  void     MatrixMultiply();
440 extern  spREAL   MatrixRoundoffError();
441 extern  int      MatrixError();
442 extern  int      OrderAndDecomposeMatrix();
443 extern  void     OutputMatrixToFile();
444 extern  void     OutputStatisticsToFile();
445 extern  void     OutputVectorToFile();
446 extern  void     PreorderForModifiedNodal();
447 extern  void     PrintMatrix();
448 extern  void     SetMatrixComplex();
449 extern  void     SetMatrixReal();
450 extern  void     SolveMatrix();
451 extern  void     SolveTransposedMatrix();
452 extern  void     ScaleMatrix();
453 #endif /* spCOMPATIBILITY */
454 
455 #endif  /* spOKAY */
456