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