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
00026
00027 #ifndef SOFA_DEFAULTTYPE_MAT_H
00028 #define SOFA_DEFAULTTYPE_MAT_H
00029
00030 #include <sofa/defaulttype/Vec.h>
00031 #include <assert.h>
00032 #include <sofa/helper/static_assert.h>
00033
00034 namespace sofa
00035 {
00036
00037 namespace defaulttype
00038 {
00039
00040 template <int L, int C, class real=float>
00041 class Mat : public helper::fixed_array<VecNoInit<C,real>,L>
00042
00043 {
00044 public:
00045
00046 enum { N = L*C };
00047
00048 typedef real Real;
00049 typedef Vec<C,real> Line;
00050 typedef Vec<L,real> Col;
00051
00052 Mat()
00053 {
00054 clear();
00055 }
00056
00057 explicit Mat(NoInit)
00058 {
00059 }
00060
00061
00063
00064
00065
00066
00067
00068
00069
00071 Mat(Line r1, Line r2)
00072 {
00073 BOOST_STATIC_ASSERT(L == 2);
00074 this->elems[0]=r1;
00075 this->elems[1]=r2;
00076 }
00077
00079 Mat(Line r1, Line r2, Line r3)
00080 {
00081 BOOST_STATIC_ASSERT(L == 3);
00082 this->elems[0]=r1;
00083 this->elems[1]=r2;
00084 this->elems[2]=r3;
00085 }
00086
00088 Mat(Line r1, Line r2, Line r3, Line r4)
00089 {
00090 BOOST_STATIC_ASSERT(L == 4);
00091 this->elems[0]=r1;
00092 this->elems[1]=r2;
00093 this->elems[2]=r3;
00094 this->elems[3]=r4;
00095 }
00096
00098 explicit Mat(const real& v)
00099 {
00100 for( int i=0; i<L; i++ )
00101 for( int j=0; j<C; j++ )
00102 this->elems[i][j] = v;
00103 }
00104
00106 template<typename real2>
00107 Mat(const Mat<L,C,real2>& m)
00108 {
00109 std::copy(m.begin(), m.begin()+L, this->begin());
00110 }
00111
00113 template<typename real2>
00114 explicit Mat(const real2* p)
00115 {
00116 std::copy(p, p+N, this->begin()->begin());
00117 }
00118
00120 real getNbLines() const
00121 {
00122 return L;
00123 }
00124
00126 real getNbCols() const
00127 {
00128 return C;
00129 }
00130
00131
00133 void operator=(const real* p)
00134 {
00135 std::copy(p, p+N, this->begin()->begin());
00136 }
00137
00139 template<typename real2> void operator=(const Mat<L,C,real2>& m)
00140 {
00141 std::copy(m.begin(), m.begin()+L, this->begin());
00142 }
00143
00145 template<int L2, int C2> void operator=(const Mat<L2,C2,real>& m)
00146 {
00147 std::copy(m.begin(), m.begin()+(L>L2?L2:L), this->begin());
00148 }
00149
00150 template<int L2, int C2> void getsub(int L0, int C0, Mat<L2,C2,real>& m) const
00151 {
00152 for (int i=0;i<L2;i++)
00153 for (int j=0;j<C2;j++)
00154 m[i][j] = this->elems[i+L0][j+C0];
00155 }
00156
00157 template<int L2, int C2> void setsub(int L0, int C0, const Mat<L2,C2,real>& m)
00158 {
00159 for (int i=0;i<L2;i++)
00160 for (int j=0;j<C2;j++)
00161 this->elems[i+L0][j+C0] = m[i][j];
00162 }
00163
00165 void clear()
00166 {
00167 for (int i=0;i<L;i++)
00168 this->elems[i].clear();
00169 }
00170
00172 void fill(real r)
00173 {
00174 for (int i=0;i<L;i++)
00175 this->elems[i].fill(r);
00176 }
00177
00179 const Line& line(int i) const
00180 {
00181 return this->elems[i];
00182 }
00183
00185 Col col(int j) const
00186 {
00187 Col c;
00188 for (int i=0;i<L;i++)
00189 c[i]=this->elems[i][j];
00190 return c;
00191 }
00192
00194 Line& operator[](int i)
00195 {
00196 return this->elems[i];
00197 }
00198
00200 const Line& operator[](int i) const
00201 {
00202 return this->elems[i];
00203 }
00204
00206 Line& operator()(int i)
00207 {
00208 return this->elems[i];
00209 }
00210
00212 const Line& operator()(int i) const
00213 {
00214 return this->elems[i];
00215 }
00216
00218 real& operator()(int i, int j)
00219 {
00220 return this->elems[i][j];
00221 }
00222
00224 const real& operator()(int i, int j) const
00225 {
00226 return this->elems[i][j];
00227 }
00228
00230 const Line* lptr() const
00231 {
00232 return this->elems;
00233 }
00234
00236 Line* lptr()
00237 {
00238 return this->elems;
00239 }
00240
00242 const real* ptr() const
00243 {
00244 return this->elems[0].ptr();;
00245 }
00246
00248 real* ptr()
00249 {
00250 return this->elems[0].ptr();
00251 }
00252
00254 Line& x() { BOOST_STATIC_ASSERT(L >= 1); return this->elems[0]; }
00256 Line& y() { BOOST_STATIC_ASSERT(L >= 2); return this->elems[1]; }
00258 Line& z() { BOOST_STATIC_ASSERT(L >= 3); return this->elems[2]; }
00260 Line& w() { BOOST_STATIC_ASSERT(L >= 4); return this->elems[3]; }
00261
00263 const Line& x() const { BOOST_STATIC_ASSERT(L >= 1); return this->elems[0]; }
00265 const Line& y() const { BOOST_STATIC_ASSERT(L >= 2); return this->elems[1]; }
00267 const Line& z() const { BOOST_STATIC_ASSERT(L >= 3); return this->elems[2]; }
00269 const Line& w() const { BOOST_STATIC_ASSERT(L >= 4); return this->elems[3]; }
00270
00272 void identity()
00273 {
00274 BOOST_STATIC_ASSERT(L == C);
00275 clear();
00276 for (int i=0;i<L;i++)
00277 this->elems[i][i]=1;
00278 }
00279
00281 void transpose(const Mat<C,L,real> &m)
00282 {
00283 for (int i=0;i<L;i++)
00284 for (int j=0;j<C;j++)
00285 this->elems[i][j]=m[j][i];
00286 }
00287
00289 Mat<C,L,real> transposed() const
00290 {
00291 Mat<C,L,real> m(NOINIT);
00292 for (int i=0;i<L;i++)
00293 for (int j=0;j<C;j++)
00294 m[j][i]=this->elems[i][j];
00295 return m;
00296 }
00297
00299 void transpose()
00300 { BOOST_STATIC_ASSERT(L == C);
00301 for (int i=0;i<L;i++)
00302 for (int j=i+1;j<C;j++)
00303 {
00304 real t = this->elems[i][j];
00305 this->elems[i][j] = this->elems[j][i];
00306 this->elems[j][i] = t;
00307 }
00308 }
00309
00312
00313 bool operator==(const Mat<L,C,real>& b) const
00314 {
00315 for (int i=0;i<L;i++)
00316 if (!(this->elems[i]==b[i])) return false;
00317 return true;
00318 }
00319
00320 bool operator!=(const Mat<L,C,real>& b) const
00321 {
00322 for (int i=0;i<L;i++)
00323 if (this->elems[i]!=b[i]) return true;
00324 return false;
00325 }
00326
00327
00328 bool isSymetric() const
00329 {
00330 for (int i=0;i<L;i++)
00331 for (int j=i+1;j<C;j++)
00332 if( fabs( this->elems[i][j] - this->elems[j][i] ) > EQUALITY_THRESHOLD ) return false;
00333 return true;
00334 }
00335
00336
00338
00339
00340
00342 template <int P>
00343 Mat<L,P,real> operator*(const Mat<C,P,real>& m) const
00344 {
00345 Mat<L,P,real> r(NOINIT);
00346 for(int i=0;i<L;i++)
00347 for(int j=0;j<P;j++)
00348 {
00349 r[i][j]=(*this)[i][0] * m[0][j];
00350 for(int k=1;k<C;k++)
00351 r[i][j] += (*this)[i][k] * m[k][j];
00352 }
00353 return r;
00354 }
00355
00357 Mat<L,C,real> operator+(const Mat<L,C,real>& m) const
00358 {
00359 Mat<L,C,real> r(NOINIT);
00360 for(int i = 0; i < L; i++)
00361 r[i] = (*this)[i] + m[i];
00362 return r;
00363 }
00364
00366 Mat<L,C,real> operator-(const Mat<L,C,real>& m) const
00367 {
00368 Mat<L,C,real> r(NOINIT);
00369 for(int i = 0; i < L; i++)
00370 r[i] = (*this)[i] - m[i];
00371 return r;
00372 }
00373
00375 Col operator*(const Line& v) const
00376 {
00377 Col r(NOINIT);
00378 for(int i=0;i<L;i++)
00379 {
00380 r[i]=(*this)[i][0] * v[0];
00381 for(int j=1;j<C;j++)
00382 r[i] += (*this)[i][j] * v[j];
00383 }
00384 return r;
00385 }
00386
00388 Line multTranspose(const Col& v) const
00389 {
00390 Line r(NOINIT);
00391 for(int i=0;i<C;i++)
00392 {
00393 r[i]=(*this)[0][i] * v[0];
00394 for(int j=1;j<L;j++)
00395 r[i] += (*this)[j][i] * v[j];
00396 }
00397 return r;
00398 }
00399
00400
00402 template <int P>
00403 Mat<C,P,real> multTranspose(const Mat<L,P,real>& m) const
00404 {
00405 Mat<C,P,real> r(NOINIT);
00406 for(int i=0;i<C;i++)
00407 for(int j=0;j<P;j++)
00408 {
00409 r[i][j]=(*this)[0][i] * m[0][j];
00410 for(int k=1;k<L;k++)
00411 r[i][j] += (*this)[k][i] * m[k][j];
00412 }
00413 return r;
00414 }
00415
00416
00418 Mat<L,C,real> operator*(real f) const
00419 {
00420 Mat<L,C,real> r(NOINIT);
00421 for(int i=0;i<L;i++)
00422 for(int j=0;j<C;j++)
00423 r[i][j] = (*this)[i][j] * f;
00424 return r;
00425 }
00426
00428 Mat<L,C,real> operator/(real f) const
00429 {
00430 Mat<L,C,real> r(NOINIT);
00431 for(int i=0;i<L;i++)
00432 for(int j=0;j<C;j++)
00433 r[i][j] = (*this)[i][j] / f;
00434 return r;
00435 }
00436
00438 void operator *=(real r)
00439 {
00440 for(int i=0;i<L;i++)
00441 this->elems[i]*=r;
00442 }
00443
00445 void operator /=(real r)
00446 {
00447 for(int i=0;i<L;i++)
00448 this->elems[i]/=r;
00449 }
00450
00452 void operator +=(const Mat<L,C,real>& m)
00453 {
00454 for(int i=0;i<L;i++)
00455 this->elems[i]+=m[i];
00456 }
00457
00459 void addTransposed(const Mat<L,C,real>& m)
00460 {
00461 BOOST_STATIC_ASSERT(L==C);
00462 for(int i=0;i<L;i++)
00463 for(int j=0;j<L;j++)
00464 (*this)[i][j] += m[j][i];
00465 }
00466
00468 void subTransposed(const Mat<L,C,real>& m)
00469 {
00470 BOOST_STATIC_ASSERT(L==C);
00471 for(int i=0;i<L;i++)
00472 for(int j=0;j<L;j++)
00473 (*this)[i][j] += m[j][i];
00474 }
00475
00477 void operator -=(const Mat<L,C,real>& m)
00478 {
00479 for(int i=0;i<L;i++)
00480 this->elems[i]-=m[i];
00481 }
00482
00484 bool invert(const Mat<L,C,real>& m)
00485 {
00486 return invertMatrix(*this, m);
00487 }
00488
00489 };
00490
00492 template <int L, int C, typename real=float>
00493 class MatNoInit : public Mat<L,C,real>
00494 {
00495 public:
00496 MatNoInit()
00497 : Mat<L,C,real>(NOINIT)
00498 {
00499 }
00500
00502 void operator=(const real* p)
00503 {
00504 this->Mat<L,C,real>::operator=(p);
00505 }
00506
00508 template<int L2, int C2, typename real2> void operator=(const Mat<L2,C2,real2>& m)
00509 {
00510 this->Mat<L,C,real>::operator=(m);
00511 }
00512 };
00513
00515 template<class real>
00516 inline real determinant(const Mat<3,3,real>& m)
00517 {
00518 return m(0,0)*m(1,1)*m(2,2)
00519 + m(1,0)*m(2,1)*m(0,2)
00520 + m(2,0)*m(0,1)*m(1,2)
00521 - m(0,0)*m(2,1)*m(1,2)
00522 - m(1,0)*m(0,1)*m(2,2)
00523 - m(2,0)*m(1,1)*m(0,2);
00524 }
00525
00527 template<class real>
00528 inline real determinant(const Mat<2,2,real>& m)
00529 {
00530 return m(0,0)*m(1,1)
00531 - m(1,0)*m(0,1);
00532 }
00533
00535 template<int S, class real>
00536 bool invertMatrix(Mat<S,S,real>& dest, const Mat<S,S,real>& from)
00537 {
00538 int i, j, k;
00539 Vec<S,int> r, c, row, col;
00540
00541 Mat<S,S,real> m1 = from;
00542 Mat<S,S,real> m2;
00543 m2.identity();
00544
00545 for ( k = 0; k < S; k++ )
00546 {
00547
00548 real pivot = 0;
00549 for (i = 0; i < S; i++)
00550 {
00551 if (row[i])
00552 continue;
00553 for (j = 0; j < S; j++)
00554 {
00555 if (col[j])
00556 continue;
00557 real t = m1[i][j]; if (t<0) t=-t;
00558 if ( t > pivot)
00559 {
00560 pivot = t;
00561 r[k] = i;
00562 c[k] = j;
00563 }
00564 }
00565 }
00566
00567 if (pivot <= 1e-10)
00568 {
00569 return false;
00570 }
00571
00572 row[r[k]] = col[c[k]] = 1;
00573 pivot = m1[r[k]][c[k]];
00574
00575
00576 m1[r[k]] /= pivot; m1[r[k]][c[k]] = 1;
00577 m2[r[k]] /= pivot;
00578
00579
00580 for (i = 0; i < S; i++)
00581 {
00582 if (i != r[k])
00583 {
00584 real f = m1[i][c[k]];
00585 m1[i] -= m1[r[k]]*f; m1[i][c[k]] = 0;
00586 m2[i] -= m2[r[k]]*f;
00587 }
00588 }
00589 }
00590
00591 for (i = 0; i < S; i++)
00592 for (j = 0; j < S; j++)
00593 if (c[j] == i)
00594 row[i] = r[j];
00595
00596 for ( i = 0; i < S; i++ )
00597 dest[i] = m2[row[i]];
00598
00599 return true;
00600 }
00601
00603 template<class real>
00604 bool invertMatrix(Mat<3,3,real>& dest, const Mat<3,3,real>& from)
00605 {
00606 real det=determinant(from);
00607
00608 if ( -1e-10<=det && det<=1e-10)
00609 return false;
00610
00611 dest(0,0)= (from(1,1)*from(2,2) - from(2,1)*from(1,2))/det;
00612 dest(1,0)= (from(1,2)*from(2,0) - from(2,2)*from(1,0))/det;
00613 dest(2,0)= (from(1,0)*from(2,1) - from(2,0)*from(1,1))/det;
00614 dest(0,1)= (from(2,1)*from(0,2) - from(0,1)*from(2,2))/det;
00615 dest(1,1)= (from(2,2)*from(0,0) - from(0,2)*from(2,0))/det;
00616 dest(2,1)= (from(2,0)*from(0,1) - from(0,0)*from(2,1))/det;
00617 dest(0,2)= (from(0,1)*from(1,2) - from(1,1)*from(0,2))/det;
00618 dest(1,2)= (from(0,2)*from(1,0) - from(1,2)*from(0,0))/det;
00619 dest(2,2)= (from(0,0)*from(1,1) - from(1,0)*from(0,1))/det;
00620
00621 return true;
00622 }
00623
00625 template<class real>
00626 bool invertMatrix(Mat<2,2,real>& dest, const Mat<2,2,real>& from)
00627 {
00628 real det=determinant(from);
00629
00630 if ( -1e-10<=det && det<=1e-10)
00631 return false;
00632
00633 dest(0,0)= from(1,1)/det;
00634 dest(0,1)= -from(0,1)/det;
00635 dest(1,0)= -from(1,0)/det;
00636 dest(1,1)= from(0,0)/det;
00637
00638 return true;
00639 }
00640
00641 typedef Mat<2,2,float> Mat2x2f;
00642 typedef Mat<2,2,double> Mat2x2d;
00643
00644 typedef Mat<3,3,float> Mat3x3f;
00645 typedef Mat<3,3,double> Mat3x3d;
00646
00647 typedef Mat<3,4,float> Mat3x4f;
00648 typedef Mat<3,4,double> Mat3x4d;
00649
00650 typedef Mat<4,4,float> Mat4x4f;
00651 typedef Mat<4,4,double> Mat4x4d;
00652
00653 #ifdef SOFA_FLOAT
00654 typedef Mat2x2f Matrix2;
00655 typedef Mat3x3f Matrix3;
00656 typedef Mat4x4f Matrix4;
00657 #else
00658 typedef Mat2x2d Matrix2;
00659 typedef Mat3x3d Matrix3;
00660 typedef Mat4x4d Matrix4;
00661 #endif
00662
00663
00664 template <int L, int C, typename real>
00665 std::ostream& operator<<(std::ostream& o, const Mat<L,C,real>& m)
00666 {
00667 o << '[' << m[0];
00668 for (int i=1; i<L; i++)
00669 o << ',' << m[i];
00670 o << ']';
00671 return o;
00672 }
00673
00674 template <int L, int C, typename real>
00675 std::istream& operator>>(std::istream& in, sofa::defaulttype::Mat<L,C,real>& m)
00676 {
00677 int c;
00678 c = in.peek();
00679 while (c==' ' || c=='\n' || c=='[')
00680 {
00681 in.get();
00682 c = in.peek();
00683 }
00684 in >> m[0];
00685 for (int i=1; i<L; i++)
00686 {
00687 c = in.peek();
00688 while (c==' ' || c==',')
00689 {
00690 in.get();
00691 c = in.peek();
00692 }
00693 in >> m[i];
00694 }
00695 c = in.peek();
00696 while (c==' ' || c=='\n' || c==']')
00697 {
00698 in.get();
00699 c = in.peek();
00700 }
00701 return in;
00702 }
00703
00704
00706 template<class T1,class T2>
00707 inline const T1 S_MAX(const T1 &a, const T2 &b)
00708 {
00709 return b > a ? (b) : (a);
00710 }
00711
00713 template<class T1,class T2>
00714 inline const T1 S_MIN(const T1 &a, const T2 &b)
00715 {
00716 return b < a ? (b) : (a);
00717 }
00718
00719 template<class T1,class T2>
00720 inline const T1 S_SIGN(const T1 &a, const T2 &b)
00721 {
00722 return b >= 0 ? (a >= 0 ? a : -a) : (a >= 0 ? -a : a);
00723 }
00724
00725 template<class T>
00726 inline const T S_SQR(const T a)
00727 {
00728 return a*a;
00729 }
00730
00732 template <class T1, class T2>
00733 T1 pythag(const T1 a, const T2 b)
00734 {
00735 T1 absa,absb;
00736 absa=fabs(a);
00737 absb=fabs(b);
00738 if (absa > absb) return absa*sqrt(1.0+SQR(absb/absa));
00739 else return (absb == 0.0 ? 0.0 : absb*sqrt(1.0+SQR(absa/absb)));
00740 }
00742
00747 template< int m, int n, typename Real>
00748 void svddcmp(Mat<m,n,Real> &a, Vec<n,Real> &w, Mat<n,m,Real> &v)
00749 {
00750 bool flag;
00751 int i,its,j,jj,k,l,nm;
00752 Real anorm,c,f,g,h,s,scale,x,y,z;
00753
00754 Vec<n,Real> rv1;
00755 g=scale=anorm=0.0;
00756 for (i=0;i<n;i++) {
00757 l=i+2;
00758 rv1[i]=scale*g;
00759 g=s=scale=0.0;
00760 if (i < m) {
00761 for (k=i;k<m;k++) scale += fabs(a[k][i]);
00762 if (scale != 0.0) {
00763 for (k=i;k<m;k++) {
00764 a[k][i] /= scale;
00765 s += a[k][i]*a[k][i];
00766 }
00767 f=a[i][i];
00768 g = -S_SIGN(sqrt(s),f);
00769 h=f*g-s;
00770 a[i][i]=f-g;
00771 for (j=l-1;j<n;j++) {
00772 for (s=0.0,k=i;k<m;k++) s += a[k][i]*a[k][j];
00773 f=s/h;
00774 for (k=i;k<m;k++) a[k][j] += f*a[k][i];
00775 }
00776 for (k=i;k<m;k++) a[k][i] *= scale;
00777 }
00778 }
00779 w[i]=scale *g;
00780 g=s=scale=0.0;
00781 if (i+1 <= m && i != n) {
00782 for (k=l-1;k<n;k++) scale += fabs(a[i][k]);
00783 if (scale != 0.0) {
00784 for (k=l-1;k<n;k++) {
00785 a[i][k] /= scale;
00786 s += a[i][k]*a[i][k];
00787 }
00788 f=a[i][l-1];
00789 g = -S_SIGN(sqrt(s),f);
00790 h=f*g-s;
00791 a[i][l-1]=f-g;
00792 for (k=l-1;k<n;k++) rv1[k]=a[i][k]/h;
00793 for (j=l-1;j<m;j++) {
00794 for (s=0.0,k=l-1;k<n;k++) s += a[j][k]*a[i][k];
00795 for (k=l-1;k<n;k++) a[j][k] += s*rv1[k];
00796 }
00797 for (k=l-1;k<n;k++) a[i][k] *= scale;
00798 }
00799 }
00800 anorm=S_MAX(anorm,(fabs(w[i])+fabs(rv1[i])));
00801 }
00802 for (i=n-1;i>=0;i--) {
00803 if (i < n-1) {
00804 if (g != 0.0) {
00805 for (j=l;j<n;j++)
00806 v[j][i]=(a[i][j]/a[i][l])/g;
00807 for (j=l;j<n;j++) {
00808 for (s=0.0,k=l;k<n;k++) s += a[i][k]*v[k][j];
00809 for (k=l;k<n;k++) v[k][j] += s*v[k][i];
00810 }
00811 }
00812 for (j=l;j<n;j++) v[i][j]=v[j][i]=0.0;
00813 }
00814 v[i][i]=1.0;
00815 g=rv1[i];
00816 l=i;
00817 }
00818 for (i=S_MIN(m,n)-1;i>=0;i--) {
00819 l=i+1;
00820 g=w[i];
00821 for (j=l;j<n;j++) a[i][j]=0.0;
00822 if (g != 0.0) {
00823 g=1.0/g;
00824 for (j=l;j<n;j++) {
00825 for (s=0.0,k=l;k<m;k++) s += a[k][i]*a[k][j];
00826 f=(s/a[i][i])*g;
00827 for (k=i;k<m;k++) a[k][j] += f*a[k][i];
00828 }
00829 for (j=i;j<m;j++) a[j][i] *= g;
00830 } else for (j=i;j<m;j++) a[j][i]=0.0;
00831 ++a[i][i];
00832 }
00833 for (k=n-1;k>=0;k--) {
00834 for (its=0;its<30;its++) {
00835 flag=true;
00836 for (l=k;l>=0;l--) {
00837 nm=l-1;
00838 if (fabs(rv1[l])+anorm == anorm) {
00839 flag=false;
00840 break;
00841 }
00842 if (fabs(w[nm])+anorm == anorm) break;
00843 }
00844 if (flag) {
00845 c=0.0;
00846 s=1.0;
00847 for (i=l-1;i<k+1;i++) {
00848 f=s*rv1[i];
00849 rv1[i]=c*rv1[i];
00850 if (fabs(f)+anorm == anorm) break;
00851 g=w[i];
00852 h=pythag(f,g);
00853 w[i]=h;
00854 h=1.0/h;
00855 c=g*h;
00856 s = -f*h;
00857 for (j=0;j<m;j++) {
00858 y=a[j][nm];
00859 z=a[j][i];
00860 a[j][nm]=y*c+z*s;
00861 a[j][i]=z*c-y*s;
00862 }
00863 }
00864 }
00865 z=w[k];
00866 if (l == k) {
00867 if (z < 0.0) {
00868 w[k] = -z;
00869 for (j=0;j<n;j++) v[j][k] = -v[j][k];
00870 }
00871 break;
00872 }
00873 if (its == 29)
00874 {
00875
00876 return;
00877 }
00878 x=w[l];
00879 nm=k-1;
00880 y=w[nm];
00881 g=rv1[nm];
00882 h=rv1[k];
00883 f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y);
00884 g=pythag(f,1.0);
00885 f=((x-z)*(x+z)+h*((y/(f+S_SIGN(g,f)))-h))/x;
00886 c=s=1.0;
00887 for (j=l;j<=nm;j++) {
00888 i=j+1;
00889 g=rv1[i];
00890 y=w[i];
00891 h=s*g;
00892 g=c*g;
00893 z=pythag(f,h);
00894 rv1[j]=z;
00895 c=f/z;
00896 s=h/z;
00897 f=x*c+g*s;
00898 g=g*c-x*s;
00899 h=y*s;
00900 y *= c;
00901 for (jj=0;jj<n;jj++) {
00902 x=v[jj][j];
00903 z=v[jj][i];
00904 v[jj][j]=x*c+z*s;
00905 v[jj][i]=z*c-x*s;
00906 }
00907 z=pythag(f,h);
00908 w[j]=z;
00909 if (z) {
00910 z=1.0/z;
00911 c=f*z;
00912 s=h*z;
00913 }
00914 f=c*g+s*y;
00915 x=c*y-s*g;
00916 for (jj=0;jj<m;jj++) {
00917 y=a[jj][j];
00918 z=a[jj][i];
00919 a[jj][j]=y*c+z*s;
00920 a[jj][i]=z*c-y*s;
00921 }
00922 }
00923 rv1[l]=0.0;
00924 rv1[k]=f;
00925 w[k]=x;
00926 }
00927 }
00928 }
00929
00930
00931
00933 template< int m, int n, typename Real>
00934 Real cond(Mat<m,n,Real> &a)
00935 {
00936 Vec<n,Real>w;
00937 Mat<n,m,Real> *v = new Mat<n,m,Real>();
00938
00939 svddcmp( a, w, *v );
00940
00941 delete v;
00942
00943 return fabs(w[0]/w[n-1]);
00944 }
00945
00946
00948 template< int n, typename Real>
00949 void ludcmp(Mat<n,n,Real> &a, Vec<n,int> &indx)
00950 {
00951 const Real TINY=(Real)1.0e-20;
00952 int i,imax=0,j,k;
00953 Real big,dum,sum,temp;
00954
00955 Vec<n,Real> vv;
00956 for (i=0;i<n;i++) {
00957 big=0.0;
00958 for (j=0;j<n;j++)
00959 if ((temp=fabs(a[i][j])) > big) big=temp;
00960 assert (big != 0.0);
00961 vv[i]=(Real)1.0/big;
00962 }
00963 for (j=0;j<n;j++) {
00964 for (i=0;i<j;i++) {
00965 sum=a[i][j];
00966 for (k=0;k<i;k++) sum -= a[i][k]*a[k][j];
00967 a[i][j]=sum;
00968 }
00969 big=0.0;
00970 for (i=j;i<n;i++) {
00971 sum=a[i][j];
00972 for (k=0;k<j;k++) sum -= a[i][k]*a[k][j];
00973 a[i][j]=sum;
00974 if ((dum=vv[i]*fabs(sum)) >= big) {
00975 big=dum;
00976 imax=i;
00977 }
00978 }
00979 if (j != imax) {
00980 for (k=0;k<n;k++) {
00981 dum=a[imax][k];
00982 a[imax][k]=a[j][k];
00983 a[j][k]=dum;
00984 }
00985 vv[imax]=vv[j];
00986 }
00987 indx[j]=imax;
00988 if (a[j][j] == 0.0) a[j][j]=TINY;
00989 if (j != n-1) {
00990 dum=(Real)1.0/(a[j][j]);
00991 for (i=j+1;i<n;i++) a[i][j] *= dum;
00992 }
00993 }
00994 }
00995
00997 template< int n, typename Real>
00998 void lubksb(const Mat<n,n,Real> &a, const Vec<n,int> &indx, Vec<n,Real> &b)
00999 {
01000 int i,ii=0,ip,j;
01001 Real sum;
01002
01003 for (i=0;i<n;i++) {
01004 ip=indx[i];
01005 sum=b[ip];
01006 b[ip]=b[i];
01007 if (ii != 0)
01008 for (j=ii-1;j<i;j++) sum -= a[i][j]*b[j];
01009 else if (sum != 0.0)
01010 ii=i+1;
01011 b[i]=sum;
01012 }
01013 for (i=n-1;i>=0;i--) {
01014 sum=b[i];
01015 for (j=i+1;j<n;j++) sum -= a[i][j]*b[j];
01016 b[i]=sum/a[i][i];
01017 }
01018 }
01019
01023 template< int n, typename Real>
01024 void luinv( Mat<n,n,Real> &inv, Mat<n,n,Real> &m )
01025 {
01026 Vec<n,int> idx;
01027 Vec<n,Real> col;
01028
01029 ludcmp(m,idx);
01030
01031 for( int i=0; i<n; i++ ){
01032 for( int j=0; j<n; j++ )
01033 col[j] = 0;
01034 col[i] = 1;
01035 lubksb(m,idx,col);
01036 for( int j=0; j<n; j++ )
01037 inv[j][i] = col[j];
01038 }
01039 }
01040
01042 template <int L, int C, typename T>
01043 inline Mat<L,C,T> dyad( const Vec<L,T>& u, const Vec<C,T>& v )
01044 {
01045 Mat<L,C,T> res(NOINIT);
01046 for( int i=0; i<L; i++ )
01047 for( int j=0; j<C; j++ )
01048 res[i][j] = u[i]*v[j];
01049 return res;
01050 }
01051
01052 }
01053
01054 }
01055
01056
01057
01058
01059
01061 template <int L, int C, typename real>
01062 sofa::defaulttype::Mat<L,C,real> operator*(real r, const sofa::defaulttype::Mat<L,C,real>& m)
01063 {
01064 return m*r;
01065 }
01066
01067 #endif