IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 24080


Ignore:
Timestamp:
May 6, 2009, 2:14:25 PM (17 years ago)
Author:
eugene
Message:

add test for excessive pivot growth (ill-conditioned matrix)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/libohana/src/gaussj.c

    r16120 r24080  
    11# include <ohana.h>
     2# define GROWTHTEST 0
     3# define MAX_RANGE 1.0e7
    24
    35// Gauss-Jordan elimination using full pivots based on Press et al's description.  Substantially
    46// reworked for Ohana: major modifications to conform to C indexing, use a boolean to track the
    57// completed pivot rows and catch the singular matrix early on.  Also, much cleaner control loops
    6 // than their implementation.  XXX this really needs to check on round-off errors (see version by
    7 // William Kahan
     8// than their implementation.  (largely based on version by William Kahan)
     9
     10// MAX_RANGE is used to test for ill-conditioned input matrices.  For an ill-conditioned
     11// matrix, one or more of the pivots trends towards zero.  Rather than allow this to go to the
     12// numerical precision, I am raising an error if |growth| > 1e8
    813int dgaussjordan (double **A, double **B, int N, int M) {
    914
     
    1924  memset (pivot, 0, N*sizeof(int));
    2025
     26  double growth = 1.0;
     27
    2128  // determine underflow conditions
    2229  // double underFlow = DBL_MIN;
    23 # if (0)
     30# if (GROWTHTEST)
    2431  double roundTest = 4.0;
    2532  roundTest /= 3.0;
    2633  roundTest -= 1.0;
    2734  double epsilon = fabs(((roundTest+roundTest) - 1.0) + roundTest);
    28   double growth = 1.0;
    2935# endif
    3036
     
    5763    }
    5864
     65# if (GROWTHTEST)
     66    fprintf (stderr, "maxcol: %d\n", maxcol);
     67    fprintf (stderr, "full A matrix:\n");
     68    for (row = 0; row < N; row++) {
     69        for (col = 0; col < N; col++) {
     70            fprintf (stderr, "%10.3e ", A[row][col]);
     71        }
     72        fprintf (stderr, "\n");
     73    }
     74    fprintf (stderr, "\n");
     75# endif
     76
    5977    // if pivot[maxcol] is set, we have already done this row: this implies a singular matrix
    6078    if (pivot[maxcol]) goto escape;
     
    7694    for (col = 0; col < N; col++) A[maxcol][col] *= tmpval;
    7795    for (col = 0; col < M; col++) B[maxcol][col] *= tmpval;
    78     // XXX measure the pivot growth and trigger on over/under flow
    79     // growth *= tmpval;
    80     // fprintf (stderr, "column: %d, growth: %e, epsilon: %e\n", maxcol, growth, epsilon);
     96
     97    // check for ill-conditioned matrix
     98    growth *= tmpval;
     99
     100    // report the pivot growth
     101#   if (GROWTHTEST)
     102    fprintf (stderr, "column: %d, maxval : %f, growth: %e, epsilon: %e\n", maxcol, tmpval, growth, epsilon);
     103    fprintf (stderr, "A diagonal: ");
     104    for (col = 0; col < N; col++) fprintf (stderr, "%f ", A[col][col]);
     105    fprintf (stderr, "\n");
     106# endif
     107
     108    if (fabs(growth) > MAX_RANGE) goto escape;
    81109
    82110    /* adjust the elements above the pivot */
     
    122150  memset (pivot, 0, N*sizeof(int));
    123151
     152  float growth = 1.0;
     153
    124154  // determine underflow conditions
    125155  // float underFlow = FLT_MIN;
    126 # if (0)
     156# if (GROWTHTEST)
    127157  float roundTest = 4.0;
    128158  roundTest /= 3.0;
    129159  roundTest -= 1.0;
    130160  float epsilon = fabs(((roundTest+roundTest) - 1.0) + roundTest);
    131   float growth = 1.0;
    132161# endif
    133162
     
    179208    for (col = 0; col < N; col++) A[maxcol][col] *= tmpval;
    180209    for (col = 0; col < M; col++) B[maxcol][col] *= tmpval;
    181     // growth *= tmpval;
    182     // fprintf (stderr, "column: %d, growth: %e, epsilon: %e\n", maxcol, growth, epsilon);
     210
     211    // check for ill-conditioned matrix
     212    growth *= tmpval;
     213
     214    // report the pivot growth
     215#   if (GROWTHTEST)
     216    fprintf (stderr, "column: %d, maxval : %f, growth: %e, epsilon: %e\n", maxcol, tmpval, growth, epsilon);
     217    fprintf (stderr, "A diagonal: ");
     218    for (col = 0; col < N; col++) fprintf (stderr, "%f ", A[col][col]);
     219    fprintf (stderr, "\n");
     220# endif
     221
     222    if (fabs(growth) > MAX_RANGE) goto escape;
    183223
    184224    /* adjust the elements above the pivot */
Note: See TracChangeset for help on using the changeset viewer.