IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Nov 15, 2006, 3:43:39 PM (20 years ago)
Author:
magnier
Message:

added psSparseBorder for special matrices

File:
1 edited

Legend:

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

    r10001 r10009  
    1111#include "psAssert.h"
    1212#include "psConstants.h"
     13#include "psImageStructManip.h"
     14#include "psImage.h"
     15#include "psMatrix.h"
    1316#include "psSparse.h"
    1417#include "psAbort.h"
     
    210213}
    211214
    212 # if (0)
    213 
    214     /*** psSparseBorder Functions : these are used to solve a matrix equation of the form:
    215       A x = f  where A is partitioned into:
    216       A = |S B| where Q is a low-rank square matrix (N<20)
    217           |B Q| and B is a rectangular band (technically this is B and B^T)
    218       and S is a sparse matrix.
    219     */
    220 
    221     static void psSparseBorderFree(psSparse *sparse)
    222 {
    223     if (!sparse) {
     215/*** psSparseBorder Functions : these are used to solve a matrix equation of the form:
     216     A x = f  where A is partitioned into:
     217     A = |S B| where Q is a low-rank square matrix (N<20)
     218     |B Q| and B is a rectangular band (technically this is B and B^T)
     219     and S is a sparse matrix.
     220*/
     221
     222static void psSparseBorderFree(psSparseBorder *border)
     223{
     224    if (!border) {
    224225        return;
    225226    }
    226     psFree(sparse->Bij);
    227     psFree(sparse->Qii);
     227    psFree(border->sparse);
     228    psFree(border->Bij);
     229    psFree(border->Tjj);
     230    psFree(border->Gj);
    228231    return;
    229232}
     
    236239    psMemSetDeallocator(border, (psFreeFunc) psSparseBorderFree);
    237240
     241    border->sparse = psMemIncrRefCounter (sparse); // XXX increment ref counter or not?
     242
    238243    int Nrows = sparse->Nrows;
    239244    border->Nrows = Nrows;
     
    243248    psImageInit (border->Bij, 0.0);
    244249
    245     border->Qii = psImageAlloc(Nborder, Nborder, PS_DATA_F32);
    246     psImageInit (border->Qii, 0.0);
    247 
    248     border->Yi = psVectorAlloc(Nborder, PS_DATA_F32);
    249     psVectorInit (border->Yi, 0.0);
    250 
    251     border->Gi = psVectorAlloc(Nborder, PS_DATA_F32);
    252     psVectorInit (border->Gi, 0.0);
     250    border->Tjj = psImageAlloc(Nborder, Nborder, PS_DATA_F32);
     251    psImageInit (border->Tjj, 0.0);
     252
     253    border->Gj = psVectorAlloc(Nborder, PS_DATA_F32);
     254    psVectorInit (border->Gj, 0.0);
    253255
    254256    return border;
    255257}
    256258
    257 // add elements to border->Qii
    258 bool psSparseBorderElementQ(psSparseBorder *border, int i, int j, float value)
     259// add elements to border->Tjj
     260bool psSparseBorderElementT(psSparseBorder *border, int i, int j, float value)
    259261{
    260262    PS_ASSERT_PTR_NON_NULL(border, false);
    261     PS_ASSERT_PTR_NON_NULL(border->Qii, false);
     263    PS_ASSERT_PTR_NON_NULL(border->Tjj, false);
    262264    PS_ASSERT_INT_NONNEGATIVE(i, false);
    263265    PS_ASSERT_INT_NONNEGATIVE(j, false);
    264266
    265     // check i,j against border->Qii->nX,nY
    266     border->Qii->data.F32[i][j] = value;
     267    // check i,j against border->Tjj->nX,nY
     268    border->Tjj->data.F32[i][j] = value;
    267269    return true;
    268270}
     
    280282}
    281283
    282 // add elements to border->Yi
    283 bool psSparseBorderElementY(psSparseBorder *border, int i, float value)
     284// add elements to border->Gj
     285bool psSparseBorderElementG(psSparseBorder *border, int i, float value)
    284286{
    285287    PS_ASSERT_PTR_NON_NULL(border, false);
    286     PS_ASSERT_PTR_NON_NULL(border->Yi, false);
     288    PS_ASSERT_PTR_NON_NULL(border->Gj, false);
    287289    PS_ASSERT_INT_NONNEGATIVE(i, false);
    288290
    289     border->Yi->data.F32[i] = value;
    290     return true;
    291 }
    292 
    293 // add elements to border->Gi
    294 bool psSparseBorderElementY(psSparseBorder *border, int i, float value)
    295 {
    296     PS_ASSERT_PTR_NON_NULL(border, false);
    297     PS_ASSERT_PTR_NON_NULL(border->Gi, false);
    298     PS_ASSERT_INT_NONNEGATIVE(i, false);
    299 
    300     border->Gi->data.F32[i] = value;
     291    border->Gj->data.F32[i] = value;
    301292    return true;
    302293}
    303294
    304295// perform the operation dG = B*x
    305 psVector *psSparseBorderUpperProduct (psSparse *border)
    306 {
     296psVector *psSparseBorderLowerProduct (psVector *dG, psSparseBorder *border, psVector *xVec)
     297{
     298    // XXX assert xVec->n == border->Nrows
    307299
    308300    int Nborder = border->Nborder;
    309     int Nrow = border->Nrows;
    310 
    311     psVector *dG = psVectorAlloc (Nborder, PS_DATA_F32);
     301    int Nrows = border->Nrows;
     302
     303    dG = psVectorRecycle (dG, Nborder, PS_TYPE_F32);
    312304    psVectorInit (dG, 0.0);
    313305
     
    315307        double value = 0;
    316308        for (int i = 0; i < Nrows; i++) {
    317             value += border->Bij->data.F32[i][j] * x->data.F32[i];
     309            value += border->Bij->data.F32[i][j] * xVec->data.F32[i];
    318310        }
    319311        dG->data.F32[j] = value;
     
    324316
    325317// perform the operation dF = B^T*y
    326 psVector *psSparseBorderLowerProduct (psSparse *border)
    327 {
     318psVector *psSparseBorderUpperProduct (psVector *dF, psSparseBorder *border, psVector *yVec)
     319{
     320    // XXX assert yVec->n == border->Nborder
    328321
    329322    int Nborder = border->Nborder;
    330     int Nrow = border->Nrows;
    331 
    332     psVector *dF = psVectorAlloc (Nrows, PS_DATA_F32);
     323    int Nrows = border->Nrows;
     324
     325    dF = psVectorRecycle (dF, Nrows, PS_TYPE_F32);
    333326    psVectorInit (dF, 0.0);
    334327
     
    336329        double value = 0;
    337330        for (int j = 0; j < Nborder; j++) {
    338             value += border->Bij->data.F32[i][j] * border->Yi->data.F32[j];
     331            value += border->Bij->data.F32[i][j] * yVec->data.F32[j];
    339332        }
    340333        dF->data.F32[i] = value;
     
    344337}
    345338
     339// perform the operation dG = T*y
     340psVector *psSparseBorderSquareProduct (psVector *dG, psSparseBorder *border, psVector *yVec)
     341{
     342    // XXX assert yVec->n == border->Nborder
     343
     344    int Nborder = border->Nborder;
     345
     346    dG = psVectorRecycle (dG, Nborder, PS_TYPE_F32);
     347    psVectorInit (dG, 0.0);
     348
     349    for (int i = 0; i < Nborder; i++) {
     350        double value = 0;
     351        for (int j = 0; j < Nborder; j++) {
     352            value += border->Tjj->data.F32[j][i] * yVec->data.F32[j];
     353        }
     354        dG->data.F32[i] = value;
     355    }
     356
     357    return dG;
     358}
     359
    346360// perform the operation dF = B^T*y
    347 psVector *psSparseBorderUpperDelta (psSparse *border, psVector *dF)
    348 {
    349 
    350     int Nborder = border->Nborder;
    351     int Nrow = border->Nrows;
     361bool psSparseBorderUpperDelta (psSparseBorder *border, psVector *dF)
     362{
     363
     364    int Nrows = border->Nrows;
    352365
    353366    for (int i = 0; i < Nrows; i++) {
     
    359372
    360373// perform the operation dF = B^T*y
    361 psVector *psSparseBorderLowerDelta (psSparse *border, psVector *dG)
     374bool psSparseBorderLowerDelta (psSparseBorder *border, psVector *dG)
    362375{
    363376
    364377    int Nborder = border->Nborder;
    365     int Nrow = border->Nrows;
    366378
    367379    for (int i = 0; i < Nborder; i++) {
    368         border->Gi->data.F32[i] -= dG->data.F32[i];
    369     }
    370 
    371     return true;
    372 }
    373 # endif /* gene's dev work */
     380        border->Gj->data.F32[i] -= dG->data.F32[i];
     381    }
     382
     383    return true;
     384}
     385
     386// multiply A*x = b (where x is (x,y) and b is (f,g))
     387bool psSparseBorderMultiply (psVector **fIn, psVector **gIn, psSparseBorder *border, psVector *xVec, psVector *yVec)
     388{
     389    psVector *fVec = *fIn;
     390    fVec = psSparseMatrixTimesVector (fVec, border->sparse, xVec);
     391    psVector *dF = psSparseBorderUpperProduct (NULL, border, yVec);
     392    for (int i = 0; i < border->Nrows; i++) {
     393        fVec->data.F32[i] += dF->data.F32[i];
     394    }
     395    psFree (dF);
     396    *fIn = fVec;
     397
     398    psVector *gVec = *gIn;
     399    gVec = psSparseBorderSquareProduct (gVec, border, yVec);
     400    psVector *dG = psSparseBorderLowerProduct (NULL, border, xVec);
     401    for (int i = 0; i < border->Nborder; i++) {
     402        gVec->data.F32[i] += dG->data.F32[i];
     403    }
     404    psFree (dG);
     405    *gIn = gVec;
     406
     407    return true;
     408}
     409
     410bool psSparseBorderSolve(psVector **xFit, psVector **yFit, psSparseConstraint constraint, psSparseBorder *border, int Niter)
     411{
     412    // PS_ASSERT_PTR_NON_NULL(sparse, NULL);
     413    // PS_ASSERT_INT_POSITIVE(Niter, NULL);
     414    // PS_ASSERT_FLOAT_LARGER_THAN(constraint.paramDelta, 0.0, NULL);
     415
     416    psVector *xVec = *xFit;
     417    psVector *yVec = *yFit;
     418
     419    for (int j = 0; j < Niter; j++) {
     420
     421        // solve Sx = f
     422        xVec = psSparseSolve(xVec, constraint, border->sparse, Niter);
     423
     424        psVector *dG = psSparseBorderLowerProduct (NULL, border, xVec);
     425        psSparseBorderLowerDelta (border, dG);
     426
     427        // XXX not defined
     428        psImage *square = psImageCopy (NULL, border->Tjj, PS_TYPE_F32);
     429        psVectorCopy (yVec, border->Gj, PS_TYPE_F32);
     430        psMatrixGJSolve (square, yVec);
     431        psFree (square);
     432
     433        psVector *dF = psSparseBorderUpperProduct (NULL, border, yVec);
     434        psSparseBorderUpperDelta (border, dF);
     435
     436        psFree (dF);
     437        psFree (dG);
     438    }
     439
     440    *xFit = xVec;
     441    *yFit = yVec;
     442    return true;
     443}
Note: See TracChangeset for help on using the changeset viewer.