void Q_SortEl(QMatrix *Q) /* sorts elements of a row or column in ascended order */ { size_t Dim, RoC; Boolean UpperOnly; if (LASResult() == LASOK && !(*Q->ElSorted)) { Dim = Q->Dim; UpperOnly = True; for (RoC = 1; RoC <= Dim; RoC++) { /* sort of elements by the quick sort algorithms */ qsort((void *)Q->El[RoC], Q->Len[RoC], sizeof(ElType), ElCompar); /* test whether elements contained in upper triangular part (incl. diagonal) of the matrix only */ if (Q->ElOrder == Rowws) { if (Q->El[RoC][0].Pos < RoC) UpperOnly = False; } if (Q->ElOrder == Clmws) { if (Q->El[RoC][Q->Len[RoC] - 1].Pos > RoC) UpperOnly = False; } } *Q->ElSorted = True; *Q->DiagElAlloc = False; *Q->ZeroInDiag = True; if (Q->Symmetry) { if(!UpperOnly) LASError(LASSymStorErr, "Q_SortEl", Q->Name, NULL, NULL); } } }
Boolean RTCResult(int Iter, double rNorm, double bNorm, IterIdType IterId) /* get result of RTC */ { Boolean Result; if (LASResult() == LASOK) { if (rNorm < RTCEps * bNorm || (IsZero(bNorm) && IsOne(1.0 + rNorm))) Result = True; else Result = False; LastNoIter = Iter; if (!IsZero(bNorm)) LastAcc = rNorm / bNorm; else LastAcc = 1.0; if (RTCAuxProc != NULL) (*RTCAuxProc)(Iter, rNorm, bNorm, IterId); } else { Result = True; } return(Result); }
char *Q_GetName(QMatrix *Q) /* returns the name of the matrix Q */ { if (LASResult() == LASOK) return(Q->Name); else return(""); }
char *V_GetName(QVector *V) /* returns the name of the vector V */ { if (LASResult() == LASOK) return(V->Name); else return(""); }
const char *M_GetName(Matrix *M) /* returns the name of the matrix M */ { if (LASResult() == LASOK) return(M->Name); else return(""); }
void Q_AllocInvDiagEl(QMatrix *Q) /* allocate pointers and compute inverse for diagonal elements of the matrix Q */ { size_t Dim, RoC, Len, ElCount; Boolean Found; ElType *PtrEl; if (LASResult() == LASOK && !(*Q->DiagElAlloc)) { Dim = Q->Dim; *Q->ZeroInDiag = False; if (Q->Symmetry && Q->ElOrder == Rowws) { for (RoC = 1; RoC <= Dim; RoC++) { if (Q->El[RoC][0].Pos == RoC) { Q->DiagEl[RoC] = Q->El[RoC]; } else { *Q->ZeroInDiag = True; Q->DiagEl[RoC] = &ZeroEl; } } } if (Q->Symmetry && Q->ElOrder == Clmws) { for (RoC = 1; RoC <= Dim; RoC++) { Len = Q->Len[RoC]; if (Q->El[RoC][Len - 1].Pos == RoC) { Q->DiagEl[RoC] = Q->El[RoC] + Len - 1; } else { *Q->ZeroInDiag = True; Q->DiagEl[RoC] = &ZeroEl; } } } if (!Q->Symmetry) { for (RoC = 1; RoC <= Dim; RoC++) { Found = False; Len = Q->Len[RoC]; PtrEl = Q->El[RoC] + Len - 1; for (ElCount = Len; ElCount > 0; ElCount--) { if ((*PtrEl).Pos == RoC) { Found = True; Q->DiagEl[RoC] = PtrEl; } PtrEl--; } if (!Found) { *Q->ZeroInDiag = True; Q->DiagEl[RoC] = &ZeroEl; } } } *Q->DiagElAlloc = True; if (!(*Q->ZeroInDiag)) { for (RoC = 1; RoC <= Dim; RoC++) Q->InvDiagEl[RoC] = 1.0 / (*Q->DiagEl[RoC]).Val; } } }
void Q_AddVal(QMatrix *Q, size_t RoC, size_t Entry, Real Val) /* add a value to a matrix entry */ { if (LASResult() == LASOK) { if ((RoC > 0 && RoC <= Q->Dim) && (Entry < Q->Len[RoC])) Q->El[RoC][Entry].Val += Val; else LASError(LASRangeErr, "Q_AddVal", Q->Name, NULL, NULL); } }
void V_AddCmp(Vector *V, size_t Ind, Real Val) /* add a value to a vector component */ { if (LASResult() == LASOK) { if (Ind > 0 && Ind <= V->Dim && V->Instance == Normal && V->OwnData == True) { V->Cmp[Ind] += Val; } else { LASError(LASRangeErr, "V_AddCmp", V->Name, NULL, NULL); } } }
size_t Q_GetDim(QMatrix *Q) /* returns the dimension of the matrix Q */ { size_t Dim; if (LASResult() == LASOK) Dim = Q->Dim; else Dim = 0; return(Dim); }
size_t M_GetRowDim(Matrix *M) /* returns the row dimension of the matrix M */ { size_t Dim; if (LASResult() == LASOK) Dim = M->RowDim; else Dim = 0; return(Dim); }
size_t M_GetClmDim(Matrix *M) /* returns the column dimension of the matrix M */ { size_t Dim; if (LASResult() == LASOK) Dim = M->ClmDim; else Dim = 0; return(Dim); }
void V_SetCmp(QVector *V, size_t Ind, _LPNumber Val) /* set a value of a vector component */ { if (LASResult() == LASOK) { if (Ind > 0 && Ind <= V->Dim && V->Instance == Normal && V->OwnData == _LPTrue) { V->Cmp[Ind] = Val; } else { LASError(LASRangeErr, "V_SetCmp", V->Name, NULL, NULL); } } }
size_t V_GetDim(QVector *V) /* returns dimension of the vector V */ { size_t Dim; if (LASResult() == LASOK) Dim = V->Dim; else Dim = 0; return(Dim); }
ElOrderType Q_GetElOrder(QMatrix *Q) /* returns element order of the matrix Q */ { ElOrderType ElOrder; if (LASResult() == LASOK) { ElOrder = Q->ElOrder; } else { ElOrder = (ElOrderType)0; } return(ElOrder); }
Boolean Q_GetSymmetry(QMatrix *Q) /* returns True if Q is symmetric otherwise False */ { Boolean Symmetry; if (LASResult() == LASOK) { Symmetry = Q->Symmetry; } else { Symmetry = (Boolean)0; } return(Symmetry); }
void Q_SetName(QMatrix *Q, char *Name) /* (re)set name of the matrix Q */ { if (LASResult() == LASOK) { free(Q->Name); Q->Name = (char *)malloc((strlen(Name) + 1) * sizeof(char)); if (Q->Name != NULL) strcpy(Q->Name, Name); else LASError(LASMemAllocErr, "Q_SetName", Name, NULL, NULL); } }
void M_AddVal(Matrix *M, size_t RoC, size_t Entry, _LPNumber Val) /* add a value to a matrix entry */ { if (LASResult() == LASOK) { if ((M->ElOrder == Rowws && RoC > 0 && RoC <= M->RowDim) || ((M->ElOrder == Clmws && RoC > 0 && RoC <= M->ClmDim) && (Entry < M->Len[RoC]))) M->El[RoC][Entry].Val += Val; else LASError(LASRangeErr, "M_AddVal", M->Name, NULL, NULL); } }
ElOrderType M_GetElOrder(Matrix *M) /* returns the element order */ { ElOrderType ElOrder; if (LASResult() == LASOK) { ElOrder = M->ElOrder; } else { ElOrder = (ElOrderType)0; } return(ElOrder); }
void M_SetName(Matrix *M, const char *Name) /* (re)set name of the matrix M */ { if (LASResult() == LASOK) { free(M->Name); M->Name = (char *)malloc((strlen(Name) + 1) * sizeof(char)); if (M->Name != NULL) strcpy(M->Name, Name); else LASError(LASMemAllocErr, "M_SetName", Name, NULL, NULL); } }
void V_SetName(QVector *V, char *Name) /* (re)set name of the vector V */ { if (LASResult() == LASOK) { free(V->Name); V->Name = (char *)malloc((strlen(Name) + 1) * sizeof(char)); if (V->Name != NULL) strcpy(V->Name, Name); else LASError(LASMemAllocErr, "V_SetName", Name, NULL, NULL); } }
void Q_SetEntry(QMatrix *Q, size_t RoC, size_t Entry, size_t Pos, Real Val) /* set a new matrix entry */ { if (LASResult() == LASOK) { if ((RoC > 0 && RoC <= Q->Dim && Pos > 0 && Pos <= Q->Dim) && (Entry < Q->Len[RoC])) { Q->El[RoC][Entry].Pos = Pos; Q->El[RoC][Entry].Val = Val; } else { LASError(LASRangeErr, "Q_SetEntry", Q->Name, NULL, NULL); } } }
double GetMaxEigenval(QMatrix *A, PrecondProcType PrecondProc, double OmegaPrecond) /* returns estimate for maximum eigenvalue of the matrix A */ { double MaxEigenval; EigenvalInfoType *EigenvalInfo; Q_Lock(A); if (LASResult() == LASOK) { EigenvalInfo = (EigenvalInfoType *)*(Q_EigenvalInfo(A)); /* if eigenvalues not estimated yet, ... */ if (EigenvalInfo == NULL) { EigenvalInfo = (EigenvalInfoType *)malloc(sizeof(EigenvalInfoType)); if (EigenvalInfo != NULL) { *(Q_EigenvalInfo(A)) = (void *)EigenvalInfo; EstimEigenvals(A, PrecondProc, OmegaPrecond); } else { LASError(LASMemAllocErr, "GetMaxEigenval", Q_GetName(A), NULL, NULL); } } /* if eigenvalues estimated with an other preconditioner, ... */ if (EigenvalInfo->PrecondProcUsed != PrecondProc || EigenvalInfo->OmegaPrecondUsed != OmegaPrecond) { EstimEigenvals(A, PrecondProc, OmegaPrecond); } if (LASResult() == LASOK) MaxEigenval = EigenvalInfo->MaxEigenval; else MaxEigenval = 1.0; } else { MaxEigenval = 1.0; } return(MaxEigenval); }
void V_SetAllCmp(QVector *V, _LPNumber Val) /* set all vector components equal Val */ { size_t Dim, Ind; _LPNumber *VCmp; if (LASResult() == LASOK) { Dim = V->Dim; VCmp = V->Cmp; for(Ind = 1; Ind <= Dim; Ind++) VCmp[Ind] = Val; V->Multipl = 1.0; } }
void M_SetEntry(Matrix *M, size_t RoC, size_t Entry, size_t Pos, _LPNumber Val) /* set a new matrix entry */ { if (LASResult() == LASOK) { if ((M->ElOrder == Rowws && RoC > 0 && RoC <= M->RowDim && Pos > 0 && Pos <= M->ClmDim) || ((M->ElOrder == Clmws && RoC > 0 && RoC <= M->ClmDim && Pos > 0 && Pos <= M->RowDim) && (Entry < M->Len[RoC]))) { M->El[RoC][Entry].Val = Val; M->El[RoC][Entry].Pos = Pos; } else { LASError(LASRangeErr, "M_SetEntry", M->Name, NULL, NULL); } } }
void V_SetRndCmp(QVector *V) /* set random components of the vector V */ { size_t Dim, Ind; _LPNumber *VCmp; if (LASResult() == LASOK) { Dim = V_GetDim(V); VCmp = V->Cmp; for (Ind = 1; Ind <= Dim; Ind++) { VCmp[Ind] = (_LPDouble)rand() / ((_LPDouble)RAND_MAX + 1.0); } V->Multipl = 1.0; } }
Real Q_GetVal(QMatrix *Q, size_t RoC, size_t Entry) /* returns the value of a matrix element */ { Real Val; if (LASResult() == LASOK) if (RoC > 0 && RoC <= Q->Dim && Entry < Q->Len[RoC]) { Val = Q->El[RoC][Entry].Val; } else { LASError(LASRangeErr, "Q_GetVal", Q->Name, NULL, NULL); Val = 0.0; } else Val = 0.0; return(Val); }
size_t Q_GetPos(QMatrix *Q, size_t RoC, size_t Entry) /* returns the position of a matrix element */ { size_t Pos; if (LASResult() == LASOK) if (RoC > 0 && RoC <= Q->Dim && Entry < Q->Len[RoC]) { Pos = Q->El[RoC][Entry].Pos; } else { LASError(LASRangeErr, "Q_GetPos", Q->Name, NULL, NULL); Pos = 0; } else Pos = 0; return(Pos); }
Boolean Q_KerDefined(QMatrix *Q) /* returns True if Q is singular and the null space has been defined otherwise False */ { Boolean KerDefined; if (LASResult() == LASOK) { if ((Q->UnitRightKer || Q->RightKerCmp != NULL) && !IsZero(Q->MultiplD) && IsOne(Q->MultiplU / Q->MultiplD) && IsOne(Q->MultiplL / Q->MultiplD)) KerDefined = True; else KerDefined = False; } else { KerDefined = (Boolean)0; } return(KerDefined); }
_LPNumber V_GetCmp(QVector *V, size_t Ind) /* returns the value of a vector component */ { _LPNumber Val; if (LASResult() == LASOK) { if (Ind > 0 && Ind <= V->Dim) { Val = V->Cmp[Ind]; } else { LASError(LASRangeErr, "V_GetCmp", V->Name, NULL, NULL); Val = 0.0; } } else { Val = 0.0; } return(Val); }
size_t Q_GetLen(QMatrix *Q, size_t RoC) /* returns the lenght of a row or column of the matrix Q */ { size_t Len; if (LASResult() == LASOK) { if (RoC > 0 && RoC <= Q->Dim) { Len = Q->Len[RoC]; } else { LASError(LASRangeErr, "Q_GetLen", Q->Name, NULL, NULL); Len = 0; } } else { Len = 0; } return(Len); }