/** * @file Matrix.cpp * @brief matrix class * @author Christian Potthast */ #include #include #include #include #include #include #include #include #include "Matrix.h" #include "Vector.h" #include "svdcmp.h" using namespace std; namespace ublas = boost::numeric::ublas; namespace gtsam { /* ************************************************************************* */ Matrix Matrix_( size_t m, size_t n, const double* const data) { Matrix A(m,n); copy(data, data+m*n, A.data().begin()); return A; } /* ************************************************************************* */ Matrix Matrix_( size_t m, size_t n, const Vector& v) { Matrix A(m,n); // column-wise copy for( size_t j = 0, k=0 ; j < n ; j++) for( size_t i = 0; i < m ; i++,k++) A(i,j) = v(k); return A; } /* ************************************************************************* */ Matrix Matrix_(size_t m, size_t n, ...) { Matrix A(m,n); va_list ap; va_start(ap, n); for( size_t i = 0 ; i < m ; i++) for( size_t j = 0 ; j < n ; j++) { double value = va_arg(ap, double); A(i,j) = value; } va_end(ap); return A; } /* ************************************************************************* */ /** create a matrix with value zero */ /* ************************************************************************* */ Matrix zeros( size_t m, size_t n ) { Matrix A(m,n); fill(A.data().begin(),A.data().end(),0.0); return A; } /** * Identity matrix */ Matrix eye( size_t m, size_t n){ Matrix A = zeros(m,n); for(size_t i = 0; i tol) return false; } return true; } /* ************************************************************************* */ bool assert_equal(const Matrix& A, const Matrix& B, double tol) { if (equal_with_abs_tol(A,B,tol)) return true; size_t n1 = A.size2(), m1 = A.size1(); size_t n2 = B.size2(), m2 = B.size1(); cout << "not equal:" << endl; print(A,"actual = "); print(B,"expected = "); if(m1!=m2 || n1!=n2) cout << m1 << "," << n1 << " != " << m2 << "," << n2 << endl; else print(A-B, "actual - expected = "); return false; } /* ************************************************************************ */ /** negation */ /* ************************************************************************ */ /* Matrix operator-() const { size_t m = size1(),n=size2(); Matrix M(m,n); for(size_t i = 0; i < m; i++) for(size_t j = 0; j < n; j++) M(i,j) = -matrix_(i,j); return M; } */ /* ************************************************************************* */ Vector Vector_(const Matrix& A) { size_t m = A.size1(), n = A.size2(); Vector v(m*n); for( size_t j = 0, k=0 ; j < n ; j++) for( size_t i = 0; i < m ; i++,k++) v(k) = A(i,j); return v; } /* ************************************************************************* */ Vector column(const Matrix& A, size_t j) { if (j>=A.size2()) throw invalid_argument("Column index out of bounds!"); size_t m = A.size1(); Vector a(m); for (int i=0; i=A.size1()) throw invalid_argument("Row index out of bounds!"); size_t n = A.size2(); Vector a(n); for (int j=0; j(A, B); } /* ************************************************************************* */ Matrix inverse(const Matrix& originalA) { Matrix A(originalA); Matrix B = eye(A.size2()); solve(A,B); return B; } /* ************************************************************************* */ /** Householder QR factorization, Golub & Van Loan p 224, explicit version */ /* ************************************************************************* */ pair qr(const Matrix& A) { const size_t m = A.size1(), n = A.size2(), kprime = min(m,n); Matrix Q=eye(m,m),R(A); Vector v(m); // loop over the kprime first columns for(size_t j=0; j < kprime; j++){ // we now work on the matrix (m-j)*(n-j) matrix A(j:end,j:end) const size_t mm=m-j; // copy column from matrix to xjm, i.e. x(j:m) = A(j:m,j) Vector xjm(mm); for(size_t k = 0 ; k < mm; k++) xjm(k) = R(j+k, j); // calculate the Householder vector v double beta; Vector vjm; boost::tie(beta,vjm) = house(xjm); // pad with zeros to get m-dimensional vector v for(size_t k = 0 ; k < m; k++) v(k) = k > weighted_eliminate(Matrix& A, Vector& b, const Vector& sigmas) { bool verbose = false; size_t m = A.size1(), n = A.size2(); // get size(A) size_t maxRank = min(m,n); // create list list > results; // We loop over all columns, because the columns that can be eliminated // are not necessarily contiguous. For each one, estimate the corresponding // scalar variable x as d-rS, with S the separator (remaining columns). // Then update A and b by substituting x with d-rS, zero-ing out x's column. for (int j=0; j 0 ; i--){ cols--; int j = n; div = R(i-1, cols); for( int ii = i ; ii < n ; ii++ ){ j = j - 1; tmp = tmp + R(i-1,j) * result(j); } // assigne the result vector result(i-1) = (b(i-1) - tmp) / div; tmp = 0.0; } return result; } /* ************************************************************************* */ Matrix stack(size_t nrMatrices, ...) { int dimA1 = 0; int dimA2 = 0; va_list ap; va_start(ap, nrMatrices); for(size_t i = 0 ; i < nrMatrices ; i++) { Matrix *M = va_arg(ap, Matrix *); dimA1 += M->size1(); dimA2 = M->size2(); // TODO: should check if all the same ! } va_end(ap); va_start(ap, nrMatrices); Matrix A(dimA1, dimA2); int vindex = 0; for( size_t i = 0 ; i < nrMatrices ; i++) { Matrix *M = va_arg(ap, Matrix *); for(size_t d1 = 0; d1 < M->size1(); d1++) for(size_t d2 = 0; d2 < M->size2(); d2++) A(vindex+d1, d2) = (*M)(d1, d2); vindex += M->size1(); } return A; } /* ************************************************************************* */ Matrix collect(vector matrices) { int dimA1 = 0; int dimA2 = 0; BOOST_FOREACH(const Matrix* M, matrices) { dimA1 = M->size1(); // TODO: should check if all the same ! dimA2 += M->size2(); } Matrix A(dimA1, dimA2); int hindex = 0; BOOST_FOREACH(const Matrix* M, matrices) { for(size_t d1 = 0; d1 < M->size1(); d1++) for(size_t d2 = 0; d2 < M->size2(); d2++) A(d1, d2+hindex) = (*M)(d1, d2); hindex += M->size2(); } return A; } /* ************************************************************************* */ Matrix collect(size_t nrMatrices, ...) { vector matrices; va_list ap; va_start(ap, nrMatrices); for( size_t i = 0 ; i < nrMatrices ; i++) { Matrix *M = va_arg(ap, Matrix *); matrices.push_back(M); } return collect(matrices); } /* ************************************************************************* */ // row scaling Matrix vector_scale(const Matrix& A, const Vector& v) { Matrix M(A); for (int i=0; i