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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #ifndef MATRIX_VCGLIB
00045 #define MATRIX_VCGLIB
00046
00047 #include <stdio.h>
00048 #include <math.h>
00049 #include <memory.h>
00050 #include <assert.h>
00051 #include <algorithm>
00052 #include <vcg/space/point.h>
00053
00054 namespace vcg{
00055 namespace ndim{
00056
00058
00059
00064 class MatrixDiagBase{public:
00065 virtual const int & Dimension()const =0;
00066 virtual float operator[](const int & i)const = 0;
00067 };
00068 template<int N, class S>
00069 class MatrixDiag: public Point<N,S>, public MatrixDiagBase{
00070 public:
00071 const int & Dimension() const {return N;}
00072 MatrixDiag(const Point<N,S>&p):Point<N,S>(p){}
00073 };
00074
00079 template<class TYPE>
00080 class Matrix
00081 {
00082
00083 public:
00084 typedef TYPE ScalarType;
00085
00092 Matrix(unsigned int m, unsigned int n)
00093 {
00094 _rows = m;
00095 _columns = n;
00096 _data = new ScalarType[m*n];
00097 memset(_data, 0, m*n*sizeof(ScalarType));
00098 };
00099
00107 Matrix(unsigned int m, unsigned int n, TYPE *values)
00108 {
00109 _rows = m;
00110 _columns = n;
00111 unsigned int dim = m*n;
00112 _data = new ScalarType[dim];
00113 memcpy(_data, values, dim*sizeof(ScalarType));
00114
00115
00116
00117 };
00118
00123 Matrix()
00124 {
00125 _rows = 0;
00126 _columns = 0;
00127 _data = NULL;
00128 };
00129
00135 Matrix(const Matrix<TYPE> &m)
00136 {
00137 _rows = m._rows;
00138 _columns = m._columns;
00139 _data = new ScalarType[_rows*_columns];
00140
00141 unsigned int dim = _rows * _columns;
00142 memcpy(_data, m._data, dim * sizeof(ScalarType));
00143
00144
00145
00146 };
00147
00151 ~Matrix()
00152 {
00153 delete []_data;
00154 };
00155
00159 inline unsigned int ColumnsNumber() const
00160 {
00161 return _columns;
00162 };
00163
00164
00168 inline unsigned int RowsNumber() const
00169 {
00170 return _rows;
00171 };
00172
00178 bool operator==(const Matrix<TYPE> &m) const
00179 {
00180 if (_rows==m._rows && _columns==m._columns)
00181 {
00182 bool result = true;
00183 for (unsigned int i=0; i<_rows*_columns && result; i++)
00184 result = (_data[i]==m._data[i]);
00185 return result;
00186 }
00187 return false;
00188 };
00189
00195 bool operator!=(const Matrix<TYPE> &m) const
00196 {
00197 if (_rows==m._rows && _columns==m._columns)
00198 {
00199 bool result = false;
00200 for (unsigned int i=0; i<_rows*_columns && !result; i++)
00201 result = (_data[i]!=m._data[i]);
00202 return result;
00203 }
00204 return true;
00205 };
00206
00213 inline TYPE ElementAt(unsigned int i, unsigned int j)
00214 {
00215 assert(i>=0 && i<_rows);
00216 assert(j>=0 && j<_columns);
00217 return _data[i*_columns+j];
00218 };
00219
00224 TYPE Determinant() const
00225 {
00226 assert(_rows == _columns);
00227 switch (_rows)
00228 {
00229 case 2:
00230 {
00231 return _data[0]*_data[3]-_data[1]*_data[2];
00232 break;
00233 };
00234 case 3:
00235 {
00236 return _data[0]*(_data[4]*_data[8]-_data[5]*_data[7]) -
00237 _data[1]*(_data[3]*_data[8]-_data[5]*_data[6]) +
00238 _data[2]*(_data[3]*_data[7]-_data[4]*_data[6]) ;
00239 break;
00240 };
00241 default:
00242 {
00243
00244 ScalarType det = 0;
00245 for (unsigned int j=0; j<_columns; j++)
00246 if (_data[j]!=0)
00247 det += _data[j]*this->Cofactor(0, j);
00248
00249 return det;
00250 }
00251 };
00252 };
00253
00258 TYPE Cofactor(unsigned int i, unsigned int j) const
00259 {
00260 assert(_rows == _columns);
00261 assert(_rows>2);
00262 TYPE *values = new TYPE[(_rows-1)*(_columns-1)];
00263 unsigned int u, v, p, q, s, t;
00264 for (u=0, p=0, s=0, t=0; u<_rows; u++, t+=_rows)
00265 {
00266 if (i==u)
00267 continue;
00268
00269 for (v=0, q=0; v<_columns; v++)
00270 {
00271 if (j==v)
00272 continue;
00273 values[s+q] = _data[t+v];
00274 q++;
00275 }
00276 p++;
00277 s+=(_rows-1);
00278 }
00279 Matrix<TYPE> temp(_rows-1, _columns-1, values);
00280 return (pow(TYPE(-1.0), TYPE(i+j))*temp.Determinant());
00281 };
00282
00288 inline TYPE* operator[](const unsigned int i)
00289 {
00290 assert(i<_rows);
00291 return _data + i*_columns;
00292 };
00293
00299 inline const TYPE* operator[](const unsigned int i) const
00300 {
00301 assert(i<_rows);
00302 return _data + i*_columns;
00303 };
00304
00310 TYPE* GetColumn(const unsigned int j)
00311 {
00312 assert(j>=0 && j<_columns);
00313 ScalarType *v = new ScalarType[_columns];
00314 unsigned int i, p;
00315 for (i=0, p=j; i<_rows; i++, p+=_columns)
00316 v[i] = _data[p];
00317 return v;
00318 };
00319
00325 TYPE* GetRow(const unsigned int i)
00326 {
00327 assert(i>=0 && i<_rows);
00328 ScalarType *v = new ScalarType[_rows];
00329 unsigned int j, p;
00330 for (j=0, p=i*_columns; j<_columns; j++, p++)
00331 v[j] = _data[p];
00332 return v;
00333 };
00334
00340 void SwapColumns(const unsigned int i, const unsigned int j)
00341 {
00342 assert(0<=i && i<_columns);
00343 assert(0<=j && j<_columns);
00344 if (i==j)
00345 return;
00346
00347 unsigned int r, e0, e1;
00348 for (r=0, e0=i, e1=j; r<_rows; r++, e0+=_columns, e1+=_columns)
00349 std::swap(_data[e0], _data[e1]);
00350 };
00351
00357 void SwapRows(const unsigned int i, const unsigned int j)
00358 {
00359 assert(0<=i && i<_rows);
00360 assert(0<=j && j<_rows);
00361 if (i==j)
00362 return;
00363
00364 unsigned int r, e0, e1;
00365 for (r=0, e0=i*_columns, e1=j*_columns; r<_columns; r++, e0++, e1++)
00366 std::swap(_data[e0], _data[e1]);
00367 };
00368
00373 Matrix<TYPE>& operator=(const Matrix<TYPE> &m)
00374 {
00375 if (this != &m)
00376 {
00377 assert(_rows == m._rows);
00378 assert(_columns == m._columns);
00379 for (unsigned int i=0; i<_rows*_columns; i++)
00380 _data[i] = m._data[i];
00381 }
00382 return *this;
00383 };
00384
00390 Matrix<TYPE>& operator+=(const Matrix<TYPE> &m)
00391 {
00392 assert(_rows == m._rows);
00393 assert(_columns == m._columns);
00394 for (unsigned int i=0; i<_rows*_columns; i++)
00395 _data[i] += m._data[i];
00396 return *this;
00397 };
00398
00404 Matrix<TYPE>& operator-=(const Matrix<TYPE> &m)
00405 {
00406 assert(_rows == m._rows);
00407 assert(_columns == m._columns);
00408 for (unsigned int i=0; i<_rows*_columns; i++)
00409 _data[i] -= m._data[i];
00410 return *this;
00411 };
00412
00418 Matrix<TYPE>& operator+=(const TYPE k)
00419 {
00420 for (unsigned int i=0; i<_rows*_columns; i++)
00421 _data[i] += k;
00422 return *this;
00423 };
00424
00430 Matrix<TYPE>& operator-=(const TYPE k)
00431 {
00432 for (unsigned int i=0; i<_rows*_columns; i++)
00433 _data[i] -= k;
00434 return *this;
00435 };
00436
00442 Matrix<TYPE>& operator*=(const TYPE k)
00443 {
00444 for (unsigned int i=0; i<_rows*_columns; i++)
00445 _data[i] *= k;
00446 return *this;
00447 };
00448
00454 Matrix<TYPE>& operator/=(const TYPE k)
00455 {
00456 assert(k!=0);
00457 for (unsigned int i=0; i<_rows*_columns; i++)
00458 _data[i] /= k;
00459 return *this;
00460 };
00461
00467 Matrix<TYPE> operator*(const Matrix<TYPE> &m) const
00468 {
00469 assert(_columns == m._rows);
00470 Matrix<TYPE> result(_rows, m._columns);
00471 unsigned int i, j, k, p, q, r;
00472 for (i=0, p=0, r=0; i<result._rows; i++, p+=_columns, r+=result._columns)
00473 for (j=0; j<result._columns; j++)
00474 {
00475 ScalarType temp = 0;
00476 for (k=0, q=0; k<_columns; k++, q+=m._columns)
00477 temp+=(_data[p+k]*m._data[q+j]);
00478 result._data[r+j] = temp;
00479 }
00480
00481 return result;
00482 };
00483
00489 ScalarType* operator*(const ScalarType v[]) const
00490 {
00491 ScalarType *result = new ScalarType[_rows];
00492 memset(result, 0, _rows*sizeof(ScalarType));
00493 unsigned int r, c, i;
00494 for (r=0, i=0; r<_rows; r++)
00495 for (c=0; c<_columns; c++, i++)
00496 result[r] += _data[i]*v[c];
00497
00498 return result;
00499 };
00500
00506 template <int N,int M>
00507 void DotProduct(Point<N,TYPE> &m,Point<M,TYPE> &result)
00508 {
00509 unsigned int i, j, p, r;
00510 for (i=0, p=0, r=0; i<M; i++)
00511 { result[i]=0;
00512 for (j=0; j<N; j++)
00513 result[i]+=(*this)[i][j]*m[j];
00514 }
00515 };
00516
00520 Matrix<TYPE> operator*(const MatrixDiagBase &m) const
00521 {
00522 assert(_columns == _rows);
00523 assert(_columns == m.Dimension());
00524 int i,j;
00525 Matrix<TYPE> result(_rows, _columns);
00526
00527 for (i=0; i<result._rows; i++)
00528 for (j=0; j<result._columns; j++)
00529 result[i][j]*= m[j];
00530
00531 return result;
00532 };
00536 template <int N, int M>
00537 void OuterProduct(const Point<N,TYPE> a, const Point< M,TYPE> b)
00538 {
00539 assert(N == _rows);
00540 assert(M == _columns);
00541 Matrix<TYPE> result(_rows,_columns);
00542 unsigned int i, j;
00543
00544 for (i=0; i<result._rows; i++)
00545 for (j=0; j<result._columns; j++)
00546 (*this)[i][j] = a[i] * b[j];
00547 };
00548
00549
00556 Point3<TYPE> operator*(Point3<TYPE> &p) const
00557 {
00558 assert(_columns==3 && _rows==3);
00559 vcg::Point3<TYPE> result;
00560 result[0] = _data[0]*p[0]+_data[1]*p[1]+_data[2]*p[2];
00561 result[1] = _data[3]*p[0]+_data[4]*p[1]+_data[5]*p[2];
00562 result[2] = _data[6]*p[0]+_data[7]*p[1]+_data[8]*p[2];
00563 return result;
00564 };
00565
00566
00572 Matrix<TYPE> operator+(const TYPE k)
00573 {
00574 Matrix<TYPE> result(_rows, _columns);
00575 for (unsigned int i=0; i<_rows*_columns; i++)
00576 result._data[i] = _data[i]+k;
00577 return result;
00578 };
00579
00585 Matrix<TYPE> operator-(const TYPE k)
00586 {
00587 Matrix<TYPE> result(_rows, _columns);
00588 for (unsigned int i=0; i<_rows*_columns; i++)
00589 result._data[i] = _data[i]-k;
00590 return result;
00591 };
00592
00597 Matrix<TYPE> operator-() const
00598 {
00599 Matrix<TYPE> result(_rows, _columns, _data);
00600 for (unsigned int i=0; i<_columns*_rows; i++)
00601 result._data[i] = -1*_data[i];
00602 return result;
00603 };
00604
00610 Matrix<TYPE> operator*(const TYPE k) const
00611 {
00612 Matrix<TYPE> result(_rows, _columns);
00613 for (unsigned int i=0; i<_rows*_columns; i++)
00614 result._data[i] = _data[i]*k;
00615 return result;
00616 };
00617
00623 Matrix<TYPE> operator/(const TYPE k)
00624 {
00625 Matrix<TYPE> result(_rows, _columns);
00626 for (unsigned int i=0; i<_rows*_columns; i++)
00627 result._data[i] = _data[i]/k;
00628 return result;
00629 };
00630
00631
00635 void SetZero()
00636 {
00637 for (unsigned int i=0; i<_rows*_columns; i++)
00638 _data[i] = ScalarType(0.0);
00639 };
00640
00644 void SetIdentity()
00645 {
00646 assert(_rows==_columns);
00647 for (unsigned int i=0; i<_rows; i++)
00648 for (unsigned int j=0; j<_columns; j++)
00649 _data[i] = (i==j) ? ScalarType(1.0) : ScalarType(0.0f);
00650 };
00651
00657 void SetColumn(const unsigned int j, TYPE* v)
00658 {
00659 assert(j>=0 && j<_columns);
00660 unsigned int i, p;
00661 for (i=0, p=j; i<_rows; i++, p+=_columns)
00662 _data[p] = v[i];
00663 };
00664
00670 void SetRow(const unsigned int i, TYPE* v)
00671 {
00672 assert(i>=0 && i<_rows);
00673 unsigned int j, p;
00674 for (j=0, p=i*_rows; j<_columns; j++, p++)
00675 _data[p] = v[j];
00676 };
00677
00682 void SetDiagonal(TYPE *v)
00683 {
00684 assert(_rows == _columns);
00685 for (unsigned int i=0, p=0; i<_rows; i++, p+=_rows)
00686 _data[p+i] = v[i];
00687 };
00688
00694 void Resize(const unsigned int m, const unsigned int n)
00695 {
00696 assert(m>=2);
00697 assert(n>=2);
00698 _rows = m;
00699 _columns = n;
00700 delete []_data;
00701 _data = new ScalarType[m*n];
00702 for (unsigned int i=0; i<m*n; i++)
00703 _data[i] = 0;
00704 };
00705
00706
00710 void Transpose()
00711 {
00712 ScalarType *temp = new ScalarType[_rows*_columns];
00713 unsigned int i, j, p, q;
00714 for (i=0, p=0; i<_rows; i++, p+=_columns)
00715 for (j=0, q=0; j<_columns; j++, q+=_rows)
00716 temp[q+i] = _data[p+j];
00717
00718 std::swap(_columns, _rows);
00719 std::swap(_data, temp);
00720 delete []temp;
00721 };
00722
00723
00724 Matrix transpose()
00725 {
00726 Matrix res = *this;
00727 res.Transpose();
00728 return res;
00729 }
00730 void transposeInPlace() { Transpose(); }
00731
00732
00736 void Dump()
00737 {
00738 unsigned int i, j, p;
00739 for (i=0, p=0; i<_rows; i++, p+=_columns)
00740 {
00741 printf("[\t");
00742 for (j=0; j<_columns; j++)
00743 printf("%f\t", _data[p+j]);
00744
00745 printf("]\n");
00746 }
00747 printf("\n");
00748 };
00749
00750 protected:
00752 unsigned int _rows;
00753
00755 unsigned int _columns;
00756
00758 ScalarType *_data;
00759 };
00760
00761 typedef vcg::ndim::Matrix<double> MatrixMNd;
00762 typedef vcg::ndim::Matrix<float> MatrixMNf;
00763
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783 }
00784 };
00785
00786 #endif