GMatrix.cc

Go to the documentation of this file.
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 // extension
00017 GMatrix::GMatrix(int rows, int cols, double *data, bool preset) {
00018     nRow = rows;
00019     nCol = cols;
00020     if (preset) {
00021         //cout << "Using preset: " << data << endl;
00022         // use preset directly !!!
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 // from - to, scale,  rot
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 //    if (flag) cout << "input to compute_svd = " << endl << gmatrix7 << endl;
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 //              cout << "U=" << endl << gmatrix1 << endl;
00196 //              cout << "u=" << endl << gmatrix5 << endl;
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 //              cout << "m=" << endl << gmatrix7 << endl;
00217 //              cout << "U=" << endl << gmatrix1 << endl;
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 //            cout << gmatrix7 << endl;
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 //              cout << "V=" << endl << gmatrix3 << endl
00292 //                  << "v=" << endl << gmatrix6 << endl
00293 //                  << "tmp=" << endl << gmatrix4 << endl;
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 //              cout << "tmp=" << endl << gmatrix4 << endl;
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 //              cout << "m=" << endl << gmatrix7 << endl
00314 //                  << "V=" << endl << gmatrix3 << endl;
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         //l9 = ad1.length;
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             //double d19 = 2 - d11; unused
00403             double d28 = d13 * d13;
00404             //double d30 = d19 * d19;
00405             //double d17 = sqrt(d30 + d28);
00406             double d15;
00407 
00408             if (d11 == 0.0)
00409                 d15 = Math::abs(d13);
00410             else
00411                 d15 = sqrt(d11 * d11 + d28);
00412             //double d7 = (d17 + d15) * 0.5;
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  *              QR-diagonalization of a bidiagonal matrix
00496  *
00497  * After bidiagonalization we get a bidiagonal matrix J:
00498  *    (1)  J = U' * A * V
00499  * The present method turns J into a matrix JJ by applying a set of
00500  * orthogonal transforms
00501  *    (2)  JJ = S' * J * T
00502  * Orthogonal matrices S and T are chosen so that JJ were also a
00503  * bidiagonal matrix, but with superdiag elements smaller than those of J.
00504  * We repeat (2) until non-diag elements of JJ become smaller than EPS
00505  * and can be disregarded.
00506  * Matrices S and T are constructed as
00507  *    (3)  S = S1 * S2 * S3 ... Sn, and similarly T
00508  * where Sk and Tk are matrices of simple rotations
00509  *    (4)  Sk[i,j] = i==j ? 1 : 0 for all i>k or i<k-1
00510  *         Sk[k-1,k-1] = cos(Phk),  Sk[k-1,k] = -sin(Phk),
00511  *         SK[k,k-1] = sin(Phk),    Sk[k,k] = cos(Phk), k=2..N
00512  * Matrix Tk is constructed similarly, only with angle Thk rather than Phk.
00513  *
00514  * Thus left multiplication of J by SK' can be spelled out as
00515  *    (5)  (Sk' * J)[i,j] = J[i,j] when i>k or i<k-1,
00516  *                  [k-1,j] = cos(Phk)*J[k-1,j] + sin(Phk)*J[k,j]
00517  *                  [k,j] =  -sin(Phk)*J[k-1,j] + cos(Phk)*J[k,j]
00518  * That is, k-1 and k rows of J are replaced by their linear combinations;
00519  * the rest of J is unaffected. Right multiplication of J by Tk similarly
00520  * changes only k-1 and k columns of J.
00521  * Matrix T2 is chosen the way that T2'J'JT2 were a QR-transform with a
00522  * shift. Note that multiplying J by T2 gives rise to a J[2,1] element of
00523  * the product J (which is below the main diagonal). Angle Ph2 is then
00524  * chosen so that multiplication by S2' (which combines 1 and 2 rows of J)
00525  * gets rid of that elemnent. But this will create a [1,3] non-zero element.
00526  * T3 is made to make it disappear, but this leads to [3,2], etc.
00527  * In the end, Sn removes a [N,N-1] element of J and matrix S'JT becomes
00528  * bidiagonal again. However, because of a special choice
00529  * of T2 (QR-algorithm), its non-diag elements are smaller than those of J.
00530  *
00531  * All this process in more detail is described in
00532  *    J.H. Wilkinson, C. Reinsch. Linear algebra - Springer-Verlag, 1971
00533  *
00534  * If during transforms (1), JJ[N-1,N] turns 0, then JJ[N,N] is a singular
00535  * number (possibly with a wrong (that is, negative) sign). This is a
00536  * consequence of Frantsis' Theorem, see the book above. In that case, we can
00537  * eliminate the N-th row and column of JJ and carry out further transforms
00538  * with a smaller matrix. If any other superdiag element of JJ turns 0,
00539  * then JJ effectively falls into two independent matrices. We will process
00540  * them independently (the bottom one first).
00541  *
00542  * Since matrix J is a bidiagonal, it can be stored efficiently. As a matter
00543  * of fact, its N diagonal elements are in array Sig, and superdiag elements
00544  * are stored in array super_diag.
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     //byte byte0 = 2;
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         //          for (int k = 0; k < ad.length; k++)
00562         //              cout << ad[k];
00563         //
00564         //          cout << "es=" << endl;
00565         //          for (int l = 0; l < ad1.length; l++)
00566         //              cout << ad1[l];
00567         //
00568         //          for (int i1 = 0; i1 < ad.length; i1++)
00569         //              gmatrix2.values[i1][i1] = ad[i1];
00570         //
00571         //          for (int j1 = 0; j1 < ad1.length; j1++)
00572         //          gmatrix2.values[j1][j1 + 1] = ad1[j1];
00573 
00574 //      cout << endl << "m=" << endl << gmatrix2 << endl;
00575     }
00576     double d6 = 1.0;
00577     //double d7 = -1;
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                 // FIXME
00592                 //                  if (ad1.length == ad.length)
00593                 //                      k2 = j;
00594                 //                  else
00595                 //                      k2 = j + 1;
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 //      if (ad.length == ad1.length) {
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 // private
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     // identity
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     // G3 = U * E
01451     gmatrix3.mul(gmatrix1, gmatrix3);
01452     // G3 = G3 * V
01453     gmatrix3.mul(gmatrix3, gmatrix2);
01454 //    cout << endl << "m = " << endl << gmatrix3 << gmatrix1 << gmatrix2 << endl;
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     //          cout << endl << "s = " << endl;
01466     //          for (int i = 0; i < ad.length; i++)
01467     //              cout << " " << ad[i];
01468     //
01469     //          cout << endl << "e = " << endl;
01470     //          for (int j = 0; j < ad1.length; j++)
01471     //              cout << " " << ad1[j];
01472     //
01473 //    cout << endl << "u  = " << endl << gmatrix << endl;
01474 //    cout << endl << "v  = " << endl << gmatrix1 << endl;
01475     GMatrix gmatrix2(gmatrix.nCol, gmatrix1.nRow);
01476     gmatrix2.setIdentity();
01477     //          for (int k = 0; k < ad.length; k++)
01478     //              gmatrix2.values[k][k] = ad[k];
01479     //
01480     //          for (int l = 0; l < ad1.length; l++)
01481     //              gmatrix2.values[l][l + 1] = ad1[l];
01482     //
01483 //    cout << endl << "m  = " << endl << gmatrix2 << endl;
01484     gmatrix2.mulTransposeLeft(gmatrix, gmatrix2);
01485     gmatrix2.mulTransposeRight(gmatrix2, gmatrix1);
01486 //    cout << endl << "u.transpose*m*v.transpose  = " << endl << gmatrix2 << endl;
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         //          for (int j = 0; j < ad.length; j++)
01575         //              gmatrix2.values[j][j] = ad[j];
01576         //
01577         //          for (int k = 0; k < ad1.length; k++)
01578         //              gmatrix2.values[k][k + 1] = ad1[k];
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         //          for (int j = 0; j < ad.length; j++)
01609         //              gmatrix2.values[j][j] = ad[j];
01610         //
01611         //          for (int k = 0; k < ad1.length; k++)
01612         //              gmatrix2.values[k][k + 1] = ad1[k];
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 

Generated on Thu Sep 29 13:39:45 2005 for vecmath by  doxygen 1.4.4