USGS

Isis 3.0 Object Programmers' Reference

Home

Matrix.cpp
Go to the documentation of this file.
1 
23 #include <vector>
24 #include <iostream>
25 #include <string>
26 #include "jama/jama_svd.h"
27 #include "jama/jama_eig.h"
28 #include "jama/jama_lu.h"
29 
30 #include "Constants.h"
31 #include "IException.h"
32 #include "IString.h"
33 #include "Matrix.h"
34 
35 namespace Isis {
40  Matrix::Matrix(const int n, const int m, const double value) {
41  if(n < 1 || m < 1) {
42  std::string m = "Invalid matrix dimensions";
44  }
45  p_matrix = TNT::Array2D<double>(n, m, value);
46  }
47 
51  Matrix::Matrix(TNT::Array2D<double> matrix) {
52  p_matrix = matrix.copy();
53  }
54 
57 
61  Matrix Matrix::Identity(const int n) {
62  if(n < 1) {
63  std::string m = "Invalid matrix dimensions";
65  }
66  Matrix identity(n, n);
67  for(int i = 0; i < identity.Rows(); i++) {
68  identity[i][i] = 1.0;
69  }
70  return identity;
71  }
72 
77  if(Rows() != Columns()) {
78  std::string m = "Unable to calculate the determinant, the matrix is not square.";
80  }
81  JAMA::LU<double> lu(p_matrix);
82  return lu.det();
83  }
84 
88  double Matrix::Trace() {
89  if(Rows() != Columns()) {
90  std::string m = "Unable to calculate the trace, the matrix is not square.";
92  }
93  double trace = 0.0;
94  for(int i = 0; i < Rows(); i++) {
95  trace += p_matrix[i][i];
96  }
97  return trace;
98  }
99 
104  if(Columns() != matrix.Rows()) {
105  std::string m = "Incompatible matrix dimensions, cannot multiply the matrices.";
107  }
108  TNT::Array2D<double> m(matrix.Rows(), matrix.Columns());
109  for(int i = 0; i < m.dim1(); i++) {
110  for(int j = 0; j < m.dim2(); j++) {
111  m[i][j] = matrix[i][j];
112  }
113  }
114  return Matrix(TNT::matmult(p_matrix, m));
115  }
116 
121  if(Rows() != matrix.Rows() || Columns() != matrix.Columns()) {
122  std::string m = "Incompatible matrix dimensions, cannot add the matrices.";
124  }
125  TNT::Array2D<double> m(matrix.Rows(), matrix.Columns());
126  for(int i = 0; i < m.dim1(); i++) {
127  for(int j = 0; j < m.dim2(); j++) {
128  m[i][j] = matrix[i][j];
129  }
130  }
131  return Matrix(p_matrix + m);
132  }
133 
138  if(Rows() != matrix.Rows() || Columns() != matrix.Columns()) {
139  std::string m = "Incompatible matrix dimensions, cannot subtract the matrices.";
141  }
142  TNT::Array2D<double> m(matrix.Rows(), matrix.Columns());
143  for(int i = 0; i < m.dim1(); i++) {
144  for(int j = 0; j < m.dim2(); j++) {
145  m[i][j] = matrix[i][j];
146  }
147  }
148 
149  return Matrix(p_matrix - m);
150  }
151 
157  if(Rows() != matrix.Rows() || Columns() != matrix.Columns()) {
158  std::string m = "Incompatible matrix dimensions, cannot multiply the matrices.";
160  }
161  TNT::Array2D<double> m(matrix.Rows(), matrix.Columns());
162  for(int i = 0; i < m.dim1(); i++) {
163  for(int j = 0; j < m.dim2(); j++) {
164  m[i][j] = matrix[i][j];
165  }
166  }
167  return Matrix(p_matrix * m);
168  }
169 
173  Matrix Matrix::Multiply(double scalar) {
174  Matrix product(Rows(), Columns());
175  for(int i = 0; i < Rows(); i++) {
176  for(int j = 0; j < Columns(); j++) {
177  product[i][j] = p_matrix[i][j] * scalar;
178  }
179  }
180  return product;
181  }
182 
187  TNT::Array2D<double> transpose(p_matrix.dim2(), p_matrix.dim1());
188  for(int i = 0; i < transpose.dim1(); i++) {
189  for(int j = 0; j < transpose.dim2(); j++) {
190  transpose[i][j] = p_matrix[j][i];
191  }
192  }
193  return Matrix(transpose);
194  }
195 
200  if(Rows() != Columns()) {
201  std::string m = "Unable to calculate the inverse, the matrix is not square.";
203  }
204  TNT::Array2D<double> id(p_matrix.dim1(), p_matrix.dim2(), 0.0);
205  for(int i = 0; i < p_matrix.dim1(); i++) id[i][i] = 1;
206 
207  JAMA::LU<double> lu(p_matrix);
208  if(lu.det() == 0.0) {
209  std::string m = "Cannot take the inverse of the matrix";
211  }
212 
213  return Matrix(lu.solve(id));
214  }
215 
219  std::vector<double> Matrix::Eigenvalues() {
220  if(Rows() != Columns()) {
221  std::string m = "Unable to calculate eigenvalues, the matrix is not square.";
223  }
224  JAMA::Eigenvalue<double> E(p_matrix);
225  TNT::Array2D<double> D;
226  E.getD(D);
227 
228  std::vector<double> eigenvalues(D.dim1());
229  for(int i = 0; i < D.dim1(); i++) {
230  eigenvalues[i] = D[i][i];
231  }
232 
233  return eigenvalues;
234  }
235 
241  if(Rows() != Columns()) {
242  std::string m = "Unable to calculate eigenvectors, the matrix is not square.";
244  }
245  JAMA::Eigenvalue<double> E(p_matrix);
246  TNT::Array2D<double> V;
247  E.getV(V);
248 
249  return Matrix(V);
250  }
251 
255  ostream &operator<<(ostream &os, Matrix &matrix) {
256  for(int i = 0; i < matrix.Rows(); i++) {
257  for(int j = 0; j < matrix.Columns(); j++) {
258  os << matrix[i][j];
259  if(j < matrix.Columns() - 1) os << " ";
260  }
261  if(i < matrix.Rows() - 1) os << endl;
262  }
263  return os;
264  }
265 } // end namespace isis