factorns.c
来自「电力系统分析计算 学习调试程序 UNIX / LINUX / CYGWIN 系统」· C语言 代码 · 共 616 行 · 第 1/2 页
C
616 行
INDEX GetLowval() { INDEX Iget; VALENCE ValGet; /* BEGIN */ ValGet = 0; do { Iget = ValClass[ValGet]; ValGet++; } while (Iget == 0); UNLinkVal(Iget); return(Iget); }#ifdef ANSIPROTO VALENCE ColumnValence(INDEX Col)#else VALENCE ColumnValence(Col) INDEX Col;#endif { VALENCE TempCount; SparseMatrixElement *ColValPtr; /* BEGIN */ TempCount = 0; ColValPtr = Matrix->ColHead[Col]; while (ColValPtr != NULL) { TempCount++; ColValPtr = ColValPtr->ColNext; } return(TempCount); }#ifdef ANSIPROTO INDEX GetHighest(INDEX Ipivot)#else INDEX GetHighest(Ipivot) INDEX Ipivot;#endif { INDEX LargestI,SmallestJ; VALENCE ColVal; SparseMatrixElement *GetPtr; ELEMENTVALUETYPE LargestV; float AlphaV; /* BEGIN */ LargestV = 0; LargestI = 0; /* Get the largest pivot on row: */ GetPtr = Matrix->RowHead[Ipivot]; while ((GetPtr != NULL) && (GetPtr->Col <= PartitionCol[CurrentColPart])) { if (ColNew->p[GetPtr->Col] == 0) { if (LargestV <= fabs(GetPtr->Value)) { LargestV = fabs(GetPtr->Value); PivotV = LargestV; DiagVal = GetPtr->Value; LargestI = GetPtr->Col; } } GetPtr = GetPtr->RowNext; } if (Alpha == 1.0) return(LargestI); /* The most robust case */ SmallestJ = maxN + 1; AlphaV = LargestV * Alpha; GetPtr = Matrix->RowHead[Ipivot]; while ((GetPtr != NULL) && (GetPtr->Col <= PartitionCol[CurrentColPart])) { if (ColNew->p[GetPtr->Col] == 0) { ColVal = ColumnValence(GetPtr->Col); if ((ColVal <= SmallestJ) && (fabs(GetPtr->Value) >= AlphaV)) { SmallestJ = ColVal; PivotV = fabs(GetPtr->Value); DiagVal = GetPtr->Value; LargestI = GetPtr->Col; } } GetPtr = GetPtr->RowNext; } return(LargestI); } /* END GetHighest */#ifdef ANSIPROTO void UpdateVals(INDEX Jpivot)#else void UpdateVals(Jpivot) INDEX Jpivot;#endif { SparseMatrixElement * UpdP1; INDEX Jord; /* BEGIN */ UpdP1 = Matrix->ColHead[Jpivot]; while (UpdP1 != NULL) { Jord = UpdP1->Row; if ((RowNew->p[Jord] == 0) && (Jord >= Ibeg) && (Jord <= Iend)) { UNLinkVal(Jord); FindVal(Jord); LinkVal(Jord,Valence[Jord]); } /* END IF */ UpdP1 = UpdP1->ColNext; } /* END WHILE */ } /* END UpdateVals */#ifdef ANSIPROTO int OrderMatrix(INDEX Ibeg,INDEX Iend)#else int OrderMatrix(Ibeg,Iend) INDEX Ibeg,Iend;#endif { int LoopLimit; INDEX Istop,Ipivot,Jpivot; /* BEGIN OrderMatrix */ FormClass(Ibeg,Iend); Istop = Iend; if (Istop > Matrix->n1) Istop = Matrix->n1; if (Istop > Matrix->n2) Istop = Matrix->n2; if (Istop > Nstop) Istop = Nstop; while (Iorder < Istop) { LoopLimit = Matrix->n1; Iorder++; if (Iorder > PartitionCol[CurrentColPart]) CurrentColPart++; do { LoopLimit--; Ipivot = GetLowval(); Jpivot = GetHighest(Ipivot); if (Jpivot == 0) { UNLinkVal(Ipivot); if (Matrix->n1 == Matrix->n2) { fCustomPrint(stderr,"\nUnable to find a nonzero pivot for row %d\n",RowOld->p[Ipivot]); fCustomPrint(stderr,"Matrix is probably numerically singular\n"); return(WARNINGEXIT); } Valence[Ipivot] = Valence[Ipivot] + DeltaValence; LinkVal(Ipivot,Valence[Ipivot]); } } while (((Jpivot <= 0) || (PivotV <= SINGULARITYZERO)) && (LinkCount > 0) && (LoopLimit >= 0)); if (Jpivot <= 0) { fCustomPrint(stderr,"\nUnable to find an available pivot for row %d\n",RowOld->p[Ipivot]); fCustomPrint(stderr,"Matrix is probably topologically singular\n"); return(WARNINGEXIT); /* Iorder = Istop; */ } else { RowNew->p[Ipivot] = Iorder; RowOld->p[Iorder] = Ipivot; if (NearZero(PivotV)) { fCustomPrint(stderr,"\nEquation %d Depends on Other Equations\n",RowOld->p[Ipivot]); fCustomPrint(stderr,"Matrix is probably numerically singular\n"); return(WARNINGEXIT); /* Iorder = Istop; */ } else { ColNew->p[Jpivot] = Iorder; ColOld->p[Iorder] = Jpivot; SimElim(Ipivot,Jpivot,&DiagVal); UpdateVals(Jpivot); } } } /* END WHILE */ return(0); } /* END OrderMatrix *//* ============================ InvertNormalize ======================== */ void InvertNormalize() { INDEX I,Inew; SparseMatrixElement *Ptr1; ELEMENTVALUETYPE DiagValue; /* BEGIN {InvertNormalize} */ for (Inew=1; Inew<=Nstop; Inew++) { I = RowOld->p[Inew]; Ptr1 = Matrix->RowHead[I]; while (Ptr1 != NULL) { if (RowNew->p[I] == ColNew->p[Ptr1->Col]) { /* InvertValue(Ptr1->Value); */ /* EquateValues(DiagValue,Ptr1->Value); */ Ptr1->Value = 1.0 / Ptr1->Value; DiagValue = Ptr1->Value; } Ptr1 = Ptr1->RowNext; } Ptr1 = Matrix->RowHead[I]; while (Ptr1 != NULL) { if (ColNew->p[Ptr1->Col] > RowNew->p[I]) { /* MultiplyValues(Ptr1^.Value,Ptr1^.Value,DiagValue); */ Ptr1->Value = Ptr1->Value * DiagValue; Nmult++; } Ptr1 = Ptr1->RowNext; } } } /* END {InvertNormalize} *//* ========================== FinishVectors =========================== */ void FinishVectors() { INDEX I,K; /* BEGIN */ K = 1; while ((RowOld->p[K] != 0) && (K <= Matrix->n1)) K++; for (I=1; I<=Matrix->n1; I++) { if (RowNew->p[I] == 0) { RowNew->p[I] = K; K++; } } for (I=1; I<=Matrix->n1; I++) { K = RowNew->p[I]; RowOld->p[K] = I; } K = 1; while ((ColOld->p[K] != 0) && (K <= Matrix->n2)) K++; for (I=1; I<=Matrix->n2; I++) { if (ColNew->p[I] == 0) { ColNew->p[I] = K; K++; } } for (I=1; I<=Matrix->n2; I++) ColOld->p[ColNew->p[I]] = I; }/* ============================= factorns ================================ */#ifdef ANSIPROTOint factorns(SparseMatrix *Mptr,double Param,IntegerVector *PartRow,IntegerVector *PartCol, IntegerVector *P1Row,IntegerVector *P1Col,IntegerVector *P2Row,IntegerVector *P2Col)#elseint factorns(Mptr,Param,PartRow,PartCol,P1Row,P1Col,P2Row,P2Col)SparseMatrix *Mptr;double Param;IntegerVector *PartRow,*PartCol,*P1Row,*P1Col,*P2Row,*P2Col;#endif{ /* FactorNS */ double MinAlpha = 0.0; double MaxAlpha = 1.0; SparseMatrixElement *Ptr; INDEX i; FILE *OutFile; /* BEGIN */ RowNew=P1Row; ColNew=P1Col; RowOld=P2Row; ColOld=P2Col; Alpha=Param; if(Alpha<MinAlpha) Alpha=MinAlpha; if(Alpha>MaxAlpha) Alpha=MaxAlpha; Matrix = Mptr; InitializeLSWR(); AllocateOrderArrays(); if (Matrix->n1 < Matrix->n2) Nstop = Matrix->n1; else Nstop = Matrix->n2; PartitionAt = PartRow->p; Nparts = PartRow->N; PartitionCol = PartCol->p; NpartCol = PartCol->N; CurrentColPart = 1; Iorder = 0; LinkCount = 0; Nfills = 0; Nmult = 0; for (Ipart=1; Ipart<=Nparts; Ipart++) { Ibeg = PartitionAt[Ipart-1]+1; Iend = PartitionAt[Ipart]; if (OrderMatrix(Ibeg,Iend)) return(1); }/* fCustomPrint(stderr," Factorization Fills: %d",Nfills);*/ FinishVectors(); /* For the case of rectangular matrix factorization */ InvertNormalize(); /* To convert to true LDU factors, as expected by REPSOL *//* fCustomPrint(stderr," Multiplications: %d\n",Nmult);*/ for (i=1; i<=Matrix->n1; i++) { Ptr=Matrix->RowHead[i]; while(Ptr!=NULL){ Ptr->Row=RowNew->p[Ptr->Row]; Ptr->Col=ColNew->p[Ptr->Col]; Ptr=Ptr->RowNext; } }#ifdef WINDOWS delete[] Lswr; delete[] Swr; delete[] Valence; delete[] FwdLink; delete[] BckLink; delete[] ValClass;#else free(Lswr); free(Swr); free(Valence); free(FwdLink); free(BckLink); free(ValClass);#endif/* if (ExistParameter('d')) { OutFile=(FILE *) OpenOutput("prow.dat"); fCustomPrint(OutFile,"%d\n",RowOld->N); for (i=1; i<=RowOld->N; i++) fCustomPrint(OutFile,"%d ",RowOld->p[i]); fCustomPrint(OutFile,"\n"); fclose(OutFile); OutFile=(FILE *) OpenOutput("pcol.dat"); fCustomPrint(OutFile,"%d\n",ColOld->N); for (i=1; i<=ColOld->N; i++) fCustomPrint(OutFile,"%d ",ColOld->p[i]); fCustomPrint(OutFile,"\n"); fclose(OutFile); }*/ return(0);} /* FactorNS */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?