Changeset 25842 for branches/pap/psLib/src/math/psMatrix.c
- Timestamp:
- Oct 14, 2009, 12:50:26 PM (17 years ago)
- File:
-
- 1 edited
-
branches/pap/psLib/src/math/psMatrix.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/pap/psLib/src/math/psMatrix.c
r24122 r25842 379 379 switch (a->type.type) { 380 380 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; 394 394 } 395 395 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; 409 409 } 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); 412 412 default: 413 psAbort("Should never get here.");413 psAbort("Should never get here."); 414 414 } 415 415 … … 471 471 switch (a->type.type) { 472 472 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; 483 483 } 484 484 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; 495 495 } 496 496 default: 497 psAbort("Should never get here.");498 } 499 497 psAbort("Should never get here."); 498 } 499 500 500 // Following the algorithm laid out by Press et al., we loop along the matrix diagonal, but 501 501 // we do not operate on the diagonal elements in order. Instead, we are looking for the … … 511 511 512 512 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 pivot527 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 it531 if (pivot[row]) continue;532 533 // if we have not yet operated on this row (pivot[row] is false), look for pivot for this row534 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 matrix544 if (pivot[maxcol]) goto escape;545 pivot[maxcol] = 1;546 547 // if the selected pivot is off the diagonal, do a row swap548 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 flow565 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 above580 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 } 585 585 } 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 pivot600 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 it604 if (pivot[row]) continue;605 606 // if we have not yet operated on this row (pivot[row] is false), look for pivot for this row607 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 matrix617 if (pivot[maxcol]) goto escape;618 pivot[maxcol] = 1;619 620 // if the selected pivot is off the diagonal, do a row swap621 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 flow638 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 above653 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 } 658 658 } 659 659 … … 708 708 if (determinant) { 709 709 // 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 711 711 // det = (psF32)gsl_linalg_LU_det(lu, signum); 712 712 // used in psMatrixDeterminatn … … 753 753 // Calculate determinant 754 754 gsl_linalg_LU_decomp(lu, perm, &signum); 755 det = (psF32)gsl_linalg_LU_ det(lu, signum);755 det = (psF32)gsl_linalg_LU_lndet(lu); 756 756 757 757 // Free GSL structs
Note:
See TracChangeset
for help on using the changeset viewer.
