57 #define spINSIDE_SPARSE
167 int Twins, StartAt = 1;
168 BOOLEAN Swapped, AnotherPassNeeded;
179 AnotherPassNeeded = Swapped =
NO;
182 for (J = StartAt; J <= Size; J++) {
188 }
else if ((Twins > 1)
AND NOT AnotherPassNeeded) {
189 AnotherPassNeeded =
YES;
196 if (AnotherPassNeeded) {
197 for (J = StartAt;
NOT Swapped
AND(J <= Size); J++) {
205 }
while (AnotherPassNeeded);
224 pTwin1 =
Matrix->FirstInCol[Col];
225 while (pTwin1 !=
NULL) {
226 if (
ABS(pTwin1->
Real) == 1.0) {
228 pTwin2 =
Matrix->FirstInCol[Row];
229 while ((pTwin2 !=
NULL)
AND(pTwin2->
Row != Col))
234 (*ppTwin1 = pTwin1)->Col = Col;
235 (*ppTwin2 = pTwin2)->Col = Row;
252 int Col1 = pTwin1->
Col, Col2 = pTwin2->
Col;
259 Matrix->Diag[Col1] = pTwin2;
260 Matrix->Diag[Col2] = pTwin1;
261 Matrix->NumberOfInterchangesIsOdd =
NOT Matrix->NumberOfInterchangesIsOdd;
327 int I, lSize, *pExtOrder;
341 --SolutionScaleFactors;
345 pExtOrder = &
Matrix->IntToExtRowMap[1];
346 for (I = 1; I <= lSize; I++) {
347 if ((ScaleFactor = RHS_ScaleFactors[*(pExtOrder++)]) != 1.0) {
348 pElement =
Matrix->FirstInRow[I];
350 while (pElement !=
NULL) {
351 pElement->
Real *= ScaleFactor;
358 pExtOrder = &
Matrix->IntToExtColMap[1];
359 for (I = 1; I <= lSize; I++) {
360 if ((ScaleFactor = SolutionScaleFactors[*(pExtOrder++)]) != 1.0) {
361 pElement =
Matrix->FirstInCol[I];
363 while (pElement !=
NULL) {
364 pElement->
Real *= ScaleFactor;
422 Vector =
Matrix->Intermediate;
424 for (I =
Matrix->Size; I > 0; I--)
425 Vector[I] = Solution[*(pExtOrder--)];
428 for (I =
Matrix->Size; I > 0; I--) {
429 pElement =
Matrix->FirstInRow[I];
432 while (pElement !=
NULL) {
433 Sum += pElement->
Real * Vector[pElement->
Col];
436 RHS[*pExtOrder--] = Sum;
443 #if MULTIPLICATION AND TRANSPOSE
488 Vector =
Matrix->Intermediate;
490 for (I =
Matrix->Size; I > 0; I--)
491 Vector[I] = Solution[*(pExtOrder--)];
494 for (I =
Matrix->Size; I > 0; I--) {
495 pElement =
Matrix->FirstInCol[I];
498 while (pElement !=
NULL) {
499 Sum += pElement->
Real * Vector[pElement->
Row];
502 RHS[*pExtOrder--] = Sum;
570 while (++I <= Size) {
571 *pDeterminant /=
Matrix->Diag[I]->Real;
574 if (*pDeterminant != 0.0) {
575 while (
ABS(*pDeterminant) >= 1.0e12) {
576 *pDeterminant *= 1.0e-12;
579 while (
ABS(*pDeterminant) < 1.0e-12) {
580 *pDeterminant *= 1.0e12;
587 if (*pDeterminant != 0.0) {
588 while (
ABS(*pDeterminant) >= 10.0) {
589 *pDeterminant *= 0.1;
592 while (
ABS(*pDeterminant) < 1.0) {
593 *pDeterminant *= 10.0;
597 if (
Matrix->NumberOfInterchangesIsOdd)
598 *pDeterminant = -*pDeterminant;
646 pListNode =
Matrix->LastFillinListNode =
Matrix->FirstFillinListNode;
650 while (pListNode !=
NULL) {
653 while (pFillin <= pLastFillin)
654 (pFillin++)->Row = 0;
655 pListNode = pListNode->
Next;
662 int I, Size =
Matrix->Size;
665 for (I = 1; I <= Size; I++) {
666 ppElement = &(
Matrix->FirstInCol[I]);
667 while ((pElement = *ppElement) !=
NULL) {
668 if (pElement->
Row == 0) {
670 if (
Matrix->Diag[pElement->
Col] == pElement)
678 for (I = 1; I <= Size; I++) {
679 ppElement = &(
Matrix->FirstInRow[I]);
680 while ((pElement = *ppElement) !=
NULL) {
681 if (pElement->
Row == 0)
733 for (I = 2; I <=
Matrix->Size; I++) {
737 else if (Mag < MinPivot)
741 return MaxPivot / MinPivot;
807 RealNumber E, Em, Wp, Wm, ASp, ASm, ASw, ASy, ASv, ASz, MaxY, ScaleFactor;
817 if (NormOfMatrix == 0.0) {
830 for (I = Size; I > 0; I--)
842 for (I = 1; I <= Size; I++) {
848 Wm = (Em + T[I]) * pPivot->
Real;
851 for (
K = Size;
K > 0;
K--)
855 Wm = (Em + T[I]) * pPivot->
Real;
857 Wp = (T[I] - Em) * pPivot->
Real;
858 ASp =
ABS(T[I] - Em);
859 ASm =
ABS(Em + T[I]);
863 while (pElement !=
NULL) {
865 Tm[Row] = T[Row] - (Wm * pElement->
Real);
866 T[Row] -= (Wp * pElement->
Real);
876 while (pElement !=
NULL) {
877 T[pElement->
Row] = Tm[pElement->
Row];
885 for (ASw = 0.0, I = Size; I > 0; I--)
887 ScaleFactor = 1.0 / (
SLACK * ASw);
888 if (ScaleFactor < 0.5) {
889 for (I = Size; I > 0; I--)
895 for (I = Size; I >= 1; I--) {
896 pElement =
Matrix->Diag[I]->NextInRow;
897 while (pElement !=
NULL) {
898 T[I] -= pElement->
Real * T[pElement->
Col];
903 for (
K = Size;
K > 0;
K--)
910 for (ASy = 0.0, I = Size; I > 0; I--)
912 ScaleFactor = 1.0 / (
SLACK * ASy);
913 if (ScaleFactor < 0.5) {
914 for (I = Size; I > 0; I--)
921 for (MaxY = 0.0, I = Size; I > 0; I--)
922 if (MaxY <
ABS(T[I]))
931 for (I = 1; I <= Size; I++) {
932 pElement =
Matrix->Diag[I]->NextInRow;
933 while (pElement !=
NULL) {
934 T[pElement->
Col] -= T[I] * pElement->
Real;
939 for (
K = Size;
K > 0;
K--)
946 for (ASv = 0.0, I = Size; I > 0; I--)
948 ScaleFactor = 1.0 / (
SLACK * ASv);
949 if (ScaleFactor < 0.5) {
950 for (I = Size; I > 0; I--)
956 for (I = Size; I >= 1; I--) {
959 while (pElement !=
NULL) {
960 T[I] -= pElement->
Real * T[pElement->
Row];
963 T[I] *= pPivot->
Real;
966 for (
K = Size;
K > 0;
K--)
973 for (ASz = 0.0, I = Size; I > 0; I--)
980 InvNormOfInverse =
MIN(Linpack, OLeary);
981 return InvNormOfInverse / NormOfMatrix;
1015 for (I =
Matrix->Size; I > 0; I--) {
1016 pElement =
Matrix->FirstInRow[I];
1018 while (pElement !=
NULL) {
1019 AbsRowSum +=
ABS(pElement->
Real);
1022 if (Max < AbsRowSum)
1101 RealNumber Mag, AbsColSum, Max = 0.0, MaxRow = 0.0, MaxCol = 0.0;
1114 for (I = 1; I <=
Matrix->Size; I++) {
1118 Pivot = 1.0 / pDiag->
Real;
1122 pElement =
Matrix->FirstInRow[I];
1123 while (pElement != pDiag) {
1131 pElement =
Matrix->FirstInCol[I];
1133 while (pElement != pDiag) {
1134 AbsColSum +=
ABS(pElement->
Real);
1137 if (AbsColSum > MaxCol)
1141 for (I = 1; I <=
Matrix->Size; I++) {
1142 pElement =
Matrix->FirstInCol[I];
1143 while (pElement !=
NULL) {
1153 return MaxRow * MaxCol;
1176 int Count, I, MaxCount = 0;
1187 if (
Matrix->MaxRowCountInLowerTri < 0) {
1188 for (I =
Matrix->Size; I > 0; I--) {
1189 pElement =
Matrix->FirstInRow[I];
1191 while (pElement->
Col < I) {
1195 if (Count > MaxCount)
1198 Matrix->MaxRowCountInLowerTri = MaxCount;
1200 MaxCount =
Matrix->MaxRowCountInLowerTri;
1203 Gear = 1.01 * ((MaxCount + 1) *
Matrix->RelThreshold + 1.0) *
SQR(MaxCount);
1204 Reid = 3.01 *
Matrix->Size;
1207 return (DBL_EPSILON * Rho * Gear);
1209 return (DBL_EPSILON * Rho * Reid);
#define ALLOC(type, number)
struct MatrixFrame * MatrixPtr
#define IS_FACTORED(matrix)
#define ASSERT(condition)
#define IS_SPARSE(matrix)
void spcRowExchange(MatrixPtr, int row1, int row2)
ElementPtr spcFindElementInCol(MatrixPtr Matrix, ElementPtr *LastAddr, int Row, int Col, BOOLEAN CreateIfMissing)
void spDeterminant(char *eMatrix, int *pExponent, RealNumber *pDeterminant, std::optional< RealNumber * > piDeterminant)
static void SwapCols(MatrixPtr Matrix, ElementPtr pTwin1, ElementPtr pTwin2)
RealNumber spCondition(char *eMatrix, RealNumber NormOfMatrix, int *pError)
static int CountTwins(MatrixPtr Matrix, int Col, ElementPtr *ppTwin1, ElementPtr *ppTwin2)
void spcColExchange(MatrixPtr, int col1, int col2)
void spMultTransposed(char *eMatrix, RealVector RHS, RealVector Solution, std::optional< RealVector > iRHS, std::optional< RealVector > iSolution)
void spScale(char *eMatrix, RealVector RHS_ScaleFactors, RealVector SolutionScaleFactors)
RealNumber spLargestElement(char *eMatrix)
void spStripFills(char *eMatrix)
void spcLinkRows(MatrixPtr)
void spMNA_Preorder(char *eMatrix)
RealNumber spRoundoff(char *eMatrix, RealNumber Rho)
RealNumber spNorm(char *eMatrix)
RealNumber spPseudoCondition(char *eMatrix)
void spMultiply(char *eMatrix, RealVector RHS, RealVector Solution, std::optional< RealVector > iRHS, std::optional< RealVector > iSolution)
int NumberOfFillinsInList
struct FillinListNodeStruct * Next
struct MatrixElement * NextInCol
struct MatrixElement * NextInRow