/* * * Template Numerical Toolkit (TNT) * * Mathematical and Computational Sciences Division * National Institute of Technology, * Gaithersburg, MD USA * * * This software was developed at the National Institute of Standards and * Technology (NIST) by employees of the Federal Government in the course * of their official duties. Pursuant to title 17 Section 105 of the * United States Code, this software is not subject to copyright protection * and is in the public domain. NIST assumes no responsibility whatsoever for * its use by other parties, and makes no guarantees, expressed or implied, * about its quality, reliability, or any other characteristic. * */ #ifndef IMPALGEBRA_TNT_ARRAY_2D_UTILS_H #define IMPALGEBRA_TNT_ARRAY_2D_UTILS_H #include #include #include #include #include #include "jama_lu.h" IMPALGEBRA_BEGIN_INTERNAL_NAMESPACE IMP_CLANG_PRAGMA(diagnostic push) IMP_CLANG_PRAGMA(diagnostic ignored "-Wshadow") namespace TNT { using namespace std; template inline std::ostream& operator<<(std::ostream &s, const Array2D &A) { int M=A.dim1(); int N=A.dim2(); s << M << " " << N << "\n"; for (int i=0; i inline std::istream& operator>>(std::istream &s, Array2D &A) { int M, N; s >> M >> N; Array2D B(M,N); for (int i=0; i> B[i][j]; } A = B; return s; } template inline Array2D operator+(const Array2D &A, const Array2D &B) { int m = A.dim1(); int n = A.dim2(); if (B.dim1() != m || B.dim2() != n ) return Array2D(); else { Array2D C(m,n); for (int i=0; i inline Array2D operator-(const Array2D &A, const Array2D &B) { int m = A.dim1(); int n = A.dim2(); if (B.dim1() != m || B.dim2() != n ) return Array2D(); else { Array2D C(m,n); for (int i=0; i inline Array2D operator*(const Array2D &A, const Array2D &B) { int m = A.dim1(); int n = A.dim2(); if (B.dim1() != m || B.dim2() != n ) return Array2D(); else { Array2D C(m,n); for (int i=0; i inline Array2D operator/(const Array2D &A, const Array2D &B) { int m = A.dim1(); int n = A.dim2(); if (B.dim1() != m || B.dim2() != n ) return Array2D(); else { Array2D C(m,n); for (int i=0; i inline Array2D& operator+=(Array2D &A, const Array2D &B) { int m = A.dim1(); int n = A.dim2(); if (B.dim1() == m || B.dim2() == n ) { for (int i=0; i inline Array2D& operator-=(Array2D &A, const Array2D &B) { int m = A.dim1(); int n = A.dim2(); if (B.dim1() == m || B.dim2() == n ) { for (int i=0; i inline Array2D& operator*=(Array2D &A, const Array2D &B) { int m = A.dim1(); int n = A.dim2(); if (B.dim1() == m || B.dim2() == n ) { for (int i=0; i inline Array2D& operator/=(Array2D &A, const Array2D &B) { int m = A.dim1(); int n = A.dim2(); if (B.dim1() == m || B.dim2() == n ) { for (int i=0; i inline Array2D matmult(const Array2D &A, const Array2D &B) { if (A.dim2() != B.dim1()) { IMP_THROW("Bad dimensions", base::ValueException); } int M = A.dim1(); int N = A.dim2(); int K = B.dim2(); Array2D C(M,K); for (int i=0; i inline Array2D transpose(const Array2D &A) { Array2D ret(A.dim2(), A.dim1()); for (int i=0; i < A.dim1(); ++i) { for (int j=0; j < A.dim2(); ++j) { ret[j][i]=A[i][j]; } } return ret; } /** Added by Keren */ template inline T determinant(const Array2D &M) { assert(M.dim1() == M.dim2()); // square matrices only please // Compute determinant using LU factors. JAMA::LU lu(M); return lu.det(); } /** Added by Keren */ template inline Array2D inverse(const Array2D &M) { assert(M.dim1() == M.dim2()); // square matrices only please // solve for inverse with LU decomposition JAMA::LU lu(M); // create identity matrix Array2D id(M.dim1(), M.dim2(), (T)0); for (int i = 0; i < M.dim1(); i++) id[i][i] = 1; // solves A * A_inv = Identity return lu.solve(id); } /** Added by Keren */ template inline bool is_inversable(const Array2D &M) { if (M.dim1() != M.dim2()) { return false; } // solve for inverse with LU decomposition JAMA::LU lu(M); // create identity matrix Array2D id(M.dim1(), M.dim2(), (T)0); for (int i = 0; i < M.dim1(); i++) id[i][i] = 1; // solves A * A_inv = Identity Array2D inv = lu.solve(id); //check if the values of inv are all numbers for(int d1=0;d1 inline Array1D multiply(const Array2D &M,const Array1D &V) { assert(M.dim2() == V.dim1()); Array1D ans(V.dim1()); for(int r=0; r< M.dim1(); ++r) { ans[r]=0.; for(int c=0; c< M.dim2(); ++c) { ans[r] += M[r][c]*V[c]; } } return ans; } /** Added by Keren */ template inline Array1D multiply(T s,const Array1D &V) { Array1D ans(V.dim1()); for(int i=0; i< V.dim1(); ++i) { ans[i]=V[i]*s; } return ans; } /** Added by Keren */ template inline Array2D multiply(T s,const Array2D &V) { Array2D ans(V.dim1(), V.dim2()); for(int i=0; i< V.dim1(); ++i) { for(int j=0; j< V.dim2(); ++j) { ans[i][j]=V[i][j]*s; } } return ans; } /** Added by Keren */ template inline Array1D add(const Array1D &V1,const Array1D &V2) { assert(V1.dim1() == V2.dim1()); Array1D ans(V1.dim1()); for(int i=0; i< V1.dim1(); ++i) { ans[i]=V1[i]+V2[i]; } return ans; } /** Added by Keren */ template inline Array1D subtract(const Array1D &V1,const Array1D &V2) { Array1D ans(V1.dim1()); for(int i=0; i< V1.dim1(); ++i) { ans[i]=V1[i]-V2[i]; } return ans; } /** Added by Keren */ template inline T dot_product(const Array1D &V1,const Array1D &V2) { assert(V1.dim1() == V2.dim1()); T ans = (T)0; for(int i=0; i< V1.dim1(); ++i) { ans += V1[i]*V2[i]; } return ans; } /** Added by Keren */ template inline void set_identity(Array2D &M) { for(int r=0; r< M.dim1(); ++r) { for(int c=0; c< M.dim2(); ++c) { M[r][c]=0.; } M[r][r]=1.; } } /** Added by Keren */ template inline void set_row(Array2D &M, const Array1D &v,int i) { assert(i