00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <base/Matrix3>
00026
00027 #include <base/Math>
00028 #include <base/Serializer>
00029
00030
00031 using base::Math;
00032 using base::Matrix3;
00033 using base::Vector3;
00034
00035 using std::ostream;
00036
00037
00038 inline static void exchange(Real& a, Real& b)
00039 {
00040 Real t(a);
00041 a = b;
00042 b = t;
00043 }
00044
00045
00046 inline static void rcswap3(Real m[], Int r, Int c)
00047 {
00048 Real* rcp = &m[MATRIX3_ACCESS(r,c)];
00049 Real* crp = &m[MATRIX3_ACCESS(c,r)];
00050 exchange(*rcp, *crp);
00051 }
00052
00053
00054 Matrix3& Matrix3::transpose()
00055 {
00056 rcswap3(m,1,2); rcswap3(m,1,3);
00057 rcswap3(m,2,3);
00058
00059 return *this;
00060 }
00061
00062
00063 Matrix3& Matrix3::invert()
00064 {
00065
00066 Matrix3 I;
00067 Matrix3 X, A(*this);
00068 Vector3 x;
00069
00070 Matrix3 L,U;
00071 Vector3 Pi;
00072
00073 A.decomposeLUP(L,U,Pi);
00074
00075 for(int c=1; c<=3; c++) {
00076 x = solveLUP(L,U,Pi,I.column(c));
00077 for(int r=1; r<=3; r++) X.e(r,c) = x[r];
00078 }
00079
00080 return (*this = X);
00081
00082 }
00083
00084
00085
00086 void Matrix3::setOrthonormalBasisOf(const Vector3& v)
00087 {
00088 Vector3 n(v); n.normalize();
00089 setRow(3, n);
00090
00091 Vector3 u;
00092 if (Math::abs(n.x) >= Math::abs(n.y)) {
00093
00094 Real invLength = 1.0 / Math::sqrt(Math::sqr(n.x) + Math::sqr(n.z));
00095 u = Vector3(-n.z * invLength, 0, n.x * invLength);
00096 }
00097 else {
00098
00099 Real invLength = 1.0/Math::sqrt(Math::sqr(n.y) + Math::sqr(n.z));
00100 u = Vector3(0, n.z * invLength, n.y * invLength);
00101 }
00102
00103 setRow(1, u);
00104 setRow(2, cross(n,u));
00105 }
00106
00107
00108 void Matrix3::decomposeLUP(Matrix3& L, Matrix3& U, Vector3& Pi) const
00109 {
00110 Real p,a;
00111 int kp,i,j,k;
00112 Matrix3 AA(*this);
00113
00114 for(i=1; i<=3; i++) Pi[i] = i;
00115 for(k=1; k<=3-1; k++) {
00116 p = Real(0); kp = 1;
00117 for(i=k; i<=3; i++) {
00118 a = Real(Math::abs(AA.e(i,k)));
00119 if ( a > p ) {
00120 p = a;
00121 kp = i;
00122 }
00123 }
00124 if (p == Real(0))
00125 throw std::invalid_argument(Exception("matrix is singular"));
00126
00127 exchange(Pi[k],Pi[kp]);
00128 for(i=1; i<=3;i++) exchange(AA.e(k,i),AA.e(kp,i));
00129
00130 for(i=k+1; i<=3;i++) {
00131 AA.e(i,k) /= AA.e(k,k);
00132 for(j=k+1; j<=3; j++)
00133 AA.e(i,j) -= AA.e(i,k)*AA.e(k,j);
00134 }
00135 }
00136
00137 for(i=1;i<=3;i++) {
00138 for(j=1;j<=3;j++)
00139 if (i>j) {
00140 L.e(i,j) = AA.e(i,j); U.e(i,j) = Real(0);
00141 }
00142 else {
00143 U.e(i,j) = AA.e(i,j); L.e(i,j) = Real(0);
00144 }
00145 L.e(i,i) = Real(1);
00146
00147 }
00148
00149 }
00150
00151
00152 Vector3 Matrix3::solve(const Vector3& b) const
00153 {
00154 Matrix3 L,U;
00155 Vector3 Pi;
00156
00157 decomposeLUP(L,U,Pi);
00158 return solveLUP(L,U,Pi,b);
00159 }
00160
00161
00162 Matrix3& Matrix3::negate() throw()
00163 {
00164 for(int i=0; i<9; i++)
00165 m[i]=-m[i];
00166 return *this;
00167 }
00168
00169
00170
00171
00172
00173 Matrix3& Matrix3::operator*=(const Matrix3& m2)
00174 {
00175 Matrix3 tmp;
00176
00177 for(int row=1; row<=3; row++)
00178 for(int col=1; col<=3; col++)
00179 tmp.e(row,col) = (e(row,1) * m2.e(1,col)) + (e(row,2) * m2.e(2,col))
00180 + (e(row,3) * m2.e(3,col));
00181
00182 return (*this = tmp);
00183 }
00184
00185
00186 Matrix3& Matrix3::operator+=(const Matrix3& m2)
00187 {
00188 for(int i=0; i<9; i++)
00189 m[i] += m2.m[i];
00190 return (*this);
00191 }
00192
00193
00194 Matrix3& Matrix3::operator-=(const Matrix3& m2)
00195 {
00196 for(int i=0; i<9; i++)
00197 m[i] -= m2.m[i];
00198 return (*this);
00199 }
00200
00201
00202 Matrix3& Matrix3::operator*=(const Real& s)
00203 {
00204 for(int i=0; i<9; i++)
00205 m[i] *= s;
00206 return *this;
00207 }
00208
00209
00210 Matrix3& Matrix3::operator/=(const Real& s)
00211 {
00212 for(int i=0; i<9; i++)
00213 m[i] /= s;
00214 return *this;
00215 }
00216
00217
00218
00219 Vector3 Matrix3::matrixMulVector(const Matrix3& m, const Vector3& v)
00220 { return Vector3(m.m[0]*v.x+m.m[3]*v.y+m.m[6]*v.z,
00221 m.m[1]*v.x+m.m[4]*v.y+m.m[7]*v.z,
00222 m.m[2]*v.x+m.m[5]*v.y+m.m[8]*v.z);
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 Vector3 Matrix3::matrixMulVectorAddVector(const Matrix3& m, const Vector3& v, const Vector3& v2)
00235 { return Vector3(m.m[0]*v.x+m.m[3]*v.y+m.m[6]*v.z+v2.x,
00236 m.m[1]*v.x+m.m[4]*v.y+m.m[7]*v.z+v2.y,
00237 m.m[2]*v.x+m.m[5]*v.y+m.m[8]*v.z+v2.z);
00238 }
00239
00240
00241
00242 Vector3 Matrix3::solveLUP(const Matrix3& L, const Matrix3& U, const Vector3& Pi, const Vector3& b)
00243 {
00244 int i,j;
00245 Vector3 y, x;
00246 Real s;
00247
00248 for(i=1;i<=3;i++) {
00249 s = Real(0);
00250 for(j=1;j<=i-1;j++) s += L.e(i,j)*y[j];
00251 y[i] = b[int(Pi[i])] - s;
00252 }
00253
00254 for(i=3;i>=1;i--) {
00255 s = Real(0);
00256 for(j=i+1;j<=3;j++) s += U.e(i,j)*x[j];
00257 x[i] = (y[i] - s)/(U.e(i,i));
00258 }
00259 return x;
00260 }
00261
00262
00263
00264
00265 inline void rotate(Matrix3& a, Real& g, Real& h, Real s, Real tau, Int i, Int j, Int k, Int l) {
00266 g=a.e(i,j); h=a.e(k,l);
00267 a.e(i,j) = g-s*(h+g*tau);
00268 a.e(k,l) = h+s*(g-h*tau);
00269 }
00270
00271
00272
00273
00274
00275
00276 Int Matrix3::eigenJacobi(Matrix3& vout, Vector3& dout, Int maxIter) const
00277 {
00278 Int i;
00279 Real tresh,theta,tau,t,sm,s,h,g,c;
00280 Vector3 b,z,d;
00281 Matrix3 v;
00282 Matrix3 a(*this);
00283
00284 b.x = a.e(1,1);
00285 b.y = a.e(2,2);
00286 b.z = a.e(3,3);
00287 d = b;
00288 z.setZero();
00289
00290 Int nrot = 0;
00291
00292 for(i=0; i<maxIter; i++) {
00293
00294 sm=0.0; sm+=Math::abs(a.e(1,2)); sm+=Math::abs(a.e(1,3)); sm+=Math::abs(a.e(2,3));
00295 if (sm == 0.0) {
00296 vout = v;
00297 dout = d;
00298 return i;
00299 }
00300
00301 if (i < 3) tresh=0.2*sm/(3.0*3.0); else tresh=0.0;
00302
00303
00304 {
00305 g = 100.0*Math::abs(a.e(1,2));
00306 if (i>3 && Math::abs(d.x)+g==Math::abs(d.x) && Math::abs(d.y)+g==Math::abs(d.y))
00307 a.e(1,2)=0.0;
00308 else if (Math::abs(a.e(1,2))>tresh)
00309 {
00310 h = d.y-d.x;
00311 if (Math::abs(h)+g == Math::abs(h))
00312 t=(a.e(1,2))/h;
00313 else {
00314 theta=0.5*h/(a.e(1,2));
00315 t=1.0/(Math::abs(theta)+Math::sqrt(1.0+theta*theta));
00316 if (theta < 0.0) t = -t;
00317 }
00318 c=1.0/Math::sqrt(1.0+t*t); s=t*c; tau=s/(1.0+c); h=t*a.e(1,2);
00319 z.x -= h; z.y += h; d.x -= h; d.y += h;
00320 a.e(1,2)=0.0;
00321 rotate(a,g,h,s,tau,1,3,2,3);
00322 rotate(v,g,h,s,tau,1,1,1,2);
00323 rotate(v,g,h,s,tau,2,1,2,2);
00324 rotate(v,g,h,s,tau,3,1,3,2);
00325 nrot++;
00326 }
00327 }
00328
00329 {
00330 g = 100.0*Math::abs(a.e(1,3));
00331 if (i>3 && Math::abs(d.x)+g==Math::abs(d.x) && Math::abs(d.z)+g==Math::abs(d.z))
00332 a.e(1,3)=0.0;
00333 else if (Math::abs(a.e(1,3))>tresh)
00334 {
00335 h = d.z-d.x;
00336 if (Math::abs(h)+g == Math::abs(h)) t=(a.e(1,3))/h;
00337 else
00338 {
00339 theta=0.5*h/(a.e(1,3));
00340 t=1.0/(Math::abs(theta)+Math::sqrt(1.0+theta*theta));
00341 if (theta < 0.0) t = -t;
00342 }
00343 c=1.0/Math::sqrt(1+t*t); s=t*c; tau=s/(1.0+c); h=t*a.e(1,3);
00344 z.x -= h; z.z += h; d.x -= h; d.z += h;
00345 a.e(1,3)=0.0;
00346 rotate(a,g,h,s,tau,1,2,2,3);
00347 rotate(v,g,h,s,tau,1,1,1,3);
00348 rotate(v,g,h,s,tau,2,1,2,3);
00349 rotate(v,g,h,s,tau,3,1,3,3);
00350 nrot++;
00351 }
00352 }
00353
00354
00355 {
00356 g = 100.0*Math::abs(a.e(2,3));
00357 if (i>3 && Math::abs(d.y)+g==Math::abs(d.y) && Math::abs(d.z)+g==Math::abs(d.z))
00358 a.e(2,3)=0.0;
00359 else if (Math::abs(a.e(2,3))>tresh)
00360 {
00361 h = d.z-d.y;
00362 if (Math::abs(h)+g == Math::abs(h)) t=(a.e(2,3))/h;
00363 else
00364 {
00365 theta=0.5*h/(a.e(2,3));
00366 t=1.0/(Math::abs(theta)+Math::sqrt(1.0+theta*theta));
00367 if (theta < 0.0) t = -t;
00368 }
00369 c=1.0/Math::sqrt(1+t*t); s=t*c; tau=s/(1.0+c); h=t*a.e(2,3);
00370 z.y -= h; z.z += h; d.y -= h; d.z += h;
00371 a.e(2,3)=0.0;
00372 rotate(a,g,h,s,tau,1,2,1,3);
00373 rotate(v,g,h,s,tau,1,2,1,3);
00374 rotate(v,g,h,s,tau,2,2,2,3);
00375 rotate(v,g,h,s,tau,3,2,3,3);
00376 nrot++;
00377 }
00378 }
00379
00380 b += z; d = b; z.setZero();
00381
00382 }
00383
00384 return i;
00385 }
00386
00387
00388 void Matrix3::serialize(Serializer& s)
00389 {
00390 for(Int i=0; i<9; i++)
00391 s(m[i]);
00392 }
00393
00394
00395
00396
00397 ostream& base::operator<<(ostream& out, const Matrix3& m)
00398 {
00399 return out << m.e(1,1) << " " << m.e(1,2) << " " << m.e(1,3) << std::endl
00400 << m.e(2,1) << " " << m.e(2,2) << " " << m.e(2,3) << std::endl
00401 << m.e(3,1) << " " << m.e(3,2) << " " << m.e(3,3) << std::endl;
00402 }
00403
00404
00405
00406
00407
00408
00409