IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Oct 14, 2009, 12:50:26 PM (17 years ago)
Author:
Paul Price
Message:

lndet works better.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/pap/psLib/src/math/psMatrix.c

    r24122 r25842  
    379379    switch (a->type.type) {
    380380      case PS_TYPE_F32: {
    381           psF32 **values = a->data.F32; /* Dereference */
    382           int numCols = a->numCols, numRows = a->numRows; /* Size of matrix */
    383           for (int i = 0; i < numRows; i++) {
    384               for (int j = 0; j < numCols; j++) {
    385                   if (!isfinite(values[i][j])) {
    386                       // psError(PS_ERR_BAD_PARAMETER_VALUE, 3,
    387                       // "Input matrix contains non-finite elements: matrix[%d][%d] is %.2f\n",
    388                       // i, j, values[i][j]);
    389                       return false;
    390                   }
    391               }
    392           }
    393           break;
     381          psF32 **values = a->data.F32; /* Dereference */
     382          int numCols = a->numCols, numRows = a->numRows; /* Size of matrix */
     383          for (int i = 0; i < numRows; i++) {
     384              for (int j = 0; j < numCols; j++) {
     385                  if (!isfinite(values[i][j])) {
     386                      // psError(PS_ERR_BAD_PARAMETER_VALUE, 3,
     387                      // "Input matrix contains non-finite elements: matrix[%d][%d] is %.2f\n",
     388                      // i, j, values[i][j]);
     389                      return false;
     390                  }
     391              }
     392          }
     393          break;
    394394      }
    395395      case PS_TYPE_F64: {
    396           psF64 **values = a->data.F64; /* Dereference */
    397           int numCols = a->numCols, numRows = a->numRows; /* Size of matrix */
    398           for (int i = 0; i < numRows; i++) {
    399               for (int j = 0; j < numCols; j++) {
    400                   if (!isfinite(values[i][j])) {
    401                       // psError(PS_ERR_BAD_PARAMETER_VALUE, 3,
    402                       // "Input matrix contains non-finite elements: matrix[%d][%d] is %.2f\n",
    403                       // i, j, values[i][j]);
    404                       return false;
    405                   }
    406               }
    407           }
    408           break;
     396          psF64 **values = a->data.F64; /* Dereference */
     397          int numCols = a->numCols, numRows = a->numRows; /* Size of matrix */
     398          for (int i = 0; i < numRows; i++) {
     399              for (int j = 0; j < numCols; j++) {
     400                  if (!isfinite(values[i][j])) {
     401                      // psError(PS_ERR_BAD_PARAMETER_VALUE, 3,
     402                      // "Input matrix contains non-finite elements: matrix[%d][%d] is %.2f\n",
     403                      // i, j, values[i][j]);
     404                      return false;
     405                  }
     406              }
     407          }
     408          break;
    409409      }
    410         // MATRIX_CHECK_NONFINITE_CASE(F32, a);
    411         // MATRIX_CHECK_NONFINITE_CASE(F64, a);
     410        // MATRIX_CHECK_NONFINITE_CASE(F32, a);
     411        // MATRIX_CHECK_NONFINITE_CASE(F64, a);
    412412      default:
    413         psAbort("Should never get here.");
     413        psAbort("Should never get here.");
    414414    }
    415415
     
    471471    switch (a->type.type) {
    472472      case PS_TYPE_F32: {
    473           psF32 **values = a->data.F32; /* Dereference */
    474           int numCols = a->numCols, numRows = a->numRows; /* Size of matrix */
    475           for (int i = 0; i < numRows; i++) {
    476               for (int j = 0; j < numCols; j++) {
    477                   if (!isfinite(values[i][j])) {
    478                       return false;
    479                   }
    480               }
    481           }
    482           break;
     473          psF32 **values = a->data.F32; /* Dereference */
     474          int numCols = a->numCols, numRows = a->numRows; /* Size of matrix */
     475          for (int i = 0; i < numRows; i++) {
     476              for (int j = 0; j < numCols; j++) {
     477                  if (!isfinite(values[i][j])) {
     478                      return false;
     479                  }
     480              }
     481          }
     482          break;
    483483      }
    484484      case PS_TYPE_F64: {
    485           psF64 **values = a->data.F64; /* Dereference */
    486           int numCols = a->numCols, numRows = a->numRows; /* Size of matrix */
    487           for (int i = 0; i < numRows; i++) {
    488               for (int j = 0; j < numCols; j++) {
    489                   if (!isfinite(values[i][j])) {
    490                       return false;
    491                   }
    492               }
    493           }
    494           break;
     485          psF64 **values = a->data.F64; /* Dereference */
     486          int numCols = a->numCols, numRows = a->numRows; /* Size of matrix */
     487          for (int i = 0; i < numRows; i++) {
     488              for (int j = 0; j < numCols; j++) {
     489                  if (!isfinite(values[i][j])) {
     490                      return false;
     491                  }
     492              }
     493          }
     494          break;
    495495      }
    496496      default:
    497         psAbort("Should never get here.");
    498     }
    499  
     497        psAbort("Should never get here.");
     498    }
     499
    500500    // Following the algorithm laid out by Press et al., we loop along the matrix diagonal, but
    501501    // we do not operate on the diagonal elements in order.  Instead, we are looking for the
     
    511511
    512512    if (a->type.type == PS_TYPE_F32) {
    513         psF32 **A = a->data.F32;
    514         psF32  *B = b->data.F32;
    515         int *colIndex = colIndexV->data.S32;
    516         int *rowIndex = rowIndexV->data.S32;
    517         int *pivot    = pivotV->data.S32;
    518         psF32 growth = 1.0;
    519 
    520         for (int diag = 0; diag < nSquare; diag++) {
    521 
    522             psF32 maxval = 0.0;
    523             int maxrow = 0;
    524             int maxcol = 0;
    525 
    526             // search for the next pivot
    527             for (int row = 0; row < nSquare; row++) {
    528                 if (!isfinite(A[row][diag])) goto escape;
    529 
    530                 // if we have already operated on this row (pivot[row] is true), skip it
    531                 if (pivot[row]) continue;
    532 
    533                 // if we have not yet operated on this row (pivot[row] is false), look for pivot for this row
    534                 for (int col = 0; col < nSquare; col++) {
    535                     if (pivot[col]) continue;
    536                     if (fabs (A[row][col]) < maxval) continue;
    537                     maxval = fabs (A[row][col]);
    538                     maxrow = row;
    539                     maxcol = col;
    540                 }
    541             }
    542 
    543             // if pivot[maxcol] is set, we have already done this row: this implies a singular matrix
    544             if (pivot[maxcol]) goto escape;
    545             pivot[maxcol] = 1;
    546 
    547             // if the selected pivot is off the diagonal, do a row swap
    548             if (maxrow != maxcol) {
    549                 for (int col = 0; col < nSquare; col++) PS_SWAP (A[maxrow][col], A[maxcol][col]);
    550                 PS_SWAP (B[maxrow], B[maxcol]);
    551             }
    552             rowIndex[diag] = maxrow;
    553             colIndex[diag] = maxcol;
    554             if (A[maxcol][maxcol] == 0.0) goto escape;
    555             // Kahan replaces the 0.0 pivot with epsilon*(largest element in column) + underFlow.
    556             // Here we are going to raise an error if the dynamic range is too large.
    557 
    558             /* rescale by pivot reciprocal */
    559             psF32 tmpval = 1.0 / A[maxcol][maxcol];
    560             A[maxcol][maxcol] = 1.0;
    561             for (int col = 0; col < nSquare; col++) A[maxcol][col] *= tmpval;
    562             B[maxcol] *= tmpval;
    563 
    564             // check for ill-conditioned matrix: measure the pivot growth and trigger on over/under flow
    565             growth *= tmpval;
    566             psTrace ("psLib.math", 4, "growth : %e\n", growth);
    567             if (fabs(growth) > MAX_RANGE) goto escape;
    568 
    569             /* adjust the elements above the pivot */
    570             for (int row = 0; row < nSquare; row++) {
    571                 if (row == maxcol) continue;
    572                 tmpval = A[row][maxcol];
    573                 A[row][maxcol] = 0.0;
    574                 for (int col = 0; col < nSquare; col++) A[row][col] -= A[maxcol][col]*tmpval;
    575                 B[row] -= B[maxcol]*tmpval;
    576             }
    577         }
    578 
    579         // swap back the inverse matrix based on the row swaps above
    580         for (int col = nSquare - 1; col >= 0; col--) {
    581             if (rowIndex[col] != colIndex[col]) {
    582                 for (int row = 0; row < nSquare; row++) PS_SWAP (A[row][rowIndex[col]], A[row][colIndex[col]]);
    583             }
    584         }
     513        psF32 **A = a->data.F32;
     514        psF32  *B = b->data.F32;
     515        int *colIndex = colIndexV->data.S32;
     516        int *rowIndex = rowIndexV->data.S32;
     517        int *pivot    = pivotV->data.S32;
     518        psF32 growth = 1.0;
     519
     520        for (int diag = 0; diag < nSquare; diag++) {
     521
     522            psF32 maxval = 0.0;
     523            int maxrow = 0;
     524            int maxcol = 0;
     525
     526            // search for the next pivot
     527            for (int row = 0; row < nSquare; row++) {
     528                if (!isfinite(A[row][diag])) goto escape;
     529
     530                // if we have already operated on this row (pivot[row] is true), skip it
     531                if (pivot[row]) continue;
     532
     533                // if we have not yet operated on this row (pivot[row] is false), look for pivot for this row
     534                for (int col = 0; col < nSquare; col++) {
     535                    if (pivot[col]) continue;
     536                    if (fabs (A[row][col]) < maxval) continue;
     537                    maxval = fabs (A[row][col]);
     538                    maxrow = row;
     539                    maxcol = col;
     540                }
     541            }
     542
     543            // if pivot[maxcol] is set, we have already done this row: this implies a singular matrix
     544            if (pivot[maxcol]) goto escape;
     545            pivot[maxcol] = 1;
     546
     547            // if the selected pivot is off the diagonal, do a row swap
     548            if (maxrow != maxcol) {
     549                for (int col = 0; col < nSquare; col++) PS_SWAP (A[maxrow][col], A[maxcol][col]);
     550                PS_SWAP (B[maxrow], B[maxcol]);
     551            }
     552            rowIndex[diag] = maxrow;
     553            colIndex[diag] = maxcol;
     554            if (A[maxcol][maxcol] == 0.0) goto escape;
     555            // Kahan replaces the 0.0 pivot with epsilon*(largest element in column) + underFlow.
     556            // Here we are going to raise an error if the dynamic range is too large.
     557
     558            /* rescale by pivot reciprocal */
     559            psF32 tmpval = 1.0 / A[maxcol][maxcol];
     560            A[maxcol][maxcol] = 1.0;
     561            for (int col = 0; col < nSquare; col++) A[maxcol][col] *= tmpval;
     562            B[maxcol] *= tmpval;
     563
     564            // check for ill-conditioned matrix: measure the pivot growth and trigger on over/under flow
     565            growth *= tmpval;
     566            psTrace ("psLib.math", 4, "growth : %e\n", growth);
     567            if (fabs(growth) > MAX_RANGE) goto escape;
     568
     569            /* adjust the elements above the pivot */
     570            for (int row = 0; row < nSquare; row++) {
     571                if (row == maxcol) continue;
     572                tmpval = A[row][maxcol];
     573                A[row][maxcol] = 0.0;
     574                for (int col = 0; col < nSquare; col++) A[row][col] -= A[maxcol][col]*tmpval;
     575                B[row] -= B[maxcol]*tmpval;
     576            }
     577        }
     578
     579        // swap back the inverse matrix based on the row swaps above
     580        for (int col = nSquare - 1; col >= 0; col--) {
     581            if (rowIndex[col] != colIndex[col]) {
     582                for (int row = 0; row < nSquare; row++) PS_SWAP (A[row][rowIndex[col]], A[row][colIndex[col]]);
     583            }
     584        }
    585585    } else {
    586         psF64 **A = a->data.F64;
    587         psF64  *B = b->data.F64;
    588         int *colIndex = colIndexV->data.S32;
    589         int *rowIndex = rowIndexV->data.S32;
    590         int *pivot    = pivotV->data.S32;
    591         psF64 growth = 1.0;
    592 
    593         for (int diag = 0; diag < nSquare; diag++) {
    594 
    595             psF64 maxval = 0.0;
    596             int maxrow = 0;
    597             int maxcol = 0;
    598 
    599             // search for the next pivot
    600             for (int row = 0; row < nSquare; row++) {
    601                 if (!isfinite(A[row][diag])) goto escape;
    602 
    603                 // if we have already operated on this row (pivot[row] is true), skip it
    604                 if (pivot[row]) continue;
    605 
    606                 // if we have not yet operated on this row (pivot[row] is false), look for pivot for this row
    607                 for (int col = 0; col < nSquare; col++) {
    608                     if (pivot[col]) continue;
    609                     if (fabs (A[row][col]) < maxval) continue;
    610                     maxval = fabs (A[row][col]);
    611                     maxrow = row;
    612                     maxcol = col;
    613                 }
    614             }
    615 
    616             // if pivot[maxcol] is set, we have already done this row: this implies a singular matrix
    617             if (pivot[maxcol]) goto escape;
    618             pivot[maxcol] = 1;
    619 
    620             // if the selected pivot is off the diagonal, do a row swap
    621             if (maxrow != maxcol) {
    622                 for (int col = 0; col < nSquare; col++) PS_SWAP (A[maxrow][col], A[maxcol][col]);
    623                 PS_SWAP (B[maxrow], B[maxcol]);
    624             }
    625             rowIndex[diag] = maxrow;
    626             colIndex[diag] = maxcol;
    627             if (A[maxcol][maxcol] == 0.0) goto escape;
    628             // Kahan replaces the 0.0 pivot with epsilon*(largest element in column) + underFlow.
    629             // Here we are going to raise an error if the dynamic range is too large.
    630 
    631             /* rescale by pivot reciprocal */
    632             psF64 tmpval = 1.0 / A[maxcol][maxcol];
    633             A[maxcol][maxcol] = 1.0;
    634             for (int col = 0; col < nSquare; col++) A[maxcol][col] *= tmpval;
    635             B[maxcol] *= tmpval;
    636 
    637             // check for ill-conditioned matrix: measure the pivot growth and trigger on over/under flow
    638             growth *= tmpval;
    639             psTrace ("psLib.math", 4, "growth : %e\n", growth);
    640             if (fabs(growth) > MAX_RANGE) goto escape;
    641 
    642             /* adjust the elements above the pivot */
    643             for (int row = 0; row < nSquare; row++) {
    644                 if (row == maxcol) continue;
    645                 tmpval = A[row][maxcol];
    646                 A[row][maxcol] = 0.0;
    647                 for (int col = 0; col < nSquare; col++) A[row][col] -= A[maxcol][col]*tmpval;
    648                 B[row] -= B[maxcol]*tmpval;
    649             }
    650         }
    651 
    652         // swap back the inverse matrix based on the row swaps above
    653         for (int col = nSquare - 1; col >= 0; col--) {
    654             if (rowIndex[col] != colIndex[col]) {
    655                 for (int row = 0; row < nSquare; row++) PS_SWAP (A[row][rowIndex[col]], A[row][colIndex[col]]);
    656             }
    657         }
     586        psF64 **A = a->data.F64;
     587        psF64  *B = b->data.F64;
     588        int *colIndex = colIndexV->data.S32;
     589        int *rowIndex = rowIndexV->data.S32;
     590        int *pivot    = pivotV->data.S32;
     591        psF64 growth = 1.0;
     592
     593        for (int diag = 0; diag < nSquare; diag++) {
     594
     595            psF64 maxval = 0.0;
     596            int maxrow = 0;
     597            int maxcol = 0;
     598
     599            // search for the next pivot
     600            for (int row = 0; row < nSquare; row++) {
     601                if (!isfinite(A[row][diag])) goto escape;
     602
     603                // if we have already operated on this row (pivot[row] is true), skip it
     604                if (pivot[row]) continue;
     605
     606                // if we have not yet operated on this row (pivot[row] is false), look for pivot for this row
     607                for (int col = 0; col < nSquare; col++) {
     608                    if (pivot[col]) continue;
     609                    if (fabs (A[row][col]) < maxval) continue;
     610                    maxval = fabs (A[row][col]);
     611                    maxrow = row;
     612                    maxcol = col;
     613                }
     614            }
     615
     616            // if pivot[maxcol] is set, we have already done this row: this implies a singular matrix
     617            if (pivot[maxcol]) goto escape;
     618            pivot[maxcol] = 1;
     619
     620            // if the selected pivot is off the diagonal, do a row swap
     621            if (maxrow != maxcol) {
     622                for (int col = 0; col < nSquare; col++) PS_SWAP (A[maxrow][col], A[maxcol][col]);
     623                PS_SWAP (B[maxrow], B[maxcol]);
     624            }
     625            rowIndex[diag] = maxrow;
     626            colIndex[diag] = maxcol;
     627            if (A[maxcol][maxcol] == 0.0) goto escape;
     628            // Kahan replaces the 0.0 pivot with epsilon*(largest element in column) + underFlow.
     629            // Here we are going to raise an error if the dynamic range is too large.
     630
     631            /* rescale by pivot reciprocal */
     632            psF64 tmpval = 1.0 / A[maxcol][maxcol];
     633            A[maxcol][maxcol] = 1.0;
     634            for (int col = 0; col < nSquare; col++) A[maxcol][col] *= tmpval;
     635            B[maxcol] *= tmpval;
     636
     637            // check for ill-conditioned matrix: measure the pivot growth and trigger on over/under flow
     638            growth *= tmpval;
     639            psTrace ("psLib.math", 4, "growth : %e\n", growth);
     640            if (fabs(growth) > MAX_RANGE) goto escape;
     641
     642            /* adjust the elements above the pivot */
     643            for (int row = 0; row < nSquare; row++) {
     644                if (row == maxcol) continue;
     645                tmpval = A[row][maxcol];
     646                A[row][maxcol] = 0.0;
     647                for (int col = 0; col < nSquare; col++) A[row][col] -= A[maxcol][col]*tmpval;
     648                B[row] -= B[maxcol]*tmpval;
     649            }
     650        }
     651
     652        // swap back the inverse matrix based on the row swaps above
     653        for (int col = nSquare - 1; col >= 0; col--) {
     654            if (rowIndex[col] != colIndex[col]) {
     655                for (int row = 0; row < nSquare; row++) PS_SWAP (A[row][rowIndex[col]], A[row][colIndex[col]]);
     656            }
     657        }
    658658    }
    659659
     
    708708    if (determinant) {
    709709      // XXX this is getting the wrong value: is it the wrong calculation?
    710       // it disagrees with the results of 
     710      // it disagrees with the results of
    711711      // det = (psF32)gsl_linalg_LU_det(lu, signum);
    712712      // used in psMatrixDeterminatn
     
    753753    // Calculate determinant
    754754    gsl_linalg_LU_decomp(lu, perm, &signum);
    755     det = (psF32)gsl_linalg_LU_det(lu, signum);
     755    det = (psF32)gsl_linalg_LU_lndet(lu);
    756756
    757757    // Free GSL structs
Note: See TracChangeset for help on using the changeset viewer.