52 static char copyright[] =
53 "Sparse1.3: Copyright (c) 1985,86,87,88,89,90 by Kenneth S. Kundert";
55 "@(#)$Header: spUtils.c,v 1.3 88/06/24 05:03:37 kundert Exp $";
72 #define spINSIDE_SPARSE 89 #if spSEPARATED_COMPLEX_VECTORS 209 register int J,
Size;
211 int Twins, StartAt = 1;
212 BOOLEAN Swapped, AnotherPassNeeded;
222 { AnotherPassNeeded = Swapped =
NO;
225 for (J = StartAt; J <=
Size; J++)
227 { Twins =
CountTwins( Matrix, J, &pTwin1, &pTwin2 );
233 else if ((Twins > 1)
AND NOT AnotherPassNeeded)
234 { AnotherPassNeeded =
YES;
241 if (AnotherPassNeeded)
242 {
for (J = StartAt;
NOT Swapped
AND (J <= Size); J++)
244 { Twins =
CountTwins( Matrix, J, &pTwin1, &pTwin2 );
250 }
while (AnotherPassNeeded);
277 pTwin1 = Matrix->FirstInCol[Col];
278 while (pTwin1 !=
NULL)
279 {
if (
ABS(pTwin1->
Real) == 1.0)
281 pTwin2 = Matrix->FirstInCol[Row];
282 while ((pTwin2 !=
NULL)
AND (pTwin2->
Row != Col))
286 if (++Twins >= 2)
return Twins;
287 (*ppTwin1 = pTwin1)->Col = Col;
288 (*ppTwin2 = pTwin2)->Col = Row;
312 int Col1 = pTwin1->
Col, Col2 = pTwin2->
Col;
316 SWAP (
ElementPtr, Matrix->FirstInCol[Col1], Matrix->FirstInCol[Col2]);
317 SWAP (
int, Matrix->IntToExtColMap[Col1], Matrix->IntToExtColMap[Col2]);
319 Matrix->ExtToIntColMap[Matrix->IntToExtColMap[Col2]]=Col2;
320 Matrix->ExtToIntColMap[Matrix->IntToExtColMap[Col1]]=Col1;
323 Matrix->Diag[Col1] = pTwin2;
324 Matrix->Diag[Col2] = pTwin1;
325 Matrix->NumberOfInterchangesIsOdd =
NOT Matrix->NumberOfInterchangesIsOdd;
396 spScale( eMatrix, RHS_ScaleFactors, SolutionScaleFactors )
399 register
RealVector RHS_ScaleFactors, SolutionScaleFactors;
419 lSize = Matrix->
Size;
424 --SolutionScaleFactors;
429 for (I = 1; I <= lSize; I++)
430 {
if ((ScaleFactor = RHS_ScaleFactors[*(pExtOrder++)]) != 1.0)
433 while (pElement !=
NULL)
434 { pElement->
Real *= ScaleFactor;
442 for (I = 1; I <= lSize; I++)
443 {
if ((ScaleFactor = SolutionScaleFactors[*(pExtOrder++)]) != 1.0)
446 while (pElement !=
NULL)
447 { pElement->
Real *= ScaleFactor;
466 #if spCOMPLEX AND SCALING 527 register
RealVector RHS_ScaleFactors, SolutionScaleFactors;
534 lSize = Matrix->Size;
539 --SolutionScaleFactors;
543 pExtOrder = &Matrix->IntToExtRowMap[1];
544 for (I = 1; I <= lSize; I++)
545 {
if ((ScaleFactor = RHS_ScaleFactors[*(pExtOrder++)]) != 1.0)
546 { pElement = Matrix->FirstInRow[
I];
548 while (pElement !=
NULL)
549 { pElement->
Real *= ScaleFactor;
550 pElement->Imag *= ScaleFactor;
557 pExtOrder = &Matrix->IntToExtColMap[1];
558 for (I = 1; I <= lSize; I++)
559 {
if ((ScaleFactor = SolutionScaleFactors[*(pExtOrder++)]) != 1.0)
560 { pElement = Matrix->FirstInCol[
I];
562 while (pElement !=
NULL)
563 { pElement->
Real *= ScaleFactor;
564 pElement->Imag *= ScaleFactor;
649 for (I = Matrix->
Size; I > 0; I--)
650 Vector[
I] = Solution[*(pExtOrder--)];
653 for (I = Matrix->
Size; I > 0; I--)
657 while (pElement !=
NULL)
658 { Sum += pElement->
Real * Vector[pElement->
Col];
661 RHS[*pExtOrder--] = Sum;
678 int size = matrix->
Size;
680 for (i = 1; i <= size; i++) {
696 #if spCOMPLEX AND MULTIPLICATION 746 #if spSEPARATED_COMPLEX_VECTORS 748 --Solution; --iSolution;
750 RHS -= 2; Solution -= 2;
756 pExtOrder = &Matrix->IntToExtColMap[Matrix->Size];
759 for (I = Matrix->Size; I > 0; I--)
761 Vector[
I].
Imag = iSolution[*(pExtOrder--)];
764 for (I = Matrix->Size; I > 0; I--)
768 pExtOrder = &Matrix->IntToExtRowMap[Matrix->Size];
769 for (I = Matrix->Size; I > 0; I--)
770 { pElement = Matrix->FirstInRow[
I];
773 while (pElement !=
NULL)
779 #if spSEPARATED_COMPLEX_VECTORS 781 iRHS[*pExtOrder--] = Sum.
Imag;
797 #if MULTIPLICATION AND TRANSPOSE 864 for (I = Matrix->
Size; I > 0; I--)
865 Vector[
I] = Solution[*(pExtOrder--)];
868 for (I = Matrix->
Size; I > 0; I--)
872 while (pElement !=
NULL)
873 { Sum += pElement->
Real * Vector[pElement->
Row];
876 RHS[*pExtOrder--] = Sum;
889 #if spCOMPLEX AND MULTIPLICATION AND TRANSPOSE 939 #if spSEPARATED_COMPLEX_VECTORS 941 --Solution; --iSolution;
943 RHS -= 2; Solution -= 2;
949 pExtOrder = &Matrix->IntToExtRowMap[Matrix->Size];
952 for (I = Matrix->Size; I > 0; I--)
954 Vector[
I].
Imag = iSolution[*(pExtOrder--)];
957 for (I = Matrix->Size; I > 0; I--)
961 pExtOrder = &Matrix->IntToExtColMap[Matrix->Size];
962 for (I = Matrix->Size; I > 0; I--)
963 { pElement = Matrix->FirstInCol[
I];
966 while (pElement !=
NULL)
972 #if spSEPARATED_COMPLEX_VECTORS 974 iRHS[*pExtOrder--] = Sum.
Imag;
1033 spDeterminant( eMatrix, pExponent, pDeterminant, piDeterminant )
1045 register int I,
Size;
1049 #define NORM(a) (nr = ABS((a).Real), ni = ABS((a).Imag), MAX (nr,ni)) 1056 { *pDeterminant = 0.0;
1058 if (Matrix->
Complex) *piDeterminant = 0.0;
1063 Size = Matrix->
Size;
1068 { cDeterminant.
Real = 1.0;
1069 cDeterminant.
Imag = 0.0;
1076 Norm = NORM( cDeterminant );
1078 {
while (Norm >= 1.0e12)
1079 { cDeterminant.
Real *= 1.0e-12;
1080 cDeterminant.
Imag *= 1.0e-12;
1082 Norm = NORM( cDeterminant );
1084 while (Norm < 1.0e-12)
1085 { cDeterminant.
Real *= 1.0e12;
1086 cDeterminant.
Imag *= 1.0e12;
1088 Norm = NORM( cDeterminant );
1094 Norm = NORM( cDeterminant );
1096 {
while (Norm >= 10.0)
1097 { cDeterminant.
Real *= 0.1;
1098 cDeterminant.
Imag *= 0.1;
1100 Norm = NORM( cDeterminant );
1103 { cDeterminant.
Real *= 10.0;
1104 cDeterminant.
Imag *= 10.0;
1106 Norm = NORM( cDeterminant );
1112 *pDeterminant = cDeterminant.
Real;
1113 *piDeterminant = cDeterminant.
Imag;
1116 #if REAL AND spCOMPLEX 1121 *pDeterminant = 1.0;
1124 { *pDeterminant /= Matrix->
Diag[
I]->
Real;
1127 if (*pDeterminant != 0.0)
1128 {
while (
ABS(*pDeterminant) >= 1.0e12)
1129 { *pDeterminant *= 1.0e-12;
1132 while (
ABS(*pDeterminant) < 1.0e-12)
1133 { *pDeterminant *= 1.0e12;
1140 if (*pDeterminant != 0.0)
1141 {
while (
ABS(*pDeterminant) >= 10.0)
1142 { *pDeterminant *= 0.1;
1145 while (
ABS(*pDeterminant) < 1.0)
1146 { *pDeterminant *= 10.0;
1151 *pDeterminant = -*pDeterminant;
1199 if (Matrix->
Fillins == 0)
return;
1211 while (pListNode !=
NULL)
1214 while (pFillin <= pLastFillin)
1215 (pFillin++)->Row = 0;
1216 pListNode = pListNode->
Next;
1222 register int I, Size = Matrix->
Size;
1225 for (I = 1; I <=
Size; I++)
1227 while ((pElement = *ppElement) !=
NULL)
1228 {
if (pElement->
Row == 0)
1230 if (Matrix->
Diag[pElement->
Col] == pElement)
1239 for (I = 1; I <=
Size; I++)
1241 while ((pElement = *ppElement) !=
NULL)
1242 {
if (pElement->
Row == 0)
1259 #if TRANSLATE AND DELETE 1302 int Size, ExtRow, ExtCol;
1308 ASSERT( Row <= Matrix->ExtSize
AND Col <= Matrix->ExtSize );
1310 Size = Matrix->
Size;
1340 while (pLastElement !=
NULL)
1342 while ((pElement = *ppElement) !=
NULL)
1343 {
if (pElement == pLastElement)
1353 while (pLastElement !=
NULL)
1355 while ((pElement = *ppElement) !=
NULL)
1356 {
if (pElement == pLastElement)
1365 Matrix->
Size = Size - 1;
1426 Diag = Matrix->
Diag;
1428 for (I = 2; I <= Matrix->
Size; I++)
1432 else if (Mag < MinPivot)
1436 return MaxPivot / MinPivot;
1511 register int I, K, Row;
1514 RealNumber E, Em, Wp, Wm, ASp, ASm, ASw, ASy, ASv, ASz, MaxY, ScaleFactor;
1521 *pError = Matrix->
Error;
1523 if (NormOfMatrix == 0.0)
1534 Size = Matrix->
Size;
1545 for (I = Size; I > 0; I--) T[I] = 0.0;
1556 for (I = 1; I <=
Size; I++)
1557 { pPivot = Matrix->
Diag[
I];
1558 if (T[I] < 0.0) Em = -
E;
else Em =
E;
1559 Wm = (Em + T[
I]) * pPivot->
Real;
1560 if (
ABS(Wm) > SLACK)
1561 { ScaleFactor = 1.0 /
MAX(
SQR( SLACK ),
ABS(Wm) );
1562 for (K = Size; K > 0; K--) T[K] *= ScaleFactor;
1565 Wm = (Em + T[
I]) * pPivot->
Real;
1567 Wp = (T[
I] - Em) * pPivot->
Real;
1568 ASp =
ABS(T[I] - Em);
1569 ASm =
ABS(Em + T[I]);
1573 while (pElement !=
NULL)
1574 { Row = pElement->
Row;
1575 Tm[Row] = T[Row] - (Wm * pElement->
Real);
1576 T[Row] -= (Wp * pElement->
Real);
1578 ASm +=
ABS(Tm[Row]);
1586 while (pElement !=
NULL)
1587 { T[pElement->
Row] = Tm[pElement->
Row];
1595 for (ASw = 0.0, I = Size; I > 0; I--) ASw +=
ABS(T[I]);
1596 ScaleFactor = 1.0 / (SLACK * ASw);
1597 if (ScaleFactor < 0.5)
1598 {
for (I = Size; I > 0; I--) T[I] *= ScaleFactor;
1603 for (I = Size; I >= 1; I--)
1605 while (pElement !=
NULL)
1606 { T[
I] -= pElement->
Real * T[pElement->
Col];
1609 if (
ABS(T[I]) > SLACK)
1610 { ScaleFactor = 1.0 /
MAX(
SQR( SLACK ),
ABS(T[I]) );
1611 for (K = Size; K > 0; K--) T[K] *= ScaleFactor;
1617 for (ASy = 0.0, I = Size; I > 0; I--) ASy +=
ABS(T[I]);
1618 ScaleFactor = 1.0 / (SLACK * ASy);
1619 if (ScaleFactor < 0.5)
1620 {
for (I = Size; I > 0; I--) T[I] *= ScaleFactor;
1626 for (MaxY = 0.0, I = Size; I > 0; I--)
1627 if (MaxY <
ABS(T[I])) MaxY =
ABS(T[I]);
1635 for (I = 1; I <=
Size; I++)
1637 while (pElement !=
NULL)
1638 { T[pElement->
Col] -= T[
I] * pElement->
Real;
1641 if (
ABS(T[I]) > SLACK)
1642 { ScaleFactor = 1.0 /
MAX(
SQR( SLACK ),
ABS(T[I]) );
1643 for (K = Size; K > 0; K--) T[K] *= ScaleFactor;
1649 for (ASv = 0.0, I = Size; I > 0; I--) ASv +=
ABS(T[I]);
1650 ScaleFactor = 1.0 / (SLACK * ASv);
1651 if (ScaleFactor < 0.5)
1652 {
for (I = Size; I > 0; I--) T[I] *= ScaleFactor;
1657 for (I = Size; I >= 1; I--)
1658 { pPivot = Matrix->
Diag[
I];
1660 while (pElement !=
NULL)
1661 { T[
I] -= pElement->
Real * T[pElement->
Row];
1664 T[
I] *= pPivot->
Real;
1665 if (
ABS(T[I]) > SLACK)
1666 { ScaleFactor = 1.0 /
MAX(
SQR( SLACK ),
ABS(T[I]) );
1667 for (K = Size; K > 0; K--) T[K] *= ScaleFactor;
1673 for (ASz = 0.0, I = Size; I > 0; I--) ASz +=
ABS(T[I]);
1679 Linpack = ASy / ASz;
1681 InvNormOfInverse =
MIN( Linpack, OLeary );
1682 return InvNormOfInverse / NormOfMatrix;
1721 register int I, K, Row;
1724 RealNumber E, Em, ASp, ASm, ASw, ASy, ASv, ASz, MaxY, ScaleFactor;
1725 RealNumber Linpack, OLeary, InvNormOfInverse;
1730 Size = Matrix->Size;
1737 for (I = Size; I > 0; I--) T[I].Real = T[I].Imag = 0.0;
1748 for (I = 1; I <=
Size; I++)
1749 { pPivot = Matrix->Diag[
I];
1750 if (T[I].Real < 0.0) Em = -
E;
else Em =
E;
1770 while (pElement !=
NULL)
1771 { Row = pElement->
Row;
1785 while (pElement !=
NULL)
1786 { T[pElement->
Row] = Tm[pElement->
Row];
1794 for (ASw = 0.0, I = Size; I > 0; I--) ASw +=
CMPLX_1_NORM(T[I]);
1795 ScaleFactor = 1.0 / (SLACK * ASw);
1796 if (ScaleFactor < 0.5)
1802 for (I = Size; I >= 1; I--)
1804 while (pElement !=
NULL)
1817 for (ASy = 0.0, I = Size; I > 0; I--) ASy +=
CMPLX_1_NORM(T[I]);
1818 ScaleFactor = 1.0 / (SLACK * ASy);
1819 if (ScaleFactor < 0.5)
1826 for (MaxY = 0.0, I = Size; I > 0; I--)
1835 for (I = 1; I <=
Size; I++)
1837 while (pElement !=
NULL)
1850 for (ASv = 0.0, I = Size; I > 0; I--) ASv +=
CMPLX_1_NORM(T[I]);
1851 ScaleFactor = 1.0 / (SLACK * ASv);
1852 if (ScaleFactor < 0.5)
1858 for (I = Size; I >= 1; I--)
1859 { pPivot = Matrix->Diag[
I];
1861 while (pElement !=
NULL)
1875 for (ASz = 0.0, I = Size; I > 0; I--) ASz +=
CMPLX_1_NORM(T[I]);
1879 Linpack = ASy / ASz;
1881 InvNormOfInverse =
MIN( Linpack, OLeary );
1882 return InvNormOfInverse / NormOfMatrix;
1923 {
for (I = Matrix->
Size; I > 0; I--)
1926 while (pElement !=
NULL)
1927 { AbsRowSum +=
ABS( pElement->
Real );
1930 if (Max < AbsRowSum) Max = AbsRowSum;
1936 {
for (I = Matrix->
Size; I > 0; I--)
1939 while (pElement !=
NULL)
1943 if (Max < AbsRowSum) Max = AbsRowSum;
2030 RealNumber Mag, AbsColSum, Max = 0.0, MaxRow = 0.0, MaxCol = 0.0;
2043 for (I = 1; I <= Matrix->
Size; I++)
2044 { pDiag = Matrix->
Diag[
I];
2047 Pivot = 1.0 / pDiag->
Real;
2049 if (Mag > MaxRow) MaxRow = Mag;
2051 while (pElement != pDiag)
2052 { Mag =
ABS( pElement->
Real );
2053 if (Mag > MaxRow) MaxRow = Mag;
2060 while (pElement != pDiag)
2061 { AbsColSum +=
ABS( pElement->
Real );
2064 if (AbsColSum > MaxCol) MaxCol = AbsColSum;
2068 {
for (I = 1; I <= Matrix->
Size; I++)
2070 while (pElement !=
NULL)
2071 { Mag =
ABS( pElement->
Real );
2072 if (Mag > Max) Max = Mag;
2084 for (I = 1; I <= Matrix->
Size; I++)
2085 { pDiag = Matrix->
Diag[
I];
2090 if (Mag > MaxRow) MaxRow = Mag;
2092 while (pElement != pDiag)
2094 if (Mag > MaxRow) MaxRow = Mag;
2101 while (pElement != pDiag)
2105 if (AbsColSum > MaxCol) MaxCol = AbsColSum;
2109 {
for (I = 1; I <= Matrix->
Size; I++)
2111 while (pElement !=
NULL)
2113 if (Mag > Max) Max = Mag;
2120 return MaxRow * MaxCol;
2150 register int Count,
I, MaxCount = 0;
2161 {
for (I = Matrix->
Size; I > 0; I--)
2164 while (pElement->
Col < I)
2168 if (Count > MaxCount) MaxCount = Count;
2175 Gear = 1.01*((MaxCount + 1) * Matrix->
RelThreshold + 1.0) *
SQR(MaxCount);
2176 Reid = 3.01 * Matrix->
Size;
2179 return (MACHINE_RESOLUTION * Rho * Gear);
2181 return (MACHINE_RESOLUTION * Rho * Reid);
2210 spErrorMessage( eMatrix, Stream, Originator )
2212 char *eMatrix, *Originator;
2215 int Row, Col, Error;
2218 if (eMatrix ==
NULL)
2225 if (Error ==
spOKAY)
return;
2226 if (Originator ==
NULL) Originator =
"sparse";
2227 if (Originator[0] !=
'\0') fprintf( Stream,
"%s: ", Originator);
2229 fprintf( Stream,
"fatal error, ");
2231 fprintf( Stream,
"warning, ");
2237 fprintf( Stream,
"Sparse called improperly.\n");
2239 fprintf( Stream,
"insufficient memory available.\n");
2242 fprintf( Stream,
"singular matrix detected at row %d and column %d.\n",
2247 fprintf( Stream,
"zero diagonal detected at row %d and column %d.\n",
2252 "unable to find a pivot that is larger than absolute threshold.\n");
#define CMPLX_MULT_ASSIGN(to, from)
ElementPtr NextAvailFillin
#define ALLOC(type, number)
#define CMPLX_MULT_SUBT(to, mult_a, mult_b, subt)
ArrayOfElementPtrs FirstInRow
#define IS_FACTORED(matrix)
#define spSEPARATED_COMPLEX_VECTORS
int NumberOfFillinsInList
#define Max(Dragon, Eagle)
struct FillinListNodeStruct * FirstFillinListNode
This document describes the JSPICE3 Josephson junction model I derivation of the model The expression for the junction current is J
struct ComplexNumber * ComplexVector
#define IS_SPARSE(matrix)
RealVector Solution IMAG_VECTORS
BOOLEAN NumberOfInterchangesIsOdd
#define CMPLX_MULT_SUBT_ASSIGN(to, from_a, from_b)
void spcCreateInternalVectors()
struct MatrixElement * NextInCol
struct FillinListNodeStruct * LastFillinListNode
ASSERT(IS_VALID(Matrix) AND IS_FACTORED(Matrix))
register ElementPtr pElement
#define CMPLX_MULT_ADD_ASSIGN(to, from_a, from_b)
ElementPtr spcFindElementInCol()
static void ComplexMatrixMultiply()
#define SCLR_MULT_ASSIGN(to, sclr)
spREAL spPseudoCondition()
static void ScaleComplexMatrix()
static void ComplexTransposedMatrixMultiply()
spREAL spLargestElement()
BOOLEAN InternalVectorsAllocated
struct MatrixElement * NextInRow
struct MatrixFrame * MatrixPtr
struct FillinListNodeStruct * Next
static RealNumber ComplexCondition()
int MaxRowCountInLowerTri
ArrayOfElementPtrs FirstInCol
#define CMPLX_RECIPROCAL(to, den)