00001 #include <vecmath/GMatrix.h>
00002
00003 using namespace std;
00004
00005 const double GMatrix::EPS = 1E-10;
00006
00007 GMatrix::GMatrix(int rows, int cols, const double ad[]) {
00008 nRow = rows;
00009 nCol = cols;
00010 values.resize(rows, cols);
00011 for (int i = 0; i < rows; i++)
00012 for (int j = 0; j < cols; j++)
00013 values[i][j] = ad[i * cols + j];
00014 }
00015
00016
00017 GMatrix::GMatrix(int rows, int cols, double *data, bool preset) {
00018 nRow = rows;
00019 nCol = cols;
00020 if (preset) {
00021
00022
00023 values.setPreset(cols, data);
00024 } else {
00025 values.resize(rows, cols);
00026 for (int i = 0; i < rows; i++)
00027 for (int j = 0; j < cols; j++)
00028 values[i][j] = data[i * cols + j];
00029 }
00030 }
00031
00032 GMatrix::GMatrix(const GMatrix& gmatrix) {
00033 nRow = gmatrix.nRow;
00034 nCol = gmatrix.nCol;
00035 values.resize(nRow, nCol);
00036 for (int i = 0; i < nRow; i++)
00037 for (int j = 0; j < nCol; j++)
00038 values[i][j] = gmatrix.values[i][j];
00039 }
00040
00041 int GMatrix::LUD(GMatrix& gmatrix, GVector& gvector) {
00042 int i = gmatrix.nRow * gmatrix.nCol;
00043
00044 double *ad = new double[i];
00045 int *ai = new int[1];
00046 int *ai1 = new int[gmatrix.nRow];
00047
00048 int idx = 0;
00049 for (int i = 0; i < nRow; i++)
00050 for (int j = 0; j < nCol; j++)
00051 ad[idx++] = values[i][j];
00052
00053 idx = 0;
00054 for (int i = 0; i < nRow; i++)
00055 for (int j = 0; j < nCol; j++)
00056 gmatrix.values[i][j] = ad[idx++];
00057
00058 for (int i = 0; i < gmatrix.nRow; i++)
00059 gvector.values[i] = ai1[i];
00060
00061 delete []ad;
00062 delete []ai1;
00063
00064 return ai[0];
00065 }
00066
00067
00068 int GMatrix::SVD(GMatrix& gmatrix, GMatrix& gmatrix1, GMatrix& gmatrix2) {
00069 return computeSVD(*this, gmatrix, gmatrix1, gmatrix2, false);
00070 }
00071
00072 void GMatrix::add(const GMatrix & gmatrix) {
00073 for (int i = 0; i < nRow; i++)
00074 for (int j = 0; j < nCol; j++)
00075 values[i][j] += gmatrix.values[i][j];
00076 }
00077
00078 void GMatrix::add(const GMatrix & gmatrix, const GMatrix & gmatrix1) {
00079 for (int i = 0; i < nRow; i++)
00080 for (int j = 0; j < nCol; j++)
00081 values[i][j] = gmatrix.values[i][j] + gmatrix1.values[i][j];
00082 }
00083
00099 int GMatrix::computeSVD(GMatrix& gmatrix, GMatrix& gmatrix1, GMatrix& gmatrix2,
00100 GMatrix& gmatrix3, bool flag) {
00101 std::cerr << "GMatrix.computeSVD FIXME" << std::endl;
00102 GMatrix gmatrix4(gmatrix.nRow, gmatrix.nCol);
00103 GMatrix gmatrix5(gmatrix.nRow, gmatrix.nCol);
00104 GMatrix gmatrix6(gmatrix.nRow, gmatrix.nCol);
00105 GMatrix gmatrix7(gmatrix);
00106 int i10;
00107 int j10;
00108
00109 if (gmatrix7.nRow >= gmatrix7.nCol) {
00110 j10 = gmatrix7.nCol;
00111 i10 = gmatrix7.nCol - 1;
00112 } else {
00113 j10 = gmatrix7.nRow;
00114 i10 = gmatrix7.nRow;
00115 }
00116
00117 double *ad = new double[(gmatrix7.nRow > gmatrix7.nCol) ? gmatrix7.nRow : gmatrix7.nCol];
00118 double *ad1 = new double[j10];
00119 double *ad2 = new double[i10];
00120
00121 int ad2length = i10;
00122
00123
00124 int l9 = 0;
00125
00126 gmatrix1.setIdentity();
00127 gmatrix3.setIdentity();
00128 int nRow = gmatrix7.nRow;
00129 int nCol = gmatrix7.nCol;
00130
00131 for (int row = 0; row < j10; row++) {
00132 if (nRow > 1) {
00133 if (flag)
00134 std::cout << "************************ U ************************" << std::endl;
00135
00136 double d = 0.0;
00137
00138 for (int i = 0; i < nRow; i++) {
00139 d += Math::sqr(gmatrix7.values[i + row][row]);
00140 if (flag)
00141 std::cout << "mag= " << d << " matrix.dot=" <<
00142 gmatrix7.values[i + row][row] * gmatrix7.values[i + row][row] << std::endl;
00143 }
00144
00145 d = sqrt(d);
00146
00147 if (gmatrix7.values[row][row] == 0.0)
00148 ad[0] = d;
00149 else
00150 ad[0] = gmatrix7.values[row][row] + d_sign(d, gmatrix7.values[row][row]);
00151 for (int i = 1; i < nRow; i++)
00152 ad[i] = gmatrix7.values[row + i][row];
00153
00154 double d2 = 0.0;
00155
00156 for (int i = 0; i < nRow; i++) {
00157 if (flag)
00158 std::cout << "vec[" << i << "]=" << ad[i] << std::endl;
00159 d2 += Math::sqr(ad[i]);
00160 }
00161
00162
00163 d2 = (d2 > 0.0) ? 2.0 / d2 : 0.0;
00164
00165 if (flag)
00166 std::cout << "scale= " << d2 << std::endl;
00167
00168 for (int i = row; i < gmatrix7.nRow; i++)
00169 for (int j = row; j < gmatrix7.nRow; j++)
00170 gmatrix5.values[i][j] = -d2 * ad[i - row] * ad[j - row];
00171
00172 for (int i = row; i < gmatrix7.nRow; i++)
00173 gmatrix5.values[i][i]++;
00174
00175 double d4 = 0.0;
00176
00177 for (int i = row; i < gmatrix7.nRow; i++)
00178 d4 += gmatrix5.values[row][i] * gmatrix7.values[i][row];
00179
00180 gmatrix7.values[row][row] = d4;
00181
00182 for (int i = row; i < gmatrix7.nRow; i++)
00183 for (int j = row + 1; j < gmatrix7.nCol; j++) {
00184 double d = 0.0;
00185 for (int k = row; k < gmatrix7.nCol; k++)
00186 d += gmatrix5.values[i][k] * gmatrix7.values[k][j];
00187 gmatrix4.values[i][j] = d;
00188 }
00189
00190 for (int i = row; i < gmatrix7.nRow; i++)
00191 for (int j = row + 1; j < gmatrix7.nCol; j++)
00192 gmatrix7.values[i][j] = gmatrix4.values[i][j];
00193
00194 if (flag) {
00195
00196
00197 }
00198
00199 for (int l4 = row; l4 < gmatrix7.nRow; l4++) {
00200 for (int j7 = 0; j7 < gmatrix7.nCol; j7++) {
00201 double d = 0.0;
00202 for (int k = row; k < gmatrix7.nCol; k++)
00203 d += gmatrix5.values[l4][k] * gmatrix1.values[k][j7];
00204 gmatrix4.values[l4][j7] = d;
00205
00206 }
00207
00208 }
00209
00210 for (int i = row; i < gmatrix7.nRow; i++)
00211 for (int j = 0; j < gmatrix7.nCol; j++)
00212 gmatrix1.values[i][j] = gmatrix4.values[i][j];
00213
00214 if (flag) {
00215 std::cout << "single_values[" << row << "]=" << std::endl << ad1[row] << std::endl;
00216
00217
00218 }
00219 nRow--;
00220 }
00221 if (nCol > 2) {
00222 if (flag)
00223 std::cout << "************************ V ************************" << std::endl << std::endl;
00224 double d1 = 0.0;
00225
00226 for (int i = 1; i < nCol; i++) {
00227 std::cout << i << ", " << row << ", " << nCol
00228 << " -> " << gmatrix7.values[row][row + i] << std::endl;
00229 d1 += Math::sqr(gmatrix7.values[row][row + i]);
00230 }
00231
00232 if (flag)
00233 cout << "mag = " << d1 << endl;
00234
00235 d1 = sqrt(d1);
00236
00237
00238
00239 if (gmatrix7.values[row][row + 1] == 0.0)
00240 ad[0] = d1;
00241 else
00242 ad[0] = gmatrix7.values[row][row + 1] + d_sign(d1, gmatrix7.values[row][row + 1]);
00243
00244 for (int i = 1; i < nCol - 1; i++)
00245 ad[i] = gmatrix7.values[row][row + i + 1];
00246
00247 double d3 = 0.0;
00248
00249 for (int i = 0; i < nCol - 1; i++) {
00250 if (flag)
00251 cout << "vec[" << i << "]=" << ad[i] << endl;
00252 if (ad[i] > 0)
00253 d3 += Math::sqr(ad[i]);
00254 }
00255
00256
00257 d3 = (d3 > 0.0) ? 2.0 / d3 : 0.0;
00258
00259 if (flag)
00260 cout << "scale = " << d3 << endl;
00261
00262 for (int i = row + 1; i < nCol; i++)
00263 for (int j = row + 1; j < gmatrix7.nCol; j++)
00264 gmatrix6.values[i][j] = -d3 * ad[i - row - 1] * ad[j - row - 1];
00265
00266
00267 for (int i = row + 1; i < gmatrix7.nCol; i++)
00268 gmatrix6.values[i][i]++;
00269
00270 double d5 = 0.0;
00271
00272 for (int i = row; i < gmatrix7.nCol; i++)
00273 d5 += gmatrix6.values[i][row + 1] * gmatrix7.values[row][i];
00274
00275 gmatrix7.values[row][row + 1] = d5;
00276
00277 for (int i = row + 1; i < gmatrix7.nRow; i++) {
00278 for (int j = row + 1; j < gmatrix7.nCol; j++) {
00279 double d = 0.0;
00280 for (int k = row + 1; k < gmatrix7.nCol; k++)
00281 d += gmatrix6.values[k][j] * gmatrix7.values[i][k];
00282 gmatrix4.values[i][j] = d;
00283 }
00284 }
00285
00286 for (int i = row + 1; i < gmatrix7.nRow; i++)
00287 for (int j = row + 1; j < gmatrix7.nCol; j++)
00288 gmatrix7.values[i][j] = gmatrix4.values[i][j];
00289
00290 if (flag)
00291
00292
00293
00294
00295 for (int i = 0; i < gmatrix7.nRow; i++) {
00296 for (int j = row + 1; j < gmatrix7.nCol; j++) {
00297 double d = 0.0;
00298 for (int j3 = row + 1; j3 < gmatrix7.nCol; j3++)
00299 d += gmatrix6.values[j3][j] * gmatrix3.values[i][j3];
00300 gmatrix4.values[i][j] = d;
00301 }
00302 }
00303
00304 if (flag)
00305
00306
00307 for (int i = 0; i < gmatrix7.nRow; i++)
00308 for (int j = row + 1; j < gmatrix7.nCol; j++)
00309 gmatrix3.values[i][j] = gmatrix4.values[i][j];
00310
00311
00312 if (flag)
00313
00314
00315
00316 nCol--;
00317 }
00318 }
00319
00320 for (int i = 0; i < j10; i++)
00321 ad1[i] = gmatrix7.values[i][i];
00322
00323 for (int i = 0; i < i10; i++)
00324 ad2[i] = gmatrix7.values[i][i + 1];
00325
00326 compute_qr(0, ad2length - 1, ad1, ad2, gmatrix1, gmatrix3, flag);
00327
00328 delete []ad;
00329 delete []ad1;
00330 delete []ad2;
00331
00332
00333 return l9;
00334 }
00335
00336 int GMatrix::compute_2X2(double d, double d1, double d2, double ad[], double ad1[], double ad2[],
00337 double ad3[], double ad4[], int i) {
00338 double d3 = 2;
00339 double d4 = 1.0;
00340 double d37 = ad[0];
00341 double d36 = ad[1];
00342 double d32 = 0.0;
00343 double d33 = 0.0;
00344 double d34 = 0.0;
00345 double d35 = 0.0;
00346 double d21 = 0.0;
00347 double d25 = d;
00348 double d22 = Math::abs(d25);
00349 double d27 = d2;
00350 double d24 = Math::abs(d2);
00351 byte byte0 = 1;
00352
00353 bool flag = (d24 > d22);
00354
00355 if (flag) {
00356 byte0 = 3;
00357 double d6 = d25;
00358 d25 = d27;
00359 d27 = d6;
00360 d6 = d22;
00361 d22 = d24;
00362 d24 = d6;
00363 }
00364
00365 double d26 = d1;
00366 double d23 = Math::abs(d26);
00367
00368 if (d23 == 0.0) {
00369 ad[1] = d24;
00370 ad[0] = d22;
00371 d32 = 1.0;
00372 d33 = 1.0;
00373 d34 = 0.0;
00374 d35 = 0.0;
00375 } else {
00376 bool flag1 = true;
00377
00378 if (d23 > d22) {
00379 byte0 = 2;
00380 if (d22 / d23 < 1E-10) {
00381 flag1 = false;
00382 d37 = d23;
00383 if (d24 > 1.0)
00384 d36 = d22 / (d23 / d24);
00385 else
00386 d36 = (d22 / d23) * d24;
00387 d32 = 1.0;
00388 d34 = d27 / d26;
00389 d35 = 1.0;
00390 d33 = d25 / d26;
00391 }
00392 }
00393 if (flag1) {
00394 double d9 = d22 - d24;
00395 double d11;
00396
00397 if (d9 == d22)
00398 d11 = 1.0;
00399 else
00400 d11 = d9 / d22;
00401 double d13 = d26 / d25;
00402
00403 double d28 = d13 * d13;
00404
00405
00406 double d15;
00407
00408 if (d11 == 0.0)
00409 d15 = Math::abs(d13);
00410 else
00411 d15 = sqrt(d11 * d11 + d28);
00412
00413
00414 if (d23 > d22) {
00415 byte0 = 2;
00416 if (d22 / d23 < 1E-10) {
00417 flag1 = false;
00418 d37 = d23;
00419 if (d24 > 1.0)
00420 d36 = d22 / (d23 / d24);
00421 else
00422 d36 = (d22 / d23) * d24;
00423 d32 = 1.0;
00424 d34 = d27 / d26;
00425 d35 = 1.0;
00426 d33 = d25 / d26;
00427 }
00428 }
00429 if (flag1) {
00430 double d10 = d22 - d24;
00431 double d12;
00432
00433 if (d10 == d22)
00434 d12 = 1.0;
00435 else
00436 d12 = d10 / d22;
00437 double d14 = d26 / d25;
00438 double d20 = 2 - d12;
00439 double d29 = d14 * d14;
00440 double d31 = d20 * d20;
00441 double d18 = sqrt(d31 + d29);
00442 double d16;
00443
00444 if (d12 == 0.0)
00445 d16 = Math::abs(d14);
00446 else
00447 d16 = sqrt(d12 * d12 + d29);
00448 double d8 = (d18 + d16) * 0.5;
00449
00450 d36 = d24 / d8;
00451 d37 = d22 * d8;
00452 if (d29 == 0.0) {
00453 if (d12 == 0.0)
00454 d20 = d_sign(d3, d25) * d_sign(d4, d26);
00455 else
00456 d20 = d26 / d_sign(d10, d25) + d14 / d20;
00457 } else {
00458 d20 = (d14 / (d18 + d20) + d14 / (d16 + d12)) * (d8 + 1.0);
00459 }
00460 d12 = sqrt(d20 * d20 + 4);
00461 d33 = 2 / d12;
00462 d35 = d20 / d12;
00463 d32 = (d33 + d35 * d14) / d8;
00464 d34 = ((d27 / d25) * d35) / d8;
00465 }
00466 }
00467 if (flag) {
00468 ad2[0] = d35;
00469 ad1[0] = d33;
00470 ad4[0] = d34;
00471 ad3[0] = d32;
00472 } else {
00473 ad2[0] = d32;
00474 ad1[0] = d34;
00475 ad4[0] = d33;
00476 ad3[0] = d35;
00477 }
00478 if (byte0 == 1)
00479 d21 = d_sign(d4, ad4[0]) * d_sign(d4, ad2[0]) * d_sign(d4, d);
00480 if (byte0 == 2)
00481 d21 = d_sign(d4, ad3[0]) * d_sign(d4, ad2[0]) * d_sign(d4, d1);
00482 if (byte0 == 3)
00483 d21 = d_sign(d4, ad3[0]) * d_sign(d4, ad1[0]) * d_sign(d4, d2);
00484 ad[i] = d_sign(d37, d21);
00485 double d5 = d21 * d_sign(d4, d) * d_sign(d4, d2);
00486
00487 ad[i + 1] = d_sign(d36, d5);
00488 }
00489 return 0;
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 void GMatrix::compute_qr(int i, int j, double ad[], double ad1[], GMatrix& rot,
00548 GMatrix& scale, bool flag) {
00549 double ad2[1];
00550 double ad3[1];
00551 double ad4[1];
00552 double ad5[1];
00553 GMatrix gmatrix2(rot.nCol, scale.nRow);
00554
00555 const double EPS = 4.89E-15;
00556
00557 cerr << "GMatrix.compute_qr FIXME" << endl;
00558 if (flag) {
00559 cout << "start=" << endl << i << endl;
00560 cout << "s=" << endl;
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 }
00576 double d6 = 1.0;
00577
00578 bool flag1 = false;
00579
00580 if (flag)
00581 print_svd(ad, ad1, rot, scale);
00582 double d3 = 0.0;
00583 double d4 = 0.0;
00584
00585 for (int i2 = 0; i2 < 2 && !flag1; i2++) {
00586 int k1;
00587
00588 for (k1 = i; k1 <= j; k1++) {
00589 if (k1 == i) {
00590 int k2 = j;
00591
00592
00593
00594
00595
00596 double d = compute_shift(ad[k2 - 1], ad1[j], ad[k2]);
00597
00598 d3 = (Math::abs(ad[k1]) - d) * (d_sign(d6, ad[k1]) + d / ad[k1]);
00599 d4 = ad1[k1];
00600 }
00601 double d1 = compute_rot(d3, d4, ad5, ad3);
00602
00603 if (k1 != i)
00604 ad1[k1 - 1] = d1;
00605 d3 = ad3[0] * ad[k1] + ad5[0] * ad1[k1];
00606 ad1[k1] = ad3[0] * ad1[k1] - ad5[0] * ad[k1];
00607 d4 = ad5[0] * ad[k1 + 1];
00608 ad[k1 + 1] = ad3[0] * ad[k1 + 1];
00609 update_v(k1, scale, ad3, ad5);
00610 if (flag)
00611 print_m(gmatrix2, rot, scale);
00612 d1 = compute_rot(d3, d4, ad4, ad2);
00613 ad[k1] = d1;
00614 d3 = ad2[0] * ad1[k1] + ad4[0] * ad[k1 + 1];
00615 ad[k1 + 1] = ad2[0] * ad[k1 + 1] - ad4[0] * ad1[k1];
00616 if (k1 < j) {
00617 d4 = ad4[0] * ad1[k1 + 1];
00618 ad1[k1 + 1] = ad2[0] * ad1[k1 + 1];
00619 }
00620 update_u(k1, rot, ad2, ad4);
00621 if (flag)
00622 print_m(gmatrix2, rot, scale);
00623 }
00624
00625
00626 compute_rot(d3, d4, ad5, ad3);
00627
00628 d3 = ad3[0] * ad[k1] + ad5[0] * ad1[k1];
00629 ad1[k1] = ad3[0] * ad1[k1] - ad5[0] * ad[k1];
00630 ad[k1 + 1] = ad3[0] * ad[k1 + 1];
00631 update_v(k1, scale, ad3, ad5);
00632 if (flag)
00633 print_m(gmatrix2, rot, scale);
00634
00635 if (flag) {
00636 cout << endl << "*********************** iteration #" << i2 <<
00637 " ***********************" << endl << endl;
00638 print_svd(ad, ad1, rot, scale);
00639 }
00640 for (; j - i > 1 && Math::abs(ad1[j]) < EPS; j--) ;
00641 for (int j2 = j - 2; j2 > i; j2--)
00642 if (Math::abs(ad1[j2]) < EPS) {
00643 compute_qr(j2 + 1, j, ad, ad1, rot, scale, flag);
00644 for (j = j2 - 1; j - i > 1 && Math::abs(ad1[j]) < EPS;
00645 j--) ;
00646 }
00647
00648 if (flag)
00649 cout << "start = " << i << endl;
00650 if (j - i <= 1 && Math::abs(ad1[i + 1]) < EPS)
00651 flag1 = true;
00652 }
00653
00654 if (flag)
00655 cout << endl << "****call compute_2X2 **********************" << endl;
00656 if (Math::abs(ad1[1]) < EPS) {
00657 compute_2X2(ad[i], ad1[i], ad[i + 1], ad, ad4, ad2, ad5, ad3, 0);
00658 ad1[i] = 0.0;
00659 ad1[i + 1] = 0.0;
00660 }
00661 int l1 = i;
00662
00663 update_u(l1, rot, ad2, ad4);
00664 update_v(l1, scale, ad3, ad5);
00665 if (flag) {
00666 cout << endl << "*******after call compute_2X2 **********************" << endl;
00667 print_svd(ad, ad1, rot, scale);
00668 }
00669 }
00670
00671 double GMatrix::compute_rot(double d, double d1, double ad[], double ad1[]) {
00672 const double d8 = 2.0020830951831009E-146;
00673 const double d9 = 4.9947976805055876E+145;
00674 double d2;
00675 double d3;
00676 double d7;
00677 if (d1 == 0.0) {
00678 d2 = 1.0;
00679 d3 = 0.0;
00680 d7 = d;
00681 } else if (d == 0.0) {
00682 d2 = 0.0;
00683 d3 = 1.0;
00684 d7 = d1;
00685 } else {
00686 double d5 = d;
00687 double d6 = d1;
00688 double d4 = Math::max(Math::abs(d5), Math::abs(d6));
00689
00690 if (d4 >= d9) {
00691 int i1 = 0;
00692
00693 for (; d4 >= d9; d4 = Math::max(Math::abs(d5), Math::abs(d6))) {
00694 i1++;
00695 d5 *= d8;
00696 d6 *= d8;
00697 }
00698
00699 d7 = sqrt(d5 * d5 + d6 * d6);
00700 d2 = d5 / d7;
00701 d3 = d6 / d7;
00702
00703 for (int i = 1; i <= i1; i++)
00704 d7 *= d9;
00705
00706 } else if (d4 <= d8) {
00707 int j1 = 0;
00708
00709 for (; d4 <= d8; d4 = Math::max(Math::abs(d5), Math::abs(d6))) {
00710 j1++;
00711 d5 *= d9;
00712 d6 *= d9;
00713 }
00714
00715 d7 = sqrt(d5 * d5 + d6 * d6);
00716 d2 = d5 / d7;
00717 d3 = d6 / d7;
00718
00719 for (int i = 1; i <= j1; i++)
00720 d7 *= d8;
00721
00722 } else {
00723 d7 = sqrt(d5 * d5 + d6 * d6);
00724 d2 = d5 / d7;
00725 d3 = d6 / d7;
00726 }
00727 if (Math::abs(d) > Math::abs(d1) && d2 < 0.0) {
00728 d2 = -d2;
00729 d3 = -d3;
00730 d7 = -d7;
00731 }
00732 }
00733 ad[0] = d3;
00734 ad1[0] = d2;
00735 return d7;
00736 }
00737
00738 double GMatrix::compute_shift(double d, double d1, double d2) {
00739 double d11 = Math::abs(d);
00740 double d12 = Math::abs(d1);
00741 double d13 = Math::abs(d2);
00742 double d7 = Math::min(d11, d13);
00743 double d8 = Math::max(d11, d13);
00744 double d20;
00745
00746 if (d7 == 0.0) {
00747 d20 = 0.0;
00748 double d3;
00749 if (d8 != 0.0)
00750 d3 = Math::min(d8, d12) / Math::max(d8, d12);
00751 } else if (d12 < d8) {
00752 double d14 = d7 / d8 + 1.0;
00753 double d16 = (d8 - d7) / d8;
00754 double d4 = d12 / d8;
00755 double d18 = d4 * d4;
00756 double d9 = 2 / (sqrt(d14 * d14 + d18) + sqrt(d16 * d16 + d18));
00757
00758 d20 = d7 * d9;
00759 } else {
00760 double d19 = d8 / d12;
00761
00762 if (d19 == 0.0) {
00763 d20 = (d7 * d8) / d12;
00764 } else {
00765 double d15 = d7 / d8 + 1.0;
00766 double d17 = (d8 - d7) / d8;
00767 double d5 = d15 * d19;
00768 double d6 = d17 * d19;
00769 double d10 = 1.0 / (sqrt(d5 * d5 + 1.0) + sqrt(d6 * d6 + 1.0));
00770
00771 d20 = d7 * d10 * d19;
00772 d20 += d20;
00773 }
00774 }
00775 return d20;
00776 }
00777
00778 void GMatrix::copySubMatrix(int i, int j, int k, int l, int i1, int j1, GMatrix& gmatrix) {
00779 if (this != &gmatrix) {
00780 for (int k1 = 0; k1 < k; k1++)
00781 for (int j2 = 0; j2 < l; j2++)
00782 gmatrix.values[i1 + k1][j1 + j2] = values[i + k1][j + j2];
00783 } else {
00784 DoubleArray2 ad(k, l);
00785
00786 for (int r = 0; r < k; r++)
00787 for (int s = 0; s < l; s++)
00788 ad[r][s] = values[i + r][j + s];
00789
00790 for (int i2 = 0; i2 < k; i2++)
00791 for (int l2 = 0; l2 < l; l2++)
00792 gmatrix.values[i1 + i2][j1 + l2] = ad[i2][l2];
00793 }
00794 }
00795
00796 bool GMatrix::epsilonEquals(const GMatrix & gmatrix, double d) const {
00797 if (nRow != gmatrix.nRow || nCol != gmatrix.nCol)
00798 return false;
00799
00800 for (int i = 0; i < nRow; i++) {
00801 for (int j = 0; j < nCol; j++) {
00802 double d1 = values[i][j] - gmatrix.values[i][j];
00803 if ((d1 >= 0.0 ? d1 : -d1) > d)
00804 return false;
00805 }
00806 } return true;
00807 }
00808
00809 bool GMatrix::equals(const GMatrix & gmatrix) const {
00810 if (nRow != gmatrix.nRow || nCol != gmatrix.nCol)
00811 return false;
00812
00813 for (int i = 0; i < nRow; i++)
00814 for (int j = 0; j < nCol; j++)
00815 if (values[i][j] != gmatrix.values[i][j])
00816 return false;
00817
00818 return true;
00819 }
00820
00821 void GMatrix::get(GMatrix& gmatrix) const {
00822 int k1;
00823 if (nCol < gmatrix.nCol)
00824 k1 = nCol;
00825 else
00826 k1 = gmatrix.nCol;
00827
00828 int l1;
00829 if (nRow < gmatrix.nRow)
00830 l1 = nRow;
00831 else
00832 l1 = gmatrix.nRow;
00833
00834 for (int i = 0; i < l1; i++)
00835 for (int l = 0; l < k1; l++)
00836 gmatrix.values[i][l] = values[i][l];
00837
00838 for (int j = l1; j < gmatrix.nRow; j++)
00839 for (int i1 = 0; i1 < gmatrix.nCol; i1++)
00840 gmatrix.values[j][i1] = 0.0;
00841
00842 for (int j1 = k1; j1 < gmatrix.nCol; j1++)
00843 for (int k = 0; k < l1; k++)
00844 gmatrix.values[k][j1] = 0.0;
00845 }
00846
00847 void GMatrix::get(Matrix3d& m) const {
00848 if (nRow < 3 || nCol < 3) {
00849 for (int i = 0; i < 3; i++) {
00850 for (int j = 0; j < 3; j++)
00851 if (i < nRow && j < nCol)
00852 m(i, j) = values[i][j];
00853 else
00854 m(i, j) = 0.0;
00855 }
00856 } else {
00857 m.m00 = values[0][0];
00858 m.m01 = values[0][1];
00859 m.m02 = values[0][2];
00860 m.m10 = values[1][0];
00861 m.m11 = values[1][1];
00862 m.m12 = values[1][2];
00863 m.m20 = values[2][0];
00864 m.m21 = values[2][1];
00865 m.m22 = values[2][2];
00866 }
00867 }
00868
00869 void GMatrix::get(Matrix3f& m) const {
00870 if (nRow < 3 || nCol < 3) {
00871 for (int i = 0; i < 3; i++) {
00872 for (int j = 0; j < 3; j++)
00873 if (i < nRow && j < nCol)
00874 m(i, j) = values[i][j];
00875 else
00876 m(i, j) = 0.0;
00877 }
00878 } else {
00879 m.m00 = values[0][0];
00880 m.m01 = values[0][1];
00881 m.m02 = values[0][2];
00882 m.m10 = values[1][0];
00883 m.m11 = values[1][1];
00884 m.m12 = values[1][2];
00885 m.m20 = values[2][0];
00886 m.m21 = values[2][1];
00887 m.m22 = values[2][2];
00888 }
00889 }
00890
00891 void GMatrix::get(Matrix4d& m) const {
00892 if (nRow < 4 || nCol < 4) {
00893 for (int i = 0; i < 4; i++) {
00894 for (int j = 0; j < 4; j++)
00895 if (i < nRow && j < nCol)
00896 m(i, j) = values[i][j];
00897 else
00898 m(i, j) = 0.0;
00899 }
00900 } else {
00901 m.m00 = values[0][0];
00902 m.m01 = values[0][1];
00903 m.m02 = values[0][2];
00904 m.m03 = values[0][3];
00905 m.m10 = values[1][0];
00906 m.m11 = values[1][1];
00907 m.m12 = values[1][2];
00908 m.m13 = values[1][3];
00909 m.m20 = values[2][0];
00910 m.m21 = values[2][1];
00911 m.m22 = values[2][2];
00912 m.m23 = values[2][3];
00913 m.m30 = values[3][0];
00914 m.m31 = values[3][1];
00915 m.m32 = values[3][2];
00916 m.m33 = values[3][3];
00917 }
00918 }
00919
00920 void GMatrix::get(Matrix4f& m) const {
00921 if (nRow < 4 || nCol < 4) {
00922 for (int i = 0; i < 4; i++) {
00923 for (int j = 0; j < 4; j++)
00924 if (i < nRow && j < nCol)
00925 m(i, j) = values[i][j];
00926 else
00927 m(i, j) = 0.0;
00928 }
00929 } else {
00930 m.m00 = values[0][0];
00931 m.m01 = values[0][1];
00932 m.m02 = values[0][2];
00933 m.m03 = values[0][3];
00934 m.m10 = values[1][0];
00935 m.m11 = values[1][1];
00936 m.m12 = values[1][2];
00937 m.m13 = values[1][3];
00938 m.m20 = values[2][0];
00939 m.m21 = values[2][1];
00940 m.m22 = values[2][2];
00941 m.m23 = values[2][3];
00942 m.m30 = values[3][0];
00943 m.m31 = values[3][1];
00944 m.m32 = values[3][2];
00945 m.m33 = values[3][3];
00946 }
00947 }
00948
00949 void GMatrix::identityMinus() {
00950 for (int i = 0; i < nRow; i++)
00951 for (int k = 0; k < nCol; k++)
00952 values[i][k] = -values[i][k];
00953
00954 int l = (nRow < nCol) ? nRow : nCol;
00955 for (int i = 0; i < l; i++)
00956 values[i][i]++;
00957 }
00958
00959 void GMatrix::luBacksubstitution(int i, double ad[], int ai[], double ad1[]) {
00960 int i2 = 0;
00961 for (int l1 = 0; l1 < i; l1++) {
00962 int j2 = l1;
00963 int l = -1;
00964 for (int j = 0; j < i; j++) {
00965 int i1 = ai[i2 + j];
00966 double d1 = ad1[j2 + i * i1];
00967 ad1[j2 + i * i1] = ad1[j2 + i * j];
00968 if (l >= 0) {
00969 int k2 = j * i;
00970 for (int j1 = l; j1 <= j - 1; j1++)
00971 d1 -= ad[k2 + j1] * ad1[j2 + i * j1];
00972
00973 } else if (d1 != 0.0)
00974 l = j;
00975
00976 ad1[j2 + i * j] = d1;
00977 }
00978
00979 for (int k = 0; k < i; k++) {
00980 int i3 = i - 1 - k;
00981 int l2 = i * i3;
00982 double d = 0.0;
00983
00984 for (int k1 = 1; k1 <= k; k1++)
00985 d += ad[(l2 + i) - k1] * ad1[j2 + i * (i - k1)];
00986
00987 ad1[j2 + i * i3] = (ad1[j2 + i * i3] - d) / ad[l2 + i3];
00988 }
00989 }
00990 }
00991
00992 bool GMatrix::luDecomposition(int i, double ad[], int ai[], int ai1[]) {
00993 double *ad1 = new double[i];
00994 int l = 0;
00995 int i1 = 0;
00996 ai1[0] = 1;
00997 for (int j = i; j-- != 0;) {
00998 double d = 0.0;
00999 for (int k = i; k-- != 0;) {
01000 double d1 = ad[l++];
01001 d1 = Math::abs(d1);
01002 if (d1 > d)
01003 d = d1;
01004 }
01005
01006 if (d == 0.0)
01007 return false;
01008
01009 ad1[i1++] = 1.0 / d;
01010 }
01011
01012 int k1 = 0;
01013
01014 for (int j1 = 0; j1 < i; j1++) {
01015 for (int l1 = 0; l1 < j1; l1++) {
01016 int k3 = k1 + i * l1 + j1;
01017 double d2 = ad[k3];
01018 int l2 = l1;
01019 int j4 = k1 + i * l1;
01020
01021 for (int i5 = k1 + j1; l2-- != 0; i5 += i) {
01022 d2 -= ad[j4] * ad[i5];
01023 j4++;
01024 }
01025
01026 ad[k3] = d2;
01027 }
01028
01029 double d4 = 0.0;
01030 int k2 = -1;
01031
01032 for (int i2 = j1; i2 < i; i2++) {
01033 int l3 = k1 + i * i2 + j1;
01034 double d3 = ad[l3];
01035 int i3 = j1;
01036 int k4 = k1 + i * i2;
01037
01038 for (int j5 = k1 + j1; i3-- != 0; j5 += i) {
01039 d3 -= ad[k4] * ad[j5];
01040 k4++;
01041 }
01042
01043 ad[l3] = d3;
01044 double d5;
01045
01046 if ((d5 = ad1[i2] * Math::abs(d3)) >= d4) {
01047 d4 = d5;
01048 k2 = i2;
01049 }
01050 }
01051
01052 if (j1 != k2) {
01053 int j3 = i;
01054 int l4 = k1 + i * k2;
01055 int k5 = k1 + i * j1;
01056
01057 while (j3-- != 0) {
01058 double d6 = ad[l4];
01059
01060 ad[l4++] = ad[k5];
01061 ad[k5++] = d6;
01062 }
01063 ad1[k2] = ad1[j1];
01064 ai1[0] = -ai1[0];
01065 }
01066 ai[j1] = k2;
01067 if (ad[k1 + i * j1 + j1] == 0.0) {
01068 delete []ad1;
01069 return false;
01070 }
01071 if (j1 != i - 1) {
01072 double d7 = 1.0 / ad[k1 + i * j1 + j1];
01073 int i4 = k1 + i * (j1 + 1) + j1;
01074
01075 for (int j2 = i - 1 - j1; j2-- != 0;) {
01076 ad[i4] *= d7;
01077 i4 += i;
01078 }
01079 }
01080 }
01081
01082 delete []ad1;
01083 return true;
01084 }
01085
01086 void GMatrix::mul(const GMatrix& gmatrix) {
01087 DoubleArray2 ad(nRow, nCol);
01088 for (int i = 0; i < nRow; i++) {
01089 for (int j = 0; j < nCol; j++) {
01090 double d = 0.0;
01091 for (int k = 0; k < nCol; k++)
01092 d += values[i][k] * gmatrix.values[k][j];
01093 ad[i][j] = d;
01094 }
01095 }
01096 values.swap(ad);
01097 }
01098
01099 void GMatrix::mul(const GMatrix& gmatrix, const GMatrix& gmatrix1) {
01100 DoubleArray2 ad(nRow, nCol);
01101 for (int i = 0; i < gmatrix.nRow; i++) {
01102 for (int j = 0; j < gmatrix1.nCol; j++) {
01103 double d = 0.0;
01104 for (int k = 0; k < gmatrix.nCol; k++)
01105 d += gmatrix.values[i][k] * gmatrix1.values[k][j];
01106 ad[i][j] = d;
01107 }
01108 }
01109 values.swap(ad);
01110 }
01111
01112 void GMatrix::mul(const GVector& gvector, const GVector& gvector1) {
01113 for (int i = 0; i < gvector.getSize(); i++) {
01114 for (int j = 0; j < gvector1.getSize(); j++)
01115 values[i][j] = gvector.values[i] * gvector1.values[j];
01116 }
01117 }
01118
01119 void GMatrix::mulTransposeBoth(const GMatrix& gmatrix, const GMatrix& gmatrix1) {
01120 if (&gmatrix == this || &gmatrix1 == this) {
01121 DoubleArray2 ad(nRow, nCol);
01122 for (int i = 0; i < nRow; i++) {
01123 for (int j = 0; j < nCol; j++) {
01124 double d = 0.0;
01125 for (int k = 0; k < gmatrix.nRow; k++)
01126 d += gmatrix.values[k][i] * gmatrix1.values[j][k];
01127 ad[i][j] = d;
01128 }
01129 }
01130 values.swap(ad);
01131 } else {
01132 for (int i = 0; i < nRow; i++) {
01133 for (int j = 0; j < nCol; j++) {
01134 double d = 0.0;
01135 for (int k = 0; k < gmatrix.nRow; k++)
01136 d += gmatrix.values[k][i] * gmatrix1.values[j][k];
01137 values[i][j] = d;
01138 }
01139 }
01140 }
01141 }
01142
01143 void GMatrix::mulTransposeLeft(GMatrix gmatrix, GMatrix gmatrix1) {
01144 if (&gmatrix == this || &gmatrix1 == this) {
01145 DoubleArray2 ad(nRow, nCol);
01146
01147 for (int i = 0; i < nRow; i++) {
01148 for (int j = 0; j < nCol; j++) {
01149 double d = 0.0;
01150 for (int k = 0; k < gmatrix.nRow; k++)
01151 d += gmatrix.values[k][i] * gmatrix1.values[k][j];
01152 ad[i][j] = d;
01153 }
01154 }
01155 values.swap(ad);
01156 } else {
01157 for (int i = 0; i < nRow; i++) {
01158 for (int j = 0; j < nCol; j++) {
01159 double d = 0.0;
01160 for (int k = 0; k < gmatrix.nRow; k++)
01161 d += gmatrix.values[k][i] * gmatrix1.values[k][j];
01162 values[i][j] = d;
01163 }
01164 }
01165 }
01166 }
01167
01168 void GMatrix::mulTransposeRight(const GMatrix& gmatrix, const GMatrix& gmatrix1) {
01169 if (&gmatrix == this || &gmatrix1 == this) {
01170 DoubleArray2 ad(nRow, nCol);
01171 for (int i = 0; i < nRow; i++) {
01172 for (int k = 0; k < nCol; k++) {
01173 ad[i][k] = 0.0;
01174 for (int i1 = 0; i1 < gmatrix.nCol; i1++)
01175 ad[i][k] += gmatrix.values[i][i1] * gmatrix1.values[k][i1];
01176
01177 }
01178 }
01179 values.swap(ad);
01180 } else {
01181 for (int j = 0; j < nRow; j++) {
01182 for (int l = 0; l < nCol; l++) {
01183 values[j][l] = 0.0;
01184 for (int j1 = 0; j1 < gmatrix.nCol; j1++)
01185 values[j][l] += gmatrix.values[j][j1] * gmatrix1.values[l][j1];
01186 }
01187 }
01188 }
01189 }
01190
01191 void GMatrix::negate() {
01192 for (int i = 0; i < nRow; i++)
01193 for (int j = 0; j < nCol; j++)
01194 values[i][j] = -values[i][j];
01195 }
01196
01197 void GMatrix::negate(const GMatrix& gmatrix) {
01198 for (int i = 0; i < nRow; i++)
01199 for (int j = 0; j < nCol; j++)
01200 values[i][j] = -gmatrix.values[i][j];
01201 }
01202
01203
01204 void GMatrix::set(const GMatrix& gmatrix) {
01205 if (nRow < gmatrix.nRow || nCol < gmatrix.nCol) {
01206 nRow = gmatrix.nRow;
01207 nCol = gmatrix.nCol;
01208 values.resize(nRow, nCol);
01209 }
01210
01211 for (int i = 0; i < Math::min(nRow, gmatrix.nRow); i++) {
01212 for (int k = 0; k < Math::min(nCol, gmatrix.nCol); k++)
01213 values[i][k] = gmatrix.values[i][k];
01214 }
01215
01216 for (int j = gmatrix.nRow; j < nRow; j++) {
01217 for (int l = gmatrix.nCol; l < nCol; l++)
01218 values[j][l] = 0.0;
01219 }
01220 }
01221
01222 void GMatrix::set(const Matrix3d& matrix3d) {
01223 resizeSet(3, 3);
01224
01225 values[0][0] = matrix3d.m00;
01226 values[0][1] = matrix3d.m01;
01227 values[0][2] = matrix3d.m02;
01228 values[1][0] = matrix3d.m10;
01229 values[1][1] = matrix3d.m11;
01230 values[1][2] = matrix3d.m12;
01231 values[2][0] = matrix3d.m20;
01232 values[2][1] = matrix3d.m21;
01233 values[2][2] = matrix3d.m22;
01234
01235 #define CLEAN_REST(X) \
01236 do {\
01237 for (int i = X; i < nRow; i++)\
01238 for (int j = X; j < nCol; j++)\
01239 values[i][j] = 0.0;\
01240 } while(0)
01241 }
01242
01243 void GMatrix::set(const Matrix3f& matrix3f) {
01244 resizeSet(3, 3);
01245
01246 values[0][0] = matrix3f.m00;
01247 values[0][1] = matrix3f.m01;
01248 values[0][2] = matrix3f.m02;
01249 values[1][0] = matrix3f.m10;
01250 values[1][1] = matrix3f.m11;
01251 values[1][2] = matrix3f.m12;
01252 values[2][0] = matrix3f.m20;
01253 values[2][1] = matrix3f.m21;
01254 values[2][2] = matrix3f.m22;
01255
01256 CLEAN_REST(3);
01257 }
01258
01259 void GMatrix::set(const Matrix4d& matrix4d) {
01260 resizeSet(4, 4);
01261
01262 values[0][0] = matrix4d.m00;
01263 values[0][1] = matrix4d.m01;
01264 values[0][2] = matrix4d.m02;
01265 values[0][3] = matrix4d.m03;
01266 values[1][0] = matrix4d.m10;
01267 values[1][1] = matrix4d.m11;
01268 values[1][2] = matrix4d.m12;
01269 values[1][3] = matrix4d.m13;
01270 values[2][0] = matrix4d.m20;
01271 values[2][1] = matrix4d.m21;
01272 values[2][2] = matrix4d.m22;
01273 values[2][3] = matrix4d.m23;
01274 values[3][0] = matrix4d.m30;
01275 values[3][1] = matrix4d.m31;
01276 values[3][2] = matrix4d.m32;
01277 values[3][3] = matrix4d.m33;
01278
01279 CLEAN_REST(4);
01280 }
01281
01282 void GMatrix::set(const Matrix4f& matrix4f) {
01283 resizeSet(4, 4);
01284
01285 values[0][0] = matrix4f.m00;
01286 values[0][1] = matrix4f.m01;
01287 values[0][2] = matrix4f.m02;
01288 values[0][3] = matrix4f.m03;
01289 values[1][0] = matrix4f.m10;
01290 values[1][1] = matrix4f.m11;
01291 values[1][2] = matrix4f.m12;
01292 values[1][3] = matrix4f.m13;
01293 values[2][0] = matrix4f.m20;
01294 values[2][1] = matrix4f.m21;
01295 values[2][2] = matrix4f.m22;
01296 values[2][3] = matrix4f.m23;
01297 values[3][0] = matrix4f.m30;
01298 values[3][1] = matrix4f.m31;
01299 values[3][2] = matrix4f.m32;
01300 values[3][3] = matrix4f.m33;
01301
01302 CLEAN_REST(4);
01303 }
01304
01305 void GMatrix::set(const double ad[]) {
01306 for (int i = 0; i < nRow; i++)
01307 for (int j = 0; j < nCol; j++)
01308 values[i][j] = ad[nCol * i + j];
01309 }
01310
01311 void GMatrix::setColumn(int i, const GVector& gvector) {
01312 for (int j = 0; j < nRow; j++)
01313 values[j][i] = gvector.values[j];
01314 }
01315
01316 void GMatrix::setColumn(int i, const double ad[]) {
01317 for (int j = 0; j < nRow; j++)
01318 values[j][i] = ad[j];
01319 }
01320
01321 void GMatrix::setRow(int i, const GVector& gvector) {
01322 for (int j = 0; j < nCol; j++)
01323 values[i][j] = gvector.values[j];
01324 }
01325
01326 void GMatrix::setRow(int i, const double ad[]) {
01327 for (int j = 0; j < nCol; j++)
01328 values[i][j] = ad[j];
01329 }
01330
01331 void GMatrix::setScale(double d) {
01332 setZero();
01333 int l = (nRow < nCol) ? nRow : nCol;
01334 for (int i = 0; i < l; i++)
01335 values[i][i] = d;
01336 }
01337
01338 void GMatrix::setSize(int i, int j) {
01339 DoubleArray2 ad(i, j);
01340
01341 int i1 = (nRow < i) ? nRow : i;
01342 int j1 = (nCol < j) ? nCol : j;
01343
01344 for (int k = 0; k < i1; k++)
01345 for (int l = 0; l < j1; l++)
01346 ad[k][l] = values[k][l];
01347
01348 nRow = i;
01349 nCol = j;
01350
01351 values.swap(ad);
01352 }
01353
01354 void GMatrix::sub(const GMatrix& gmatrix) {
01355 for (int i = 0; i < nRow; i++)
01356 for (int j = 0; j < nCol; j++)
01357 values[i][j] -= gmatrix.values[i][j];
01358 }
01359
01360 void GMatrix::sub(const GMatrix& gmatrix, const GMatrix& gmatrix1) {
01361 for (int i = 0; i < nRow; i++)
01362 for (int j = 0; j < nCol; j++)
01363 values[i][j] = gmatrix.values[i][j] - gmatrix1.values[i][j];
01364 }
01365
01366 double GMatrix::trace() const {
01367 int j = (nRow < nCol) ? nRow : nCol;
01368 double d = 0.0;
01369
01370 for (int i = 0; i < j; i++)
01371 d += values[i][i];
01372
01373 return d;
01374 }
01375
01376 void GMatrix::transpose() {
01377 if (nRow != nCol) {
01378 Math::swap(nRow, nCol);
01379 DoubleArray2 ad(nRow, nCol);
01380
01381 for (int i = 0; i < nRow; i++)
01382 for (int j = 0; j < nCol; j++)
01383 ad[i][j] = values[j][i];
01384 values.swap(ad);
01385 } else {
01386 for (int i = 0; i < nRow; i++) {
01387 for (int j = 0; j < i; j++) {
01388 Math::swap(values[i][j], values[j][i]);
01389 }
01390 }
01391 }
01392 }
01393
01394 void GMatrix::transpose(const GMatrix& gmatrix) {
01395 if (&gmatrix != this) {
01396 for (int i = 0; i < nRow; i++)
01397 for (int j = 0; j < nCol; j++)
01398 values[i][j] = gmatrix.values[j][i];
01399 } else
01400 transpose();
01401 }
01402
01403
01404
01405 void GMatrix::checkMatrix(GMatrix gmatrix) {
01406 for (int i = 0; i < gmatrix.nRow; i++) {
01407 for (int j = 0; j < gmatrix.nCol; j++) {
01408 if (Math::abs(gmatrix.values[i][j]) < EPS)
01409 cout << " 0.0 ";
01410 else
01411 cout << " " << gmatrix.values[i][j];
01412 }
01413 cout << endl;
01414 }
01415 }
01416
01417 void GMatrix::invertGeneral(GMatrix& gmatrix) {
01418 int size = gmatrix.nRow * gmatrix.nCol;
01419 double *ad = new double[size];
01420 double *ad1 = new double[size];
01421 int *ai = new int[gmatrix.nRow];
01422
01423 for (int i = 0; i < nRow; i++)
01424 for (int j = 0; j < nCol; j++)
01425 ad[i * nCol + j] = gmatrix.values[i][j];
01426
01427
01428 for (int i = 0; i < size; i++)
01429 ad1[i] = 0.0;
01430
01431 for (int i = 0; i < nCol; i++)
01432 ad1[i + i * nCol] = 1.0;
01433
01434 luBacksubstitution(gmatrix.nRow, ad, ai, ad1);
01435
01436 for (int i = 0; i < nRow; i++)
01437 for (int j = 0; j < nCol; j++)
01438 values[i][j] = ad1[i * nCol + j];
01439
01440 delete []ad;
01441 delete []ad1;
01442 delete []ai;
01443 }
01444
01445
01446 void GMatrix::print_m(const GMatrix& gmatrix, const GMatrix& gmatrix1, const GMatrix& gmatrix2) {
01447 GMatrix gmatrix3(gmatrix.nCol, gmatrix.nRow);
01448
01449 gmatrix3.setIdentity();
01450
01451 gmatrix3.mul(gmatrix1, gmatrix3);
01452
01453 gmatrix3.mul(gmatrix3, gmatrix2);
01454
01455 }
01456
01457 void GMatrix::print_se(double ad[], double ad1[]) {
01458 cout << "s=" << ad[0] << " " << ad[1] << " " << ad[2] << endl;
01459 cout << "e=" << ad1[0] << " " << ad1[1] << endl;
01460 }
01461
01462 void GMatrix::print_svd(const double ad[], const double ad1[], const GMatrix& gmatrix, const GMatrix& gmatrix1) {
01463 cerr << "GMatrix.print_svd FIXME" << endl;
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475 GMatrix gmatrix2(gmatrix.nCol, gmatrix1.nRow);
01476 gmatrix2.setIdentity();
01477
01478
01479
01480
01481
01482
01483
01484 gmatrix2.mulTransposeLeft(gmatrix, gmatrix2);
01485 gmatrix2.mulTransposeRight(gmatrix2, gmatrix1);
01486
01487 }
01488
01489 void GMatrix::update_u(int i, GMatrix& gmatrix, double ad[], double ad1[]) {
01490 for (int j = 0; j < gmatrix.nCol; j++) {
01491 double d = gmatrix.values[i][j];
01492 gmatrix.values[i][j] = ad[0] * d + ad1[0] * gmatrix.values[i + 1][j];
01493 gmatrix.values[i + 1][j] = -ad1[0] * d + ad[0] * gmatrix.values[i + 1][j];
01494 }
01495 }
01496
01497
01498 void GMatrix::update_u_split(int i, int j, GMatrix& gmatrix, double ad[], double ad1[],
01499 bool flag, GMatrix& gmatrix1, GMatrix& gmatrix2) {
01500 for (int k = 0; k < gmatrix.nCol; k++) {
01501 double d = gmatrix.values[i][k];
01502 gmatrix.values[i][k] = ad[0] * d - ad1[0] * gmatrix.values[j][k];
01503 gmatrix.values[j][k] = ad1[0] * d + ad[0] * gmatrix.values[j][k];
01504 }
01505
01506 if (flag) {
01507 gmatrix1.setIdentity();
01508 for (int l = 0; l < gmatrix.nCol; l++) {
01509 double d1 = gmatrix1.values[i][l];
01510
01511 gmatrix1.values[i][l] = ad[0] * d1 - ad1[0] * gmatrix1.values[j][l];
01512 gmatrix1.values[j][l] = ad1[0] * d1 + ad[0] * gmatrix1.values[j][l];
01513 }
01514 }
01515 cout << endl << "m=" << endl;
01516 checkMatrix(gmatrix2);
01517 cout << endl << "u=" << endl;
01518 checkMatrix(gmatrix1);
01519 gmatrix2.mul(gmatrix1, gmatrix2);
01520 cout << endl << "t*m=" << endl;
01521 checkMatrix(gmatrix2);
01522 }
01523
01524 void GMatrix::update_v(int i, GMatrix& gmatrix, double ad[], double ad1[]) {
01525 for (int j = 0; j < gmatrix.nRow; j++) {
01526 double d = gmatrix.values[j][i];
01527 gmatrix.values[j][i] = ad[0] * d + ad1[0] * gmatrix.values[j][i + 1];
01528 gmatrix.values[j][i + 1] = -ad1[0] * d + ad[0] * gmatrix.values[j][i + 1];
01529 }
01530 }
01531
01532 void GMatrix::update_v_split(int i, int j, GMatrix& gmatrix, double ad[], double ad1[],
01533 bool flag, GMatrix& gmatrix1, GMatrix& gmatrix2) {
01534 for (int k = 0; k < gmatrix.nRow; k++) {
01535 double d = gmatrix.values[k][i];
01536
01537 gmatrix.values[k][i] = ad[0] * d - ad1[0] * gmatrix.values[k][j];
01538 gmatrix.values[k][j] = ad1[0] * d + ad[0] * gmatrix.values[k][j];
01539 }
01540
01541 if (flag) {
01542 gmatrix1.setIdentity();
01543 for (int l = 0; l < gmatrix.nRow; l++) {
01544 double d1 = gmatrix1.values[l][i];
01545
01546 gmatrix1.values[l][i] = ad[0] * d1 - ad1[0] * gmatrix1.values[l][j];
01547 gmatrix1.values[l][j] = ad1[0] * d1 + ad[0] * gmatrix1.values[l][j];
01548 }
01549
01550 }
01551 cout << "topr =" << i << endl;
01552 cout << "bottomr=" << j << endl;
01553 cout << "cosr=" << ad[0] << endl;
01554 cout << "sinr=" << ad1[0] << endl;
01555 cout << endl << "m=" << endl;
01556 checkMatrix(gmatrix2);
01557 cout << endl << "v=" << endl;
01558 checkMatrix(gmatrix1);
01559 gmatrix2.mul(gmatrix2, gmatrix1);
01560 cout << endl << "t*m=" << endl;
01561 checkMatrix(gmatrix2);
01562 }
01563
01564 void GMatrix::chase_across(double ad[], double ad1[], int i, GMatrix& gmatrix,
01565 bool flag) {
01566 double ad2[1];
01567 double ad3[1];
01568 GMatrix gmatrix1(gmatrix.nRow, gmatrix.nCol);
01569 GMatrix gmatrix2(gmatrix.nRow, gmatrix.nCol);
01570
01571 cerr << "GMatrix.chase_across FIXME" << endl;
01572 if (flag) {
01573 gmatrix2.setIdentity();
01574
01575
01576
01577
01578
01579 }
01580
01581 double d1 = ad1[i];
01582 double d = ad[i + 1];
01583 int l;
01584
01585 for (l = i; l < gmatrix.nCol - 2; l++) {
01586 double d2 = compute_rot(d, d1, ad3, ad2);
01587
01588 d1 = -ad1[l + 1] * ad3[0];
01589 d = ad[l + 2];
01590 ad[l + 1] = d2;
01591 ad1[l + 1] = ad1[l + 1] * ad2[0];
01592 update_u_split(i, l + 1, gmatrix, ad2, ad3, flag, gmatrix1, gmatrix2);
01593 }
01594
01595 ad[l + 1] = compute_rot(d, d1, ad3, ad2);
01596 update_u_split(i, l + 1, gmatrix, ad2, ad3, flag, gmatrix1, gmatrix2);
01597 }
01598
01599 void GMatrix::chase_up(double ad[], double ad1[], int i, GMatrix& gmatrix, bool flag) {
01600 double ad2[1];
01601 double ad3[1];
01602 GMatrix gmatrix1(gmatrix.nRow, gmatrix.nCol);
01603 GMatrix gmatrix2(gmatrix.nRow, gmatrix.nCol);
01604
01605 cerr << "GMatrix.chase_up FIXME" << endl;
01606 if (flag) {
01607 gmatrix2.setIdentity();
01608
01609
01610
01611
01612
01613 }
01614
01615 double d = ad1[i];
01616 double d1 = ad[i];
01617 int l;
01618
01619 for (l = i; l > 0; l--) {
01620 double d2 = compute_rot(d, d1, ad3, ad2);
01621
01622 d = -ad1[l - 1] * ad3[0];
01623 d1 = ad[l - 1];
01624 ad[l] = d2;
01625 ad1[l - 1] = ad1[l - 1] * ad2[0];
01626 update_v_split(l, i + 1, gmatrix, ad2, ad3, flag, gmatrix1, gmatrix2);
01627 }
01628
01629 ad[l + 1] = compute_rot(d, d1, ad3, ad2);
01630 update_v_split(l, i + 1, gmatrix, ad2, ad3, flag, gmatrix1, gmatrix2);
01631 }
01632
01633 ostream& operator <<(ostream& os, const GMatrix& m) {
01634 for (int i = 0; i < m.getNumRow(); i++) {
01635 for (int j = 0; j < m.getNumCol(); j++)
01636 os << " " << m.values[i][j];
01637 os << endl;
01638 }
01639 return os;
01640 }
01641