IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Dec 11, 2007, 12:10:13 PM (18 years ago)
Author:
Paul Price
Message:

Fixing matrix multiplication. The check of dimensions was wrong, so I
went ahead and fixed the lot. Matrix multiplication is sufficiently
simple to implement that we shouldn't have to wrap GSL.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/math/psMatrix.c

    r15768 r15785  
    2222 *  @author Andy Becker, University of Washington (SVD).
    2323 *
    24  *  @version $Revision: 1.51 $ $Name: not supported by cvs2svn $
    25  *  @date $Date: 2007-12-08 01:48:34 $
     24 *  @version $Revision: 1.52 $ $Name: not supported by cvs2svn $
     25 *  @date $Date: 2007-12-11 22:10:13 $
    2626 *
    2727 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    555555    gsl_linalg_LU_invert(lu, perm, inv);
    556556    if (determinant) {
    557         *determinant = (float)gsl_linalg_LU_det(lu, signum);
     557        *determinant = (float)gsl_linalg_LU_lndet(lu);
    558558    }
    559559
     
    609609                          const psImage* in2)
    610610{
    611     gsl_matrix *m1 = NULL;
    612     gsl_matrix *m2 = NULL;
    613     gsl_matrix *m3 = NULL;
    614 
    615611    #define MULTIPLY_CLEANUP { psFree(out); return NULL; }
    616612
     
    625621    PS_CHECK_POINTERS(in1, in2, MULTIPLY_CLEANUP);
    626622
    627     if (in1->numRows != in2->numCols) {
    628         psError(PS_ERR_BAD_PARAMETER_SIZE, true, "Invalid operation: number of rows of in1 != number of cols of in2.");
     623    int rows1 = in1->numRows, cols1 = in1->numCols; // Size of input 1
     624    int rows2 = in2->numRows, cols2 = in2->numCols; // Size of input 2
     625    if (cols1 != rows2) {
     626        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
     627                "Incompatible dimensions for matrix multiplication: %dx%d * %dx%d (row x col)",
     628                rows1, cols1, rows2, cols2);
    629629        MULTIPLY_CLEANUP;
    630630    }
     631    int common = cols1;                 // Common dimension
     632
    631633    if (in1->type.type != in2->type.type) {
    632634        psError(PS_ERR_BAD_PARAMETER_SIZE, true, "Invalid operation: data types of in1 and in2 must match.");
     
    634636    }
    635637
    636     out = psImageRecycle(out, in2->numCols, in1->numRows, in2->type.type);
    637 
    638     // Initialize GSL data
    639     m1 = gsl_matrix_alloc(in1->numRows, in1->numCols);
    640     psImageToGslMatrix(m1, in1);
    641     m2 = gsl_matrix_alloc(in2->numRows, in2->numCols);
    642     psImageToGslMatrix(m2, in2);
    643     m3 = gsl_matrix_alloc(out->numRows, out->numCols);
    644 
    645     // Perform multiplication
    646     // gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, m1, m2, 0.0, m3);
    647     gsl_linalg_matmult(m1, m2, m3);
    648 
    649     // Copy GSL matrix data to psImage data
    650     gslMatrixToPsImage(out, m3);
    651 
    652     // Free GSL structs
    653     gsl_matrix_free(m1);
    654     gsl_matrix_free(m2);
    655     gsl_matrix_free(m3);
     638    psElemType type = in1->type.type;   // Data type
     639    int outRows = rows1, outCols = cols2; // Size of output
     640    out = psImageRecycle(out, outCols, outRows, type);
     641
     642#define MATRIX_MULTIPLY_CASE(TYPE) \
     643  case PS_TYPE_##TYPE: \
     644    for (int i = 0; i < outRows; i++) { \
     645        for (int j = 0; j < outCols; j++) { \
     646            ps##TYPE value = 0.0; \
     647            for (int k = 0; k < common; k++) { \
     648                value += in1->data.TYPE[i][k] * in2->data.TYPE[k][j]; \
     649            } \
     650            out->data.TYPE[i][j] = value; \
     651        } \
     652    } \
     653    break;
     654
     655    switch (type) {
     656        MATRIX_MULTIPLY_CASE(F32);
     657        MATRIX_MULTIPLY_CASE(F64);
     658      default:
     659        psAbort("Should never get here.  Unsupported type: %x", type);
     660    }
    656661
    657662    return out;
Note: See TracChangeset for help on using the changeset viewer.