00001 #ifndef __VECMATH_GMATRIX_HPP
00002 #define __VECMATH_GMATRIX_HPP
00003
00004 #ifndef __VECMATH_MATRIX3D_HPP
00005 #include <vecmath/Matrix3d.h>
00006 #endif
00007
00008 #ifndef __VECMATH_MATRIX3F_HPP
00009 #include <vecmath/Matrix3f.h>
00010 #endif
00011
00012 #ifndef __VECMATH_MATRIX4D_HPP
00013 #include <vecmath/Matrix4d.h>
00014 #endif
00015
00016 #ifndef __VECMATH_MATRIX4F_HPP
00017 #include <vecmath/Matrix4f.h>
00018 #endif
00019
00020 #ifndef __VECMATH_GVECTOR_HPP
00021 #include <vecmath/GVector.h>
00022 #endif
00023
00024 class DoubleArray2 {
00025 int cols;
00026 bool preset;
00027 double *arr;
00028 public:
00029 DoubleArray2() : preset(false), arr(0) {}
00030
00031 DoubleArray2(int i, int j) : preset(false), arr(0) {
00032 resize(i, j);
00033 }
00034
00035 ~DoubleArray2() {
00036 if (!preset && arr != 0) {
00037
00038 delete arr;
00039 }
00040 }
00041
00042 void resize(int i, int j) {
00043 if (arr != 0)
00044 delete arr;
00045 arr = new double[i * j];
00046
00047 cols = j;
00048 }
00049
00050
00051 void swap(DoubleArray2& d) {
00052 Math::swap(cols, d.cols);
00053 Math::swap(arr, d.arr);
00054 }
00055
00056 void setPreset(int c, double *data) {
00057 if (!preset && arr)
00058 delete arr;
00059 preset = true;
00060 cols = c;
00061 arr = data;
00062
00063 }
00064
00065 double* operator [] (int i) const {
00066 return &(arr[i * cols]);
00067 }
00068
00069 double& operator ()(int i, int j) const {
00070 return arr[i * cols + j];
00071 }
00072 };
00073
00074
00075 class GMatrix {
00076 public:
00077 static const double EPS;
00078 public:
00079 int nRow;
00080 int nCol;
00081 DoubleArray2 values;
00082
00083 GMatrix(int rows, int cols) {
00084 values.resize(rows, cols);
00085 nRow = rows;
00086 nCol = cols;
00087 setIdentity();
00088 }
00089
00090 GMatrix(int rows, int cols, const double ad[]);
00091
00092
00093 GMatrix(int rows, int cols, double *data, bool preset = false);
00094
00095 GMatrix(const GMatrix& gmatrix);
00096
00097 virtual ~GMatrix() {}
00098
00099 double & operator()(int i, int j) const {
00100 return values[i][j];
00101 }
00102
00103 double * operator[](int i) const {
00104 return values[i];
00105 }
00106
00107
00108 int LUD(GMatrix& LU, GVector& permutation);
00109 int SVD(GMatrix& U, GMatrix& W, GMatrix& V);
00110
00111 void add(const GMatrix & gmatrix);
00112 void add(const GMatrix & gmatrix, const GMatrix & gmatrix1);
00113 static int computeSVD(GMatrix& gmatrix, GMatrix& gmatrix1, GMatrix& gmatrix2,
00114 GMatrix& gmatrix3, bool flag);
00115 static int compute_2X2(double d, double d1, double d2, double ad[], double ad1[], double ad2[],
00116 double ad3[], double ad4[], int i);
00117 static void compute_qr(int i, int j, double ad[], double ad1[], GMatrix& gmatrix,
00118 GMatrix& gmatrix1, bool flag);
00119 static double compute_rot(double d, double d1, double ad[], double ad1[]);
00120 static double compute_shift(double d, double d1, double d2);
00121
00122 void copySubMatrix(int i, int j, int k, int l, int i1, int j1, GMatrix& gmatrix);
00123
00124 static double d_sign(double d, double d1) {
00125 double d2 = (d < 0.0) ? -d : d;
00126 return (d1 < 0.0) ? -d2 : d2;
00127 }
00128
00129 virtual bool epsilonEquals(const GMatrix & gmatrix, double d) const;
00130 virtual bool equals(const GMatrix & gmatrix) const;
00131 void get(GMatrix& gmatrix) const;
00132 void get(Matrix3d& matrix3d) const;
00133 void get(Matrix3f& matrix3f) const;
00134 void get(Matrix4d& matrix4d) const;
00135 void get(Matrix4f& matrix4f) const;
00136
00137 void getColumn(int col, GVector gvector) const {
00138 if (gvector.getSize() < nRow)
00139 gvector.setSize(nRow);
00140 for (int r = 0; r < nRow; r++)
00141 gvector.values[r] = values[r][col];
00142 }
00143
00144 void getColumn(int col, double ad[]) const {
00145 for (int r = 0; r < nRow; r++)
00146 ad[r] = values[r][col];
00147 }
00148
00149 double getElement(int row, int col) const {
00150 return values[row][col];
00151 }
00152
00153 int getNumCol() const {
00154 return nCol;
00155 }
00156
00157 int getNumRow() const {
00158 return nRow;
00159 }
00160
00161 void getRow(int row, GVector gvector) const {
00162 if (gvector.getSize() < nCol)
00163 gvector.setSize(nCol);
00164 for (int c = 0; c < nCol; c++)
00165 gvector.values[c] = values[row][c];
00166
00167 }
00168
00169 void getRow(int row, double ad[]) const {
00170 for (int c = 0; c < nCol; c++)
00171 ad[c] = values[row][c];
00172 }
00173
00174 virtual int hashCode() const {
00175 int i = 0;
00176
00177
00178
00179
00180
00181 return i;
00182 }
00183
00184 void identityMinus();
00185
00186 void invert() {
00187 invertGeneral(*this);
00188 }
00189
00190 void invert(GMatrix& gmatrix) {
00191 invertGeneral(gmatrix);
00192 }
00193
00194 static void luBacksubstitution(int i, double ad[], int ai[], double ad1[]);
00195 static bool luDecomposition(int i, double ad[], int ai[], int ai1[]);
00196 void mul(const GMatrix& gmatrix);
00197 void mul(const GMatrix& gmatrix, const GMatrix& gmatrix1);
00198 void mul(const GVector& gvector, const GVector& gvector1);
00199 void mulTransposeBoth(const GMatrix& gmatrix, const GMatrix& gmatrix1);
00200 void mulTransposeLeft(GMatrix gmatrix, GMatrix gmatrix1);
00201 void mulTransposeRight(const GMatrix& gmatrix, const GMatrix& gmatrix1);
00202 void negate();
00203 void negate(const GMatrix& gmatrix);
00204 void set(const GMatrix& gmatrix);
00205 void set(const Matrix3d& matrix3d);
00206 void set(const Matrix3f& matrix3f);
00207 void set(const Matrix4d& matrix4d);
00208 void set(const Matrix4f& matrix4f);
00209 void set(const double ad[]);
00210 void setColumn(int i, const GVector& gvector);
00211 void setColumn(int i, const double ad[]);
00212
00213 void setElement(int i, int j, double d) {
00214 values[i][j] = d;
00215 }
00216
00217 void setIdentity() {
00218 setScale(1.0);
00219 }
00220
00221 void setRow(int i, const GVector& gvector);
00222 void setRow(int i, const double ad[]);
00223 void setScale(double d);
00224 void setSize(int i, int j);
00225
00226 void setZero() {
00227 setZero(0, 0);
00228 }
00229
00230 void sub(const GMatrix& gmatrix);
00231 void sub(const GMatrix& gmatrix, const GMatrix& gmatrix1);
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 double trace() const;
00244 void transpose();
00245 void transpose(const GMatrix& gmatrix);
00246
00247
00248 private:
00249 void resize(int rows, int cols) {
00250 if (nRow != rows || nCol != cols) {
00251 nRow = rows;
00252 nCol = cols;
00253 values.resize(rows, cols);
00254 }
00255 }
00256
00257 void resizeSet(int rows, int cols) {
00258 if (nRow < rows || nCol < cols)
00259 resize(rows, cols);
00260 }
00261
00262 void setZero(int r, int c) {
00263 for (int i = r; i < nRow; i++)
00264 for (int j = c; j < nCol; j++)
00265 values[i][j] = 0.0;
00266 }
00267
00268 static void checkMatrix(GMatrix gmatrix);
00269 void invertGeneral(GMatrix& gmatrix);
00270 static void print_m(const GMatrix& gmatrix, const GMatrix& gmatrix1, const GMatrix& gmatrix2);
00271 static void print_se(double ad[], double ad1[]);
00272 static void print_svd(const double ad[], const double ad1[], const GMatrix& gmatrix, const GMatrix& gmatrix1);
00273 static void update_u(int i, GMatrix& gmatrix, double ad[], double ad1[]);
00274 static void update_u_split(int i, int j, GMatrix& gmatrix, double ad[], double ad1[],
00275 bool flag, GMatrix& gmatrix1, GMatrix& gmatrix2);
00276 static void update_v(int i, GMatrix& gmatrix, double ad[], double ad1[]);
00277 static void update_v_split(int i, int j, GMatrix& gmatrix, double ad[], double ad1[],
00278 bool flag, GMatrix& gmatrix1, GMatrix& gmatrix2);
00279 static void chase_across(double ad[], double ad1[], int i, GMatrix& gmatrix, bool flag);
00280 static void chase_up(double ad[], double ad1[], int i, GMatrix& gmatrix, bool flag);
00281 };
00282
00283 #endif