/* Copyright 2011. All rights reserved. Institute of Measurement and Control Systems Karlsruhe Institute of Technology, Germany Authors: Andreas Geiger matrix is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or any later version. matrix is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with matrix; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "matrix.h" #include #define SWAP(a,b) {temp=a;a=b;b=temp;} #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a)) static FLOAT sqrarg; #define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg) static FLOAT maxarg1,maxarg2; #define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ? (maxarg1) : (maxarg2)) static int32_t iminarg1,iminarg2; #define IMIN(a,b) (iminarg1=(a),iminarg2=(b),(iminarg1) < (iminarg2) ? (iminarg1) : (iminarg2)) using namespace std; Matrix::Matrix () { m = 0; n = 0; val = 0; } Matrix::Matrix (const int32_t m_,const int32_t n_) { allocateMemory(m_,n_); } Matrix::Matrix (const int32_t m_,const int32_t n_,const FLOAT* val_) { allocateMemory(m_,n_); int32_t k=0; for (int32_t i=0; i0) for (int32_t i=0; i=m || j1<0 || j2>=n || i2m || j1+M.n>n) { cerr << "ERROR: Cannot set submatrix [" << i1 << ".." << i1+M.m-1 << "] x [" << j1 << ".." << j1+M.n-1 << "]" << " of a (" << m << "x" << n << ") matrix." << endl; exit(0); } for (int32_t i=0; i idx) { Matrix M(m,idx.size()); for (int32_t j=0; j1 && M.n==1) { Matrix D(M.m,M.m); for (int32_t i=0; i1) { Matrix D(M.n,M.n); for (int32_t i=0; i=big) { big=fabs(A.val[j][k]); irow=j; icol=k; } ++(ipiv[icol]); // We now have the pivot element, so we interchange rows, if needed, to put the pivot // element on the diagonal. The columns are not physically interchanged, only relabeled. if (irow != icol) { for (l=0;l=0;l--) { if (indxr[l]!=indxc[l]) for (k=0;kbig) big = temp; if (big == 0.0) { // No nonzero largest element. free(vv); return false; } vv[i] = 1.0/big; // Save the scaling. } for (j=0; j=big) { big = dum; imax = i; } } if (j!=imax) { // Do we need to interchange rows? for (k=0; k=0;i--) { // Accumulation of right-hand transformations. if (i=0;i--) { // Accumulation of left-hand transformations. l = i+1; g = w[i]; for (j=l;j=0;k--) { // Diagonalization of the bidiagonal form: Loop over singular values, for (its=0;its<30;its++) { // and over allowed iterations. flag = 1; for (l=k;l>=0;l--) { // Test for splitting. nm = l-1; if ((FLOAT)(fabs(rv1[l])+anorm) == anorm) { flag = 0; break; } if ((FLOAT)(fabs( w[nm])+anorm) == anorm) { break; } } if (flag) { c = 0.0; // Cancellation of rv1[l], if l > 1. s = 1.0; for (i=l;i<=k;i++) { f = s*rv1[i]; rv1[i] = c*rv1[i]; if ((FLOAT)(fabs(f)+anorm) == anorm) break; g = w[i]; h = pythag(f,g); w[i] = h; h = 1.0/h; c = g*h; s = -f*h; for (j=0;j 1); for (k=0;k (m+n)/2) { for (i=0;im || n_>n) return; int32_t k=0; for (int32_t i=0; i absb) return absa*sqrt(1.0+SQR(absb/absa)); else return (absb == 0.0 ? 0.0 : absb*sqrt(1.0+SQR(absa/absb))); }