Changeset 10009 for trunk/psLib/src/math/psSparse.c
- Timestamp:
- Nov 15, 2006, 3:43:39 PM (20 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psSparse.c (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psSparse.c
r10001 r10009 11 11 #include "psAssert.h" 12 12 #include "psConstants.h" 13 #include "psImageStructManip.h" 14 #include "psImage.h" 15 #include "psMatrix.h" 13 16 #include "psSparse.h" 14 17 #include "psAbort.h" … … 210 213 } 211 214 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 222 static void psSparseBorderFree(psSparseBorder *border) 223 { 224 if (!border) { 224 225 return; 225 226 } 226 psFree(sparse->Bij); 227 psFree(sparse->Qii); 227 psFree(border->sparse); 228 psFree(border->Bij); 229 psFree(border->Tjj); 230 psFree(border->Gj); 228 231 return; 229 232 } … … 236 239 psMemSetDeallocator(border, (psFreeFunc) psSparseBorderFree); 237 240 241 border->sparse = psMemIncrRefCounter (sparse); // XXX increment ref counter or not? 242 238 243 int Nrows = sparse->Nrows; 239 244 border->Nrows = Nrows; … … 243 248 psImageInit (border->Bij, 0.0); 244 249 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); 253 255 254 256 return border; 255 257 } 256 258 257 // add elements to border-> Qii258 bool psSparseBorderElement Q(psSparseBorder *border, int i, int j, float value)259 // add elements to border->Tjj 260 bool psSparseBorderElementT(psSparseBorder *border, int i, int j, float value) 259 261 { 260 262 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); 262 264 PS_ASSERT_INT_NONNEGATIVE(i, false); 263 265 PS_ASSERT_INT_NONNEGATIVE(j, false); 264 266 265 // check i,j against border-> Qii->nX,nY266 border-> Qii->data.F32[i][j] = value;267 // check i,j against border->Tjj->nX,nY 268 border->Tjj->data.F32[i][j] = value; 267 269 return true; 268 270 } … … 280 282 } 281 283 282 // add elements to border-> Yi283 bool psSparseBorderElement Y(psSparseBorder *border, int i, float value)284 // add elements to border->Gj 285 bool psSparseBorderElementG(psSparseBorder *border, int i, float value) 284 286 { 285 287 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); 287 289 PS_ASSERT_INT_NONNEGATIVE(i, false); 288 290 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; 301 292 return true; 302 293 } 303 294 304 295 // perform the operation dG = B*x 305 psVector *psSparseBorderUpperProduct (psSparse *border) 306 { 296 psVector *psSparseBorderLowerProduct (psVector *dG, psSparseBorder *border, psVector *xVec) 297 { 298 // XXX assert xVec->n == border->Nrows 307 299 308 300 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); 312 304 psVectorInit (dG, 0.0); 313 305 … … 315 307 double value = 0; 316 308 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]; 318 310 } 319 311 dG->data.F32[j] = value; … … 324 316 325 317 // perform the operation dF = B^T*y 326 psVector *psSparseBorderLowerProduct (psSparse *border) 327 { 318 psVector *psSparseBorderUpperProduct (psVector *dF, psSparseBorder *border, psVector *yVec) 319 { 320 // XXX assert yVec->n == border->Nborder 328 321 329 322 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); 333 326 psVectorInit (dF, 0.0); 334 327 … … 336 329 double value = 0; 337 330 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]; 339 332 } 340 333 dF->data.F32[i] = value; … … 344 337 } 345 338 339 // perform the operation dG = T*y 340 psVector *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 346 360 // 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; 361 bool psSparseBorderUpperDelta (psSparseBorder *border, psVector *dF) 362 { 363 364 int Nrows = border->Nrows; 352 365 353 366 for (int i = 0; i < Nrows; i++) { … … 359 372 360 373 // perform the operation dF = B^T*y 361 psVector *psSparseBorderLowerDelta (psSparse*border, psVector *dG)374 bool psSparseBorderLowerDelta (psSparseBorder *border, psVector *dG) 362 375 { 363 376 364 377 int Nborder = border->Nborder; 365 int Nrow = border->Nrows;366 378 367 379 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)) 387 bool 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 410 bool 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.
