26 #define SWAP(a,b) {temp=a;a=b;b=temp;}
27 #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
29 #define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg)
30 static FLOAT maxarg1,maxarg2;
31 #define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ? (maxarg1) : (maxarg2))
32 static int32_t iminarg1,iminarg2;
33 #define IMIN(a,b) (iminarg1=(a),iminarg2=(b),(iminarg1) < (iminarg2) ? (iminarg1) : (iminarg2))
44 Matrix::Matrix (
const int32_t m_,
const int32_t n_) {
45 allocateMemory(m_,n_);
48 Matrix::Matrix (
const int32_t m_,
const int32_t n_,
const FLOAT* val_) {
49 allocateMemory(m_,n_);
51 for (int32_t i=0; i<m_; i++)
52 for (int32_t j=0; j<n_; j++)
53 val[i][j] = val_[k++];
56 Matrix::Matrix (
const Matrix &M) {
57 allocateMemory(M.m,M.n);
58 for (int32_t i=0; i<M.m; i++)
59 memcpy(val[i],M.val[i],M.n*
sizeof(FLOAT));
66 Matrix& Matrix::operator= (
const Matrix &M) {
68 if (M.m!=m || M.n!=n) {
70 allocateMemory(M.m,M.n);
73 for (int32_t i=0; i<M.m; i++)
74 memcpy(val[i],M.val[i],M.n*
sizeof(FLOAT));
79 void Matrix::getData(FLOAT* val_,int32_t i1,int32_t j1,int32_t i2,int32_t j2) {
83 for (int32_t i=i1; i<=i2; i++)
84 for (int32_t j=j1; j<=j2; j++)
85 val_[k++] = val[i][j];
88 Matrix Matrix::getMat(int32_t i1,int32_t j1,int32_t i2,int32_t j2) {
91 if (i1<0 || i2>=m || j1<0 || j2>=n || i2<i1 || j2<j1) {
92 cerr <<
"ERROR: Cannot get submatrix [" << i1 <<
".." << i2 <<
93 "] x [" << j1 <<
".." << j2 <<
"]" <<
94 " of a (" << m <<
"x" << n <<
") matrix." << endl;
97 Matrix M(i2-i1+1,j2-j1+1);
98 for (int32_t i=0; i<M.m; i++)
99 for (int32_t j=0; j<M.n; j++)
100 M.val[i][j] = val[i1+i][j1+j];
104 void Matrix::setMat(
const Matrix &M,
const int32_t i1,
const int32_t j1) {
105 if (i1<0 || j1<0 || i1+M.m>m || j1+M.n>n) {
106 cerr <<
"ERROR: Cannot set submatrix [" << i1 <<
".." << i1+M.m-1 <<
107 "] x [" << j1 <<
".." << j1+M.n-1 <<
"]" <<
108 " of a (" << m <<
"x" << n <<
") matrix." << endl;
111 for (int32_t i=0; i<M.m; i++)
112 for (int32_t j=0; j<M.n; j++)
113 val[i1+i][j1+j] = M.val[i][j];
116 void Matrix::setVal(FLOAT s,int32_t i1,int32_t j1,int32_t i2,int32_t j2) {
117 if (i2==-1) i2 = m-1;
118 if (j2==-1) j2 = n-1;
119 if (i2<i1 || j2<j1) {
120 cerr <<
"ERROR in setVal: Indices must be ordered (i1<=i2, j1<=j2)." << endl;
123 for (int32_t i=i1; i<=i2; i++)
124 for (int32_t j=j1; j<=j2; j++)
128 void Matrix::setDiag(FLOAT s,int32_t i1,int32_t i2) {
129 if (i2==-1) i2 = min(m-1,n-1);
130 for (int32_t i=i1; i<=i2; i++)
134 void Matrix::zero() {
138 Matrix Matrix::extractCols (vector<int> idx) {
139 Matrix M(m,idx.size());
140 for (int32_t j=0; j<M.n; j++)
142 for (int32_t i=0; i<m; i++)
143 M.val[i][j] = val[i][idx[j]];
147 Matrix Matrix::eye (
const int32_t m) {
149 for (int32_t i=0; i<m; i++)
154 void Matrix::eye () {
155 for (int32_t i=0; i<m; i++)
156 for (int32_t j=0; j<n; j++)
158 for (int32_t i=0; i<min(m,n); i++)
162 Matrix Matrix::diag (
const Matrix &M) {
163 if (M.m>1 && M.n==1) {
165 for (int32_t i=0; i<M.m; i++)
166 D.val[i][i] = M.val[i][0];
168 }
else if (M.m==1 && M.n>1) {
170 for (int32_t i=0; i<M.n; i++)
171 D.val[i][i] = M.val[0][i];
174 cout <<
"ERROR: Trying to create diagonal matrix from vector of size (" << M.m <<
"x" << M.n <<
")" << endl;
178 Matrix Matrix::reshape(
const Matrix &M,int32_t m_,int32_t n_) {
179 if (M.m*M.n != m_*n_) {
180 cerr <<
"ERROR: Trying to reshape a matrix of size (" << M.m <<
"x" << M.n <<
181 ") to size (" << m_ <<
"x" << n_ <<
")" << endl;
185 for (int32_t k=0; k<m_*n_; k++) {
190 M2.val[i2][j2] = M.val[i1][j1];
195 Matrix Matrix::rotMatX (
const FLOAT &angle) {
196 FLOAT s = sin(angle);
197 FLOAT c = cos(angle);
207 Matrix Matrix::rotMatY (
const FLOAT &angle) {
208 FLOAT s = sin(angle);
209 FLOAT c = cos(angle);
219 Matrix Matrix::rotMatZ (
const FLOAT &angle) {
220 FLOAT s = sin(angle);
221 FLOAT c = cos(angle);
231 Matrix Matrix::operator+ (
const Matrix &M) {
232 const Matrix &A = *
this;
234 if (A.m!=B.m || A.n!=B.n) {
235 cerr <<
"ERROR: Trying to add matrices of size (" << A.m <<
"x" << A.n <<
236 ") and (" << B.m <<
"x" << B.n <<
")" << endl;
240 for (int32_t i=0; i<m; i++)
241 for (int32_t j=0; j<n; j++)
242 C.val[i][j] = A.val[i][j]+B.val[i][j];
246 Matrix Matrix::operator- (
const Matrix &M) {
247 const Matrix &A = *
this;
249 if (A.m!=B.m || A.n!=B.n) {
250 cerr <<
"ERROR: Trying to subtract matrices of size (" << A.m <<
"x" << A.n <<
251 ") and (" << B.m <<
"x" << B.n <<
")" << endl;
255 for (int32_t i=0; i<m; i++)
256 for (int32_t j=0; j<n; j++)
257 C.val[i][j] = A.val[i][j]-B.val[i][j];
261 Matrix Matrix::operator* (
const Matrix &M) {
262 const Matrix &A = *
this;
265 cerr <<
"ERROR: Trying to multiply matrices of size (" << A.m <<
"x" << A.n <<
266 ") and (" << B.m <<
"x" << B.n <<
")" << endl;
270 for (int32_t i=0; i<A.m; i++)
271 for (int32_t j=0; j<B.n; j++)
272 for (int32_t k=0; k<A.n; k++)
273 C.val[i][j] += A.val[i][k]*B.val[k][j];
277 Matrix Matrix::operator* (
const FLOAT &s) {
279 for (int32_t i=0; i<m; i++)
280 for (int32_t j=0; j<n; j++)
281 C.val[i][j] = val[i][j]*s;
285 Matrix Matrix::operator/ (
const Matrix &M) {
286 const Matrix &A = *
this;
289 if (A.m==B.m && A.n==B.n) {
291 for (int32_t i=0; i<A.m; i++)
292 for (int32_t j=0; j<A.n; j++)
294 C.val[i][j] = A.val[i][j]/B.val[i][j];
297 }
else if (A.m==B.m && B.n==1) {
299 for (int32_t i=0; i<A.m; i++)
300 for (int32_t j=0; j<A.n; j++)
302 C.val[i][j] = A.val[i][j]/B.val[i][0];
305 }
else if (A.n==B.n && B.m==1) {
307 for (int32_t i=0; i<A.m; i++)
308 for (int32_t j=0; j<A.n; j++)
310 C.val[i][j] = A.val[i][j]/B.val[0][j];
314 cerr <<
"ERROR: Trying to divide matrices of size (" << A.m <<
"x" << A.n <<
315 ") and (" << B.m <<
"x" << B.n <<
")" << endl;
320 Matrix Matrix::operator/ (
const FLOAT &s) {
322 cerr <<
"ERROR: Trying to divide by zero!" << endl;
326 for (int32_t i=0; i<m; i++)
327 for (int32_t j=0; j<n; j++)
328 C.val[i][j] = val[i][j]/s;
332 Matrix Matrix::operator- () {
334 for (int32_t i=0; i<m; i++)
335 for (int32_t j=0; j<n; j++)
336 C.val[i][j] = -val[i][j];
340 Matrix Matrix::operator~ () {
342 for (int32_t i=0; i<m; i++)
343 for (int32_t j=0; j<n; j++)
344 C.val[j][i] = val[i][j];
348 FLOAT Matrix::l2norm () {
350 for (int32_t i=0; i<m; i++)
351 for (int32_t j=0; j<n; j++)
352 norm += val[i][j]*val[i][j];
356 FLOAT Matrix::mean () {
358 for (int32_t i=0; i<m; i++)
359 for (int32_t j=0; j<n; j++)
361 return mean/(FLOAT)(m*n);
364 Matrix Matrix::cross (
const Matrix &a,
const Matrix &b) {
365 if (a.m!=3 || a.n!=1 || b.m!=3 || b.n!=1) {
366 cerr <<
"ERROR: Cross product vectors must be of size (3x1)" << endl;
370 c.val[0][0] = a.val[1][0]*b.val[2][0]-a.val[2][0]*b.val[1][0];
371 c.val[1][0] = a.val[2][0]*b.val[0][0]-a.val[0][0]*b.val[2][0];
372 c.val[2][0] = a.val[0][0]*b.val[1][0]-a.val[1][0]*b.val[0][0];
376 Matrix Matrix::inv (
const Matrix &M) {
378 cerr <<
"ERROR: Trying to invert matrix of size (" << M.m <<
"x" << M.n <<
")" << endl;
387 bool Matrix::inv () {
389 cerr <<
"ERROR: Trying to invert matrix of size (" << m <<
"x" << n <<
")" << endl;
398 FLOAT Matrix::det () {
401 cerr <<
"ERROR: Trying to compute determinant of a matrix of size (" << m <<
"x" << n <<
")" << endl;
406 int32_t *idx = (int32_t*)malloc(m*
sizeof(int32_t));
409 for( int32_t i=0; i<m; i++)
414 bool Matrix::solve (
const Matrix &M, FLOAT eps) {
420 if (A.m != A.n || A.m != B.m || A.m<1 || B.n<1) {
421 cerr <<
"ERROR: Trying to eliminate matrices of size (" << A.m <<
"x" << A.n <<
422 ") and (" << B.m <<
"x" << B.n <<
")" << endl;
427 int32_t* indxc =
new int32_t[m];
428 int32_t* indxr =
new int32_t[m];
429 int32_t* ipiv =
new int32_t[m];
432 int32_t i, icol, irow, j, k, l, ll;
433 FLOAT big, dum, pivinv, temp;
436 for (j=0;j<m;j++) ipiv[j]=0;
448 if (fabs(A.val[j][k])>=big) {
449 big=fabs(A.val[j][k]);
458 for (l=0;l<m;l++) SWAP(A.val[irow][l], A.val[icol][l])
459 for (l=0;l<n;l++) SWAP(B.val[irow][l], B.val[icol][l])
466 if (fabs(A.val[icol][icol]) < eps) {
473 pivinv=1.0/A.val[icol][icol];
474 A.val[icol][icol]=1.0;
475 for (l=0;l<m;l++) A.val[icol][l] *= pivinv;
476 for (l=0;l<n;l++) B.val[icol][l] *= pivinv;
481 dum = A.val[ll][icol];
482 A.val[ll][icol] = 0.0;
483 for (l=0;l<m;l++) A.val[ll][l] -= A.val[icol][l]*dum;
484 for (l=0;l<n;l++) B.val[ll][l] -= B.val[icol][l]*dum;
491 for (l=m-1;l>=0;l--) {
492 if (indxr[l]!=indxc[l])
494 SWAP(A.val[k][indxr[l]], A.val[k][indxc[l]])
511 bool Matrix::lu(int32_t *idx, FLOAT &d, FLOAT eps) {
514 cerr <<
"ERROR: Trying to LU decompose a matrix of size (" << m <<
"x" << n <<
")" << endl;
519 FLOAT big,dum,sum,temp;
520 FLOAT* vv = (FLOAT*)malloc(n*
sizeof(FLOAT));
522 for (i=0; i<n; i++) {
525 if ((temp=fabs(val[i][j]))>big)
533 for (j=0; j<n; j++) {
534 for (i=0; i<j; i++) {
537 sum -= val[i][k]*val[k][j];
541 for (i=j; i<n; i++) {
544 sum -= val[i][k]*val[k][j];
546 if ( (dum=vv[i]*fabs(sum))>=big) {
552 for (k=0; k<n; k++) {
554 val[imax][k] = val[j][k];
563 for (i=j+1; i<n; i++)
576 void Matrix::svd(Matrix &U2,Matrix &W,Matrix &V) {
578 Matrix U = Matrix(*
this);
582 FLOAT* w = (FLOAT*)malloc(n*
sizeof(FLOAT));
583 FLOAT* rv1 = (FLOAT*)malloc(n*
sizeof(FLOAT));
585 int32_t flag,i,its,j,jj,k,l,nm;
586 FLOAT anorm,c,f,g,h,s,scale,x,y,z;
588 g = scale = anorm = 0.0;
594 for (k=i;k<m;k++) scale += fabs(U.val[k][i]);
597 U.val[k][i] /= scale;
598 s += U.val[k][i]*U.val[k][i];
601 g = -SIGN(sqrt(s),f);
605 for (s=0.0,k=i;k<m;k++) s += U.val[k][i]*U.val[k][j];
607 for (k=i;k<m;k++) U.val[k][j] += f*U.val[k][i];
609 for (k=i;k<m;k++) U.val[k][i] *= scale;
615 for (k=l;k<n;k++) scale += fabs(U.val[i][k]);
618 U.val[i][k] /= scale;
619 s += U.val[i][k]*U.val[i][k];
622 g = -SIGN(sqrt(s),f);
625 for (k=l;k<n;k++) rv1[k] = U.val[i][k]/h;
627 for (s=0.0,k=l;k<n;k++) s += U.val[j][k]*U.val[i][k];
628 for (k=l;k<n;k++) U.val[j][k] += s*rv1[k];
630 for (k=l;k<n;k++) U.val[i][k] *= scale;
633 anorm = FMAX(anorm,(fabs(w[i])+fabs(rv1[i])));
635 for (i=n-1;i>=0;i--) {
639 V.val[j][i]=(U.val[i][j]/U.val[i][l])/g;
641 for (s=0.0,k=l;k<n;k++) s += U.val[i][k]*V.val[k][j];
642 for (k=l;k<n;k++) V.val[k][j] += s*V.val[k][i];
645 for (j=l;j<n;j++) V.val[i][j] = V.val[j][i] = 0.0;
651 for (i=IMIN(m,n)-1;i>=0;i--) {
654 for (j=l;j<n;j++) U.val[i][j] = 0.0;
658 for (s=0.0,k=l;k<m;k++) s += U.val[k][i]*U.val[k][j];
659 f = (s/U.val[i][i])*g;
660 for (k=i;k<m;k++) U.val[k][j] += f*U.val[k][i];
662 for (j=i;j<m;j++) U.val[j][i] *= g;
663 }
else for (j=i;j<m;j++) U.val[j][i]=0.0;
666 for (k=n-1;k>=0;k--) {
667 for (its=0;its<30;its++) {
671 if ((FLOAT)(fabs(rv1[l])+anorm) == anorm) { flag = 0;
break; }
672 if ((FLOAT)(fabs( w[nm])+anorm) == anorm) {
break; }
680 if ((FLOAT)(fabs(f)+anorm) == anorm)
break;
690 U.val[j][nm] = y*c+z*s;
691 U.val[j][i] = z*c-y*s;
699 for (j=0;j<n;j++) V.val[j][k] = -V.val[j][k];
704 cerr <<
"ERROR in SVD: No convergence in 30 iterations" << endl;
710 f = ((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y);
712 f = ((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x;
714 for (j=l;j<=nm;j++) {
728 for (jj=0;jj<n;jj++) {
731 V.val[jj][j] = x*c+z*s;
732 V.val[jj][i] = z*c-x*s;
743 for (jj=0;jj<m;jj++) {
746 U.val[jj][j] = y*c+z*s;
747 U.val[jj][i] = z*c-y*s;
761 FLOAT* su = (FLOAT*)malloc(m*
sizeof(FLOAT));
762 FLOAT* sv = (FLOAT*)malloc(n*
sizeof(FLOAT));
763 do { inc *= 3; inc++; }
while (inc <= n);
766 for (i=inc;i<n;i++) {
768 for (k=0;k<m;k++) su[k] = U.val[k][i];
769 for (k=0;k<n;k++) sv[k] = V.val[k][i];
771 while (w[j-inc] < sw) {
773 for (k=0;k<m;k++) U.val[k][j] = U.val[k][j-inc];
774 for (k=0;k<n;k++) V.val[k][j] = V.val[k][j-inc];
779 for (k=0;k<m;k++) U.val[k][j] = su[k];
780 for (k=0;k<n;k++) V.val[k][j] = sv[k];
785 for (i=0;i<m;i++)
if (U.val[i][k] < 0.0) s2++;
786 for (j=0;j<n;j++)
if (V.val[j][k] < 0.0) s2++;
788 for (i=0;i<m;i++) U.val[i][k] = -U.val[i][k];
789 for (j=0;j<n;j++) V.val[j][k] = -V.val[j][k];
794 W = Matrix(min(m,n),1,w);
797 U2.setMat(U.getMat(0,0,m-1,min(m-1,n-1)),0,0);
806 ostream& operator<< (ostream& out,
const Matrix& M) {
807 if (M.m==0 || M.n==0) {
808 out <<
"[empty matrix]";
811 for (int32_t i=0; i<M.m; i++) {
812 for (int32_t j=0; j<M.n; j++) {
813 sprintf(buffer,
"%12.7f ",M.val[i][j]);
823 void Matrix::allocateMemory (
const int32_t m_,
const int32_t n_) {
824 m = abs(m_); n = abs(n_);
829 val = (FLOAT**)malloc(m*
sizeof(FLOAT*));
830 val[0] = (FLOAT*)calloc(m*n,
sizeof(FLOAT));
831 for(int32_t i=1; i<m; i++)
835 void Matrix::releaseMemory () {
842 FLOAT Matrix::pythag(FLOAT a,FLOAT b) {
847 return absa*sqrt(1.0+SQR(absb/absa));
849 return (absb == 0.0 ? 0.0 : absb*sqrt(1.0+SQR(absa/absb)));