⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matrix_indirect.c

📁 有限元程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    spScale = VectorAlloc("Scale Factor",  DOUBLE_ARRAY, spA->iNoRows );    for (ii = 1; ii <= spA->iNoRows; ii = ii + 1) {         spScale->uVector.da[ii-1] = ABS(spA->uMatrix.daa[ii-1][0]);         for (ij = 2; ij <= spA->iNoColumns; ij = ij + 1) {              dTemp = ABS(spA->uMatrix.daa[ii-1][ij-1]);              spScale->uVector.da[ii-1] = (double) MAX( spScale->uVector.da[ii-1], dTemp );         }         if( spScale->uVector.da[ii-1] == 0)             FatalError("Execution halted in SetupScaleFactors()",                        "Matrix A is Singular !!",                        (char *) NULL);    }    return ( spScale );}/*  *  ================================================================== *  SetupPivotVector() : Initialize (nx1) vector for row permutations. *   *  Input :   MATRIX spA       -- Pointer to (nxn) matrix [A]. *  Output :  VECTOR spPivot   -- Pointer to (nx1) vector spPivot. *  ================================================================== */ #ifdef __STDC__VECTOR *SetupPivotVector( MATRIX *spA )#else  /* Start case not STDC */VECTOR *SetupPivotVector( spA )MATRIX *spA;#endif /* End case not STDC */{VECTOR *spPivot;int          ii;    spPivot = VectorAlloc(  "Row Pivots", INTEGER_ARRAY, spA->iNoRows );    for (ii = 1; ii <= spA->iNoRows; ii = ii + 1)         spPivot->uVector.ia[ii-1] = ii;    return ( spPivot );}/*  *  ================================================================== *  Pivot() : Find largest element below diagonal and pivot rows *   *  Input  :   MATRIX spA       -- Pointer to (nxn) matrix [A]. *         :   VECTOR spScale   -- Pointer to (nx1) vector spScale. *         :   VECTOR spPivot   -- Pointer to (nx1) vector spPivot. *         :   int iColumnNo    -- Column No for Pivoting *  Output :   MATRIX spA       -- [A] and [spPivot] are rearranged by *                                 the pivoting procedure. *  ================================================================== */ #ifdef __STDC__Pivot( MATRIX *spA, VECTOR *spScale, VECTOR *spPivot, int iColumnNo )#else  /* Start case not STDC */Pivot( spA, spScale, spPivot, iColumnNo )VECTOR *spScale, *spPivot;MATRIX     *spA;int   iColumnNo;#endif /* End case not STDC */{double dLargest,     dTemp;int  ii , iTemp,    iOrder;int      iPivot;    /* [a] : Find Row No of Largest Scaled Equation  */       iPivot  = iColumnNo;       iOrder  = spPivot->uVector.ia[ iColumnNo - 1 ];       dLargest = spA->uMatrix.daa[ iOrder-1 ][ iColumnNo - 1 ] /                  spScale->uVector.da[ iOrder-1 ];       dLargest = ABS( dLargest );       for (ii = iColumnNo + 1; ii <= spA->iNoColumns; ii = ii + 1) {            iOrder = spPivot->uVector.ia[ ii - 1 ];            dTemp  = spA->uMatrix.daa[ iOrder-1 ][ iColumnNo - 1 ] /                     spScale->uVector.da[ iOrder-1 ];            dTemp  = ABS( dTemp );            if( dTemp > dLargest ) {                dLargest = dTemp;                iPivot   = ii;            }       }       if( dLargest == 0 )           FatalError("Execution halted in Pivot()",                      "Matrix A is Singular !!",                      (char *) NULL);    /* [b] : Swap Row Nos in Order Vector */       iTemp  = spPivot->uVector.ia[ iPivot - 1 ];       spPivot->uVector.ia[ iPivot - 1 ]    = spPivot->uVector.ia[ iColumnNo - 1 ];       spPivot->uVector.ia[ iColumnNo - 1 ] = iTemp;}/* *  ================================================================= *  GeneralizedEigen() : Solve Eigen Problem [A][x] = [B][x][Lambda]. *                       where [A] and [B] are small fully populated   *                       symmetric matrices.   *   *  We convert [A][x] = [B][x][Lambda] into [A*][y] = [y][Lambda] in *  a four-step procedure:   *   *        (a) : Compute [B] = [L].[L]^T   *        (b) : Solve   [L][C] = [A]. *        (c) : Compute [C]^T. *        (d) : Solve   [L][A*]^T = [C]^T; matrix [A*] is symmetric.   *   *  Use Householder method to solve [A*][y] = [y][Lamda], followed by  *  backward substitutution for [L]^T.[x] = [y]. *   *  Written By : M. Austin                              November 1993  *  ================================================================= */GeneralizedEigen( spA, spB, spEigenvalue, spEigenvector )MATRIX   *spA,    *spB;MATRIX   *spEigenvalue;MATRIX  *spEigenvector;{MATRIX *spEigenvectorY;MATRIX       *spCwork2;MATRIX        *spAwork;MATRIX        *spCwork;MATRIX          *spLLT;int        iSize;int   ii, ij, ik;double       sum;#ifdef MYDEBUG       printf("\n*** Enter GeneralizedEigen()\n");       MatrixPrint ( spA );       MatrixPrint ( spB );#endif    /* [a] : Check Input and Allocate Working Arrays */       iSize = spA->iNoRows;       spCwork = MatrixAllocIndirect("Working [C]", DOUBLE_ARRAY, iSize, iSize );       spAwork = MatrixAllocIndirect("Working [A]", DOUBLE_ARRAY, iSize, iSize );    /* [b] : Compute Cholesky Decomposition [B] = [L].[L]^T */       spLLT = MatrixCopy( spB );       spLLT = CholeskyDecompositionIndirect( spLLT );    /* [c] : Solve [L][C] = [A] via Forward Substitution */       for (ij = 1; ij <= spA->iNoRows; ij = ij + 1) {            for (ii = 1; ii <= spA->iNoColumns; ii = ii + 1) {            sum  = 0.0;            for (ik = 1; ik < ii; ik = ik + 1)                 sum += spLLT->uMatrix.daa[ ii-1 ][ ik-1 ] *                               spCwork->uMatrix.daa[ ik-1 ][ij-1];            spCwork->uMatrix.daa[ii-1][ij-1] = (spA->uMatrix.daa[ ii-1 ][ ij-1 ] - sum) /                                                spLLT->uMatrix.daa[ ii-1 ][ ii-1 ];            }       }    /* [d] : Replace [C] by [C]^T. */       spCwork2 = MatrixTranspose ( spCwork );    /* [e] : Solve [L][A*] = [C]^T via Forward Substitution */       for (ij = 1; ij <= spA->iNoRows; ij = ij + 1) {            for (ii = 1; ii <= spA->iNoColumns; ii = ii + 1) {            sum  = 0.0;            for (ik = 1; ik < ii; ik = ik + 1)                 sum += spLLT->uMatrix.daa[ ii-1 ][ ik-1 ] *                               spAwork->uMatrix.daa[ ik-1 ][ij-1];            spAwork->uMatrix.daa[ii-1][ij-1] =                    (spCwork2->uMatrix.daa[ ii-1 ][ ij-1 ] - sum) /                     spLLT->uMatrix.daa[ ii-1 ][ ii-1 ];            }       }    /* [f] : Use Householder Method to Solve Standard Eigenvalue Problem */       iSize = spAwork->iNoRows;       spEigenvectorY = MatrixAllocIndirect("Eigenvector [Y]", DOUBLE_ARRAY, iSize, iSize);    /* [e] : Use Householder Transformation to convert [spStiff] to Triangular form */       Householder( spAwork, spEigenvalue, spEigenvectorY );    /* [g] : Compute [L]^T.[X] = [Y] via Back Substitution */       for (ij = spAwork->iNoRows; ij >= 1 ; ij = ij - 1) {            for (ii = 1; ii <= spAwork->iNoColumns; ii = ii + 1) {            sum  = 0.0;            for (ik = ij + 1; ik <= spAwork->iNoRows; ik = ik + 1)                 sum += spLLT->uMatrix.daa[ ij-1 ][ ik-1 ] *                               spEigenvector->uMatrix.daa[ ik-1 ][ii-1];            spEigenvector->uMatrix.daa[ij-1][ii-1] =                          (spEigenvectorY->uMatrix.daa[ ij-1 ][ ii-1 ] - sum) /                           spLLT->uMatrix.daa[ ij-1 ][ ij-1 ];            }       }    /* [h] : Cleanup before leaving */       MatrixFree( spAwork );       MatrixFree( spCwork );       MatrixFree( spCwork2 );       MatrixFree( spEigenvectorY );       MatrixFree( spLLT );#ifdef MYDEBUG       printf("\n*** Leave GeneralizedEigen()\n");#endif}/* *  ======================================================================== *  Householder() : Compute Eigenvalues/Eigenvectors of Symmetric Matrix Via *  Householder's Transformation and QL-Algorithm. *   *  Input  :  MATRIX *spK           -- Pointer to large matrix [K]. *         :  MATRIX *spEigenvalue  -- Pointer to (nx1) eigenvalue matrix. *         :  MATRIX *spEigenvector -- Pointer to (nxn) eigenvector matrix. *  Output :  MATRIX *spEigenvalue  -- Pointer to (nx1) eigenvalue matrix. *         :  MATRIX *spEigenvector -- Pointer to (nxn) eigenvector matrix. *   *  Written By: Mark Austin                                    November 1993 *  ======================================================================== */Householder( spK, spEigenvalue, spEigenvector )MATRIX            *spK;MATRIX   *spEigenvalue;MATRIX  *spEigenvector;{double  *t1, *t2;int         stat;int       ii, ij;int iNoEquations; /* [a] : Setup Working Matrices for Eigenvalues and Eigenvectors */    iNoEquations = spK->iNoRows;    t1 = (double *) MyCalloc( iNoEquations, sizeof(double));    t2 = (double *) MyCalloc( iNoEquations, sizeof(double));    for( ii = 1; ii <= iNoEquations; ii = ii + 1)    for( ij = 1; ij <= iNoEquations; ij = ij + 1)         spEigenvector->uMatrix.daa[ ii-1 ][ ij-1 ] = spK->uMatrix.daa[ ii-1 ][ ij-1 ]; /* [b] : Convert [K] to Tridiagonal Form with Householder Transformation */    HouseHolderTransformation( spEigenvector, t1, t2, iNoEquations); /* [c] : Use ql Algorithm to compute Eigenvalues and Eigenvectors */    stat = QlAlgorithm( spEigenvector, t1, t2, iNoEquations); /* [d] : Transfer Working Matrix to Eigenvalues */    for( ii = 1; ii <= iNoEquations; ii = ii + 1)         spEigenvalue->uMatrix.daa[ ii-1 ][0] = t1[ ii-1 ];    free((char *) t1);    free((char *) t2);    return stat;}/* *  ============================================================== *  HouseHolderTrans() : Use HouseHolder Transformation to convert *                       Symmetric Matrix to tridiagonal form. *  ============================================================== */static double TOLERANCE = 1.3e-16;HouseHolderTransformation( spK , d, e, iNoEquations)MATRIX      *spK;double    *d, *e;int iNoEquations;{int    ii, ij, ik, im;double dTempf, dTempg;double dTemph, dTempk;    ii = iNoEquations;    while (--ii) {        im = ii - 2;        dTempf = spK->uMatrix.daa[ii][ii-1];        dTempg = 0.0;        for (ij = 0; ij <= im; ij++)             dTempg += spK->uMatrix.daa[ii][ij] * spK->uMatrix.daa[ii][ij];        dTemph = dTempg + dTempf * dTempf;        if (dTempg < TOLERANCE) {                 e[ii]  = dTempf;                 dTemph = 0.0;        } else {             im++;             if (dTempf >= 0)                 dTempg = -sqrt( dTemph );             else                 dTempg =  sqrt( dTemph );             e[ii] = dTempg;             dTemph -= dTempf * dTempg;             spK->uMatrix.daa[ii][ii-1] = dTempf - dTempg;             dTempf = 0;             for (ij = 0; ij <= im; ij++) {                  spK->uMatrix.daa[ij][ii] = spK->uMatrix.daa[ii][ij] / dTemph;                  dTempg = 0;                  for (ik = 0; ik <= ij; ik++)                       dTempg += spK->uMatrix.daa[ij][ik] * spK->uMatrix.daa[ii][ik];                  for (ik = ij+1; ik <= im; ik++)                       dTempg += spK->uMatrix.daa[ik][ij] * spK->uMatrix.daa[ii][ik];                  e[ij] = dTempg / dTemph;                  dTempf += dTempg * spK->uMatrix.daa[ij][ii];             }             dTempk = dTempf / (dTemph + dTemph);             for (ij = 0; ij <= im; ij++) {                  dTempf = spK->uMatrix.daa[ii][ij];                  dTempg = e[ij] - dTempk * dTempf;                  e[ij]  = dTempg;                  for (ik=0; ik <= ij; ik++)                       spK->uMatrix.daa[ij][ik] = spK->uMatrix.daa[ij][ik] - dTempf * e[ik] -                                                  dTempg * spK->uMatrix.daa[ii][ik];             }        }        d[ii] = dTemph;    }    d[0] = 0.0;    e[0] = 0.0;    for (ii=0; ii < iNoEquations; ii++) {         im = ii - 1;         if (d[ii] != 0.0)          for (ij=0; ij <= im; ij++) {              dTempg = 0.0;              for (ik=0; ik <= im; ik++)                   dTempg += spK->uMatrix.daa[ii][ik] * spK->uMatrix.daa[ik][ij];              for (ik=0; ik <= im; ik++)                   spK->uMatrix.daa[ik][ij] -= dTempg * spK->uMatrix.daa[ik][ii];         }         d[ii] = spK->uMatrix.daa[ii][ii];         spK->uMatrix.daa[ii][ii] = 1.0;         for (ij=0; ij <= im; ij++)              spK->uMatrix.daa[ii][ij] = spK->uMatrix.daa[ij][ii] = 0.0;    }}/*  *  ================================================ *  QL() : QL Algorithm : Adapted from EISPACK...... *  ================================================ */QlAlgorithm( spK, d, e, iNoEquations )MATRIX      *spK;doub

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -