2 #include <../../nrnconf.h>
52 "Sparse1.3: Copyright (c) 1985,86,87,88 by Kenneth S. Kundert";
71 #define spINSIDE_SPARSE
205 int Step,
Size, ReorderingRequired;
218 ReorderingRequired =
NO;
223 for (Step = 1; Step <=
Size; Step++)
233 { ReorderingRequired =
YES;
237 if (
NOT ReorderingRequired)
246 #if ANNOTATE >= ON_STRANGE_BEHAVIOR
247 printf(
"Reordering, Step = %1d\n", Step);
274 for (; Step <=
Size; Step++)
288 WriteStatus(
Matrix, Step );
345 register int Step,
Size;
353 0.0, 0.0, DIAG_PIVOTING_AS_DEFAULT );
367 for (Step = 2; Step <=
Size; Step++)
381 while (pColumn->
Row < Step)
413 while (pColumn->
Row < Step)
464 register int Step,
Size;
477 for (Step = 2; Step <=
Size; Step++)
492 while (pColumn->
Row < Step)
530 while (pColumn->
Row < Step)
604 register int Step,
Size;
605 register int *Nc, *No, *Nm;
606 BOOLEAN *DoRealDirect, *DoCmplxDirect;
619 {
for (Step = 1; Step <=
Size; Step++)
621 DoRealDirect[Step] =
YES;
624 DoCmplxDirect[Step] =
YES;
629 {
for (Step = 1; Step <=
Size; Step++)
631 DoRealDirect[Step] =
NO;
634 DoCmplxDirect[Step] =
NO;
646 for (Step = 1; Step <=
Size; Step++)
647 { Nc[Step] = No[Step] = Nm[Step] = 0;
656 while (pColumn->
Row < Step)
665 for (Step = 1; Step <=
Size; Step++)
682 DoRealDirect[Step] = (Nm[Step] + No[Step] > 3*Nc[Step] - 2*Nm[Step]);
686 DoCmplxDirect[Step] =
NO;
693 DoRealDirect[Step] = (Nm[Step] + No[Step] > 3*Nc[Step] - 2*Nm[Step]);
696 DoCmplxDirect[Step] = (Nm[Step] + No[Step] > 7*Nc[Step] - 4*Nm[Step]);
703 DoRealDirect[Step] = (Nm[Step] + No[Step] > 3*Nc[Step] - 2*Nm[Step]);
706 DoCmplxDirect[Step] = (Nm[Step] + No[Step] > 7*Nc[Step] - 4*Nm[Step]);
712 #if (ANNOTATE == FULL)
714 for (Step = 1; Step <=
Size; Step++)
716 printf(
"Operation count for inner loop of factorization = %d.\n", Ops);
849 #if spSEPARATED_COMPLEX_VECTORS OR NOT spCOMPLEX
875 #if spSEPARATED_COMPLEX_VECTORS OR NOT spCOMPLEX
877 if (
RHS[ExtRow] != 0.0) Count++;
881 {
if ((
RHS[2*ExtRow] != 0.0)
OR (
RHS[2*ExtRow+1] != 0.0))
884 else if (
RHS[
I] != 0.0) Count++;
950 register int I, *pMarkowitzRow, *pMarkowitzCol;
951 register long Product, *pMarkowitzProduct;
965 if ((*pMarkowitzRow > LARGEST_SHORT_INTEGER
AND *pMarkowitzCol != 0)
OR
966 (*pMarkowitzCol > LARGEST_SHORT_INTEGER
AND *pMarkowitzRow != 0))
967 { fProduct = (double)(*pMarkowitzRow++) * (double)(*pMarkowitzCol++);
968 if (fProduct >= LARGEST_LONG_INTEGER)
969 *pMarkowitzProduct++ = LARGEST_LONG_INTEGER;
971 *pMarkowitzProduct++ = fProduct;
974 { Product = *pMarkowitzRow++ * *pMarkowitzCol++;
975 if ((*pMarkowitzProduct++ = Product) == 0)
1035 int Step, DiagPivoting;
1048 if (ChosenPivot !=
NULL)
1054 #if DIAGONAL_PIVOTING
1064 if (ChosenPivot !=
NULL)
1074 if (ChosenPivot !=
NULL)
1140 register long *pMarkowitzProduct;
1160 while (Singletons-- > 0)
1183 while ( *pMarkowitzProduct-- )
1194 if (
I < Step)
break;
1206 )
return ChosenPivot;
1213 while ((ChosenPivot !=
NULL)
AND (ChosenPivot->
Row < Step))
1221 )
return ChosenPivot;
1225 while((ChosenPivot !=
NULL)
AND (ChosenPivot->
Col<Step))
1234 )
return ChosenPivot;
1240 while ((ChosenPivot !=
NULL)
AND (ChosenPivot->
Col < Step))
1248 )
return ChosenPivot;
1273 #if DIAGONAL_PIVOTING
1274 #if MODIFIED_MARKOWITZ
1348 register long MinMarkowitzProduct, *pMarkowitzProduct;
1349 register ElementPtr pDiag, pOtherInRow, pOtherInCol;
1350 int I, NumberOfTies;
1351 ElementPtr ChosenPivot, TiedElements[MAX_MARKOWITZ_TIES + 1];
1352 RealNumber Magnitude, LargestInCol, Ratio, MaxRatio;
1358 MinMarkowitzProduct = LARGEST_LONG_INTEGER;
1385 {
while (MinMarkowitzProduct < *(--pMarkowitzProduct))
1397 if (
I < Step)
break;
1405 if (*pMarkowitzProduct == 1)
1414 while(pOtherInRow !=
NULL)
1415 {
if (pOtherInRow->
Col >= Step
AND pOtherInRow->
Col !=
I)
1420 while(pOtherInCol !=
NULL)
1421 {
if (pOtherInCol->
Row >= Step
AND pOtherInCol->
Row !=
I)
1430 {
if (pOtherInRow->
Col == pOtherInCol->
Row)
1433 if (Magnitude >= LargestOffDiagonal)
1442 if (*pMarkowitzProduct < MinMarkowitzProduct)
1445 TiedElements[0] = pDiag;
1446 MinMarkowitzProduct = *pMarkowitzProduct;
1452 if (NumberOfTies < MAX_MARKOWITZ_TIES)
1453 { TiedElements[++NumberOfTies] = pDiag;
1454 if (NumberOfTies >= MinMarkowitzProduct * TIES_MULTIPLIER)
1461 if (NumberOfTies < 0)
1468 for (
I = 0;
I <= NumberOfTies;
I++)
1469 { pDiag = TiedElements[
I];
1472 Ratio = LargestInCol / Magnitude;
1473 if (Ratio < MaxRatio)
1474 { ChosenPivot = pDiag;
1547 register long MinMarkowitzProduct, *pMarkowitzProduct;
1550 ElementPtr ChosenPivot, pOtherInRow, pOtherInCol;
1551 RealNumber Magnitude, LargestInCol, LargestOffDiagonal;
1556 MinMarkowitzProduct = LARGEST_LONG_INTEGER;
1583 {
while (*(--pMarkowitzProduct) >= MinMarkowitzProduct)
1590 if (
I < Step)
break;
1598 if (*pMarkowitzProduct == 1)
1607 while(pOtherInRow !=
NULL)
1608 {
if (pOtherInRow->
Col >= Step
AND pOtherInRow->
Col !=
I)
1613 while(pOtherInCol !=
NULL)
1614 {
if (pOtherInCol->
Row >= Step
AND pOtherInCol->
Row !=
I)
1623 {
if (pOtherInRow->
Col == pOtherInCol->
Row)
1626 if (Magnitude >= LargestOffDiagonal)
1635 MinMarkowitzProduct = *pMarkowitzProduct;
1636 ChosenPivot = pDiag;
1639 if (ChosenPivot !=
NULL)
1713 register long MinMarkowitzProduct, *pMarkowitzProduct;
1718 RealNumber Magnitude, Ratio, RatioOfAccepted=0.0, LargestInCol;
1723 MinMarkowitzProduct = LARGEST_LONG_INTEGER;
1728 for (J =
Size+1; J > Step; J--)
1730 if (*(--pMarkowitzProduct) > MinMarkowitzProduct)
1743 if (Magnitude <= Matrix->RelThreshold * LargestInCol)
1746 if (*pMarkowitzProduct < MinMarkowitzProduct)
1749 ChosenPivot = pDiag;
1750 MinMarkowitzProduct = *pMarkowitzProduct;
1751 RatioOfAccepted = LargestInCol / Magnitude;
1758 Ratio = LargestInCol / Magnitude;
1759 if (Ratio < RatioOfAccepted)
1760 { ChosenPivot = pDiag;
1761 RatioOfAccepted = Ratio;
1763 if (NumberOfTies >= MinMarkowitzProduct * TIES_MULTIPLIER)
1844 long Product, MinMarkowitzProduct;
1846 RealNumber Magnitude, LargestElementMag, Ratio, RatioOfAccepted=0.0, LargestInCol;
1851 LargestElementMag = 0.0;
1852 MinMarkowitzProduct = LARGEST_LONG_INTEGER;
1855 for (
I = Step;
I <=
Size;
I++)
1869 { LargestElementMag = Magnitude;
1877 if ((Product <= MinMarkowitzProduct)
AND
1883 if (Product < MinMarkowitzProduct)
1887 MinMarkowitzProduct = Product;
1888 RatioOfAccepted = LargestInCol / Magnitude;
1895 Ratio = LargestInCol / Magnitude;
1896 if (Ratio < RatioOfAccepted)
1898 RatioOfAccepted = Ratio;
1900 if (NumberOfTies >= MinMarkowitzProduct * TIES_MULTIPLIER)
1908 if (ChosenPivot !=
NULL)
return ChosenPivot;
1910 if (LargestElementMag == 0.0)
1916 return pLargestElement;
1969 Largest = Magnitude;
2054 Largest = Magnitude;
2111 register int Row, Col;
2112 long OldMarkowitzProd_Step, OldMarkowitzProd_Row, OldMarkowitzProd_Col;
2121 if ((Row == Step)
AND (Col == Step))
return;
2148 {
if (OldMarkowitzProd_Row == 0)
2165 {
if (OldMarkowitzProd_Col == 0)
2188 {
if (OldMarkowitzProd_Step == 0)
2244 if (Row1 > Row2)
SWAP(
int, Row1, Row2);
2251 if (Row1Ptr ==
NULL)
2252 { Column = Row2Ptr->
Col;
2257 else if (Row2Ptr ==
NULL)
2258 { Column = Row1Ptr->
Col;
2263 else if (Row1Ptr->
Col < Row2Ptr->
Col)
2264 { Column = Row1Ptr->
Col;
2269 else if (Row1Ptr->
Col > Row2Ptr->
Col)
2270 { Column = Row2Ptr->
Col;
2276 { Column = Row1Ptr->
Col;
2345 if (Col1 > Col2)
SWAP(
int, Col1, Col2);
2352 if (Col1Ptr ==
NULL)
2353 { Row = Col2Ptr->
Row;
2358 else if (Col2Ptr ==
NULL)
2359 { Row = Col1Ptr->
Row;
2364 else if (Col1Ptr->
Row < Col2Ptr->
Row)
2365 { Row = Col1Ptr->
Row;
2370 else if (Col1Ptr->
Row > Col2Ptr->
Row)
2371 { Row = Col2Ptr->
Row;
2377 { Row = Col1Ptr->
Row;
2446 int Row1, Row2, Column;
2448 ElementPtr *ElementAboveRow1, *ElementAboveRow2;
2449 ElementPtr ElementBelowRow1, ElementBelowRow2;
2460 if (Element1 !=
NULL)
2461 { ElementBelowRow1 = Element1->
NextInCol;
2462 if (Element2 ==
NULL)
2465 if ( ElementBelowRow1 !=
NULL AND ElementBelowRow1->
Row < Row2 )
2468 *ElementAboveRow1 = ElementBelowRow1;
2478 *ElementAboveRow2 = Element1;
2480 *ElementAboveRow1 =ElementBelowRow1;
2482 Element1->
Row = Row2;
2487 if ( ElementBelowRow1->
Row == Row2)
2492 *ElementAboveRow1 = Element2;
2506 *ElementAboveRow1 = Element2;
2508 *ElementAboveRow2 = Element1;
2511 Element1->
Row = Row2;
2512 Element2->
Row = Row1;
2521 if (ElementBelowRow1->
Row != Row2)
2530 *ElementAboveRow2 = Element2->
NextInCol;
2531 *ElementAboveRow1 = Element2;
2534 Element2->
Row = Row1;
2587 int Col1, Col2, Row;
2590 ElementPtr *ElementLeftOfCol1, *ElementLeftOfCol2;
2591 ElementPtr ElementRightOfCol1, ElementRightOfCol2;
2602 if (Element1 !=
NULL)
2603 { ElementRightOfCol1 = Element1->
NextInRow;
2604 if (Element2 ==
NULL)
2607 if ( ElementRightOfCol1 !=
NULL AND ElementRightOfCol1->
Col < Col2 )
2610 *ElementLeftOfCol1 = ElementRightOfCol1;
2620 *ElementLeftOfCol2 = Element1;
2622 *ElementLeftOfCol1 =ElementRightOfCol1;
2624 Element1->
Col = Col2;
2629 if ( ElementRightOfCol1->
Col == Col2)
2634 *ElementLeftOfCol1 = Element2;
2645 ElementRightOfCol2 = Element2->
NextInRow;
2648 *ElementLeftOfCol1 = Element2;
2649 Element2->
NextInRow = ElementRightOfCol1;
2650 *ElementLeftOfCol2 = Element1;
2651 Element1->
NextInRow = ElementRightOfCol2;
2653 Element1->
Col = Col2;
2654 Element2->
Col = Col1;
2663 if (ElementRightOfCol1->
Col != Col2)
2669 ElementRightOfCol2 = Element2->
NextInRow;
2672 *ElementLeftOfCol2 = Element2->
NextInRow;
2673 *ElementLeftOfCol1 = Element2;
2674 Element2->
NextInRow = ElementRightOfCol1;
2676 Element2->
Col = Col1;
2740 while (pUpper !=
NULL)
2747 while (pLower !=
NULL)
2748 { Row = pLower->
Row;
2829 while (pUpper !=
NULL)
2837 while (pLower !=
NULL)
2838 { Row = pLower->
Row;
2897 register int Row, Col;
2906 { Row = ColPtr->
Row;
2910 if ((MarkoRow[Row] > LARGEST_SHORT_INTEGER
AND MarkoCol[Row] != 0)
OR
2911 (MarkoCol[Row] > LARGEST_SHORT_INTEGER
AND MarkoRow[Row] != 0))
2912 { Product = MarkoCol[Row] * MarkoRow[Row];
2913 if (Product >= LARGEST_LONG_INTEGER)
2919 if (MarkoRow[Row] == 0)
2924 { Col = RowPtr->
Col;
2928 if ((MarkoRow[Col] > LARGEST_SHORT_INTEGER
AND MarkoCol[Col] != 0)
OR
2929 (MarkoCol[Col] > LARGEST_SHORT_INTEGER
AND MarkoRow[Col] != 0))
2930 { Product = MarkoCol[Col] * MarkoRow[Col];
2931 if (Product >= LARGEST_LONG_INTEGER)
2937 if ((MarkoCol[Col] == 0)
AND (MarkoRow[Col] != 0))
3073 #if ANNOTATE == FULL
3082 static void WriteStatus(
Matrix, Step )
3091 printf(
"Step = %1d ", Step);
3095 {
case 's':
printf(
"SearchForSingleton\n");
break;
3096 case 'q':
printf(
"QuicklySearchDiagonal\n");
break;
3097 case 'd':
printf(
"SearchDiagonal\n");
break;
3098 case 'e':
printf(
"SearchEntireMatrix\n");
break;
3101 printf(
"MarkowitzRow = ");
3106 printf(
"MarkowitzCol = ");
3111 printf(
"MarkowitzProduct = ");
3118 printf(
"IntToExtRowMap = ");
3123 printf(
"IntToExtColMap = ");
3128 printf(
"ExtToIntRowMap = ");
3133 printf(
"ExtToIntColMap = ");
ElementPtr spcFindElementInCol(MatrixPtr Matrix, ElementPtr *LastAddr, int Row, int Col, BOOLEAN CreateIfMissing)
ElementPtr spcCreateElement(MatrixPtr Matrix, int Row, int Col, ElementPtr *LastAddr, BOOLEAN Fillin)
#define CMPLX_MULT_ASSIGN(to, from)
#define ALLOC(type, number)
#define CMPLX_MULT(to, from_a, from_b)
struct MatrixFrame * MatrixPtr
#define CMPLX_RECIPROCAL(to, den)
#define ASSERT(condition)
#define CMPLX_ASSIGN(to, from)
#define CMPLX_MULT_SUBT_ASSIGN(to, from_a, from_b)
#define IS_SPARSE(matrix)
int spOrderAndFactor(char *eMatrix, RHS, RelThreshold, AbsThreshold, BOOLEAN DiagPivoting)
static ElementPtr QuicklySearchDiagonal()
static RealNumber FindLargestInCol()
static int FactorComplexMatrix()
void spPartition(char *eMatrix, int Mode)
static ElementPtr CreateFillin()
static ElementPtr SearchEntireMatrix()
static RealNumber FindBiggestInColExclude()
static void MarkowitzProducts()
static ElementPtr SearchForPivot()
int spFactor(char *eMatrix)
static void ExchangeRowElements()
static void ComplexRowColElimination()
static void UpdateMarkowitzNumbers()
static void CreateInternalVectors()
static ElementPtr SearchForSingleton()
void spcLinkRows(MatrixPtr)
static void CountMarkowitz()
static void ExchangeColElements()
static ElementPtr SearchDiagonal()
static void ExchangeRowsAndCols()
static void RealRowColElimination()
static int MatrixIsSingular()
#define spINDIRECT_PARTITION
#define spDIRECT_PARTITION
#define spDEFAULT_PARTITION
register ElementPtr pElement
struct MatrixElement * NextInCol
struct MatrixElement * NextInRow
int MaxRowCountInLowerTri
BOOLEAN InternalVectorsAllocated
BOOLEAN NumberOfInterchangesIsOdd
ArrayOfElementPtrs FirstInCol
char PivotSelectionMethod
ArrayOfElementPtrs FirstInRow