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