Isis 3 Programmer Reference
Matrix.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include <vector>
8#include <iostream>
9#include <string>
10#include "jama/jama_svd.h"
11#include "jama/jama_eig.h"
12#include "jama/jama_lu.h"
13
14#include "Constants.h"
15#include "IException.h"
16#include "IString.h"
17#include "Matrix.h"
18
19namespace Isis {
24 Matrix::Matrix(const int n, const int m, const double value) {
25 if(n < 1 || m < 1) {
26 std::string m = "Invalid matrix dimensions";
27 throw IException(IException::Programmer, m, _FILEINFO_);
28 }
29 p_matrix = TNT::Array2D<double>(n, m, value);
30 }
31
35 Matrix::Matrix(TNT::Array2D<double> matrix) {
36 p_matrix = matrix.copy();
37 }
38
41
45 Matrix Matrix::Identity(const int n) {
46 if(n < 1) {
47 std::string m = "Invalid matrix dimensions";
48 throw IException(IException::Programmer, m, _FILEINFO_);
49 }
50 Matrix identity(n, n);
51 for(int i = 0; i < identity.Rows(); i++) {
52 identity[i][i] = 1.0;
53 }
54 return identity;
55 }
56
61 if(Rows() != Columns()) {
62 std::string m = "Unable to calculate the determinant, the matrix is not square.";
63 throw IException(IException::Programmer, m, _FILEINFO_);
64 }
65 JAMA::LU<double> lu(p_matrix);
66 return lu.det();
67 }
68
72 double Matrix::Trace() {
73 if(Rows() != Columns()) {
74 std::string m = "Unable to calculate the trace, the matrix is not square.";
75 throw IException(IException::Programmer, m, _FILEINFO_);
76 }
77 double trace = 0.0;
78 for(int i = 0; i < Rows(); i++) {
79 trace += p_matrix[i][i];
80 }
81 return trace;
82 }
83
88 if(Columns() != matrix.Rows()) {
89 std::string m = "Incompatible matrix dimensions, cannot multiply the matrices.";
90 throw IException(IException::Programmer, m, _FILEINFO_);
91 }
92 TNT::Array2D<double> m(matrix.Rows(), matrix.Columns());
93 for(int i = 0; i < m.dim1(); i++) {
94 for(int j = 0; j < m.dim2(); j++) {
95 m[i][j] = matrix[i][j];
96 }
97 }
98 return Matrix(TNT::matmult(p_matrix, m));
99 }
100
105 if(Rows() != matrix.Rows() || Columns() != matrix.Columns()) {
106 std::string m = "Incompatible matrix dimensions, cannot add the matrices.";
107 throw IException(IException::Programmer, m, _FILEINFO_);
108 }
109 TNT::Array2D<double> m(matrix.Rows(), matrix.Columns());
110 for(int i = 0; i < m.dim1(); i++) {
111 for(int j = 0; j < m.dim2(); j++) {
112 m[i][j] = matrix[i][j];
113 }
114 }
115 return Matrix(p_matrix + m);
116 }
117
122 if(Rows() != matrix.Rows() || Columns() != matrix.Columns()) {
123 std::string m = "Incompatible matrix dimensions, cannot subtract the matrices.";
124 throw IException(IException::Programmer, m, _FILEINFO_);
125 }
126 TNT::Array2D<double> m(matrix.Rows(), matrix.Columns());
127 for(int i = 0; i < m.dim1(); i++) {
128 for(int j = 0; j < m.dim2(); j++) {
129 m[i][j] = matrix[i][j];
130 }
131 }
132
133 return Matrix(p_matrix - m);
134 }
135
141 if(Rows() != matrix.Rows() || Columns() != matrix.Columns()) {
142 std::string m = "Incompatible matrix dimensions, cannot multiply the matrices.";
143 throw IException(IException::Programmer, m, _FILEINFO_);
144 }
145 TNT::Array2D<double> m(matrix.Rows(), matrix.Columns());
146 for(int i = 0; i < m.dim1(); i++) {
147 for(int j = 0; j < m.dim2(); j++) {
148 m[i][j] = matrix[i][j];
149 }
150 }
151 return Matrix(p_matrix * m);
152 }
153
157 Matrix Matrix::Multiply(double scalar) {
158 Matrix product(Rows(), Columns());
159 for(int i = 0; i < Rows(); i++) {
160 for(int j = 0; j < Columns(); j++) {
161 product[i][j] = p_matrix[i][j] * scalar;
162 }
163 }
164 return product;
165 }
166
171 TNT::Array2D<double> transpose(p_matrix.dim2(), p_matrix.dim1());
172 for(int i = 0; i < transpose.dim1(); i++) {
173 for(int j = 0; j < transpose.dim2(); j++) {
174 transpose[i][j] = p_matrix[j][i];
175 }
176 }
177 return Matrix(transpose);
178 }
179
184 if(Rows() != Columns()) {
185 std::string m = "Unable to calculate the inverse, the matrix is not square.";
186 throw IException(IException::Programmer, m, _FILEINFO_);
187 }
188 TNT::Array2D<double> id(p_matrix.dim1(), p_matrix.dim2(), 0.0);
189 for(int i = 0; i < p_matrix.dim1(); i++) id[i][i] = 1;
190
191 JAMA::LU<double> lu(p_matrix);
192 if(lu.det() == 0.0) {
193 std::string m = "Cannot take the inverse of the matrix";
194 throw IException(IException::Programmer, m, _FILEINFO_);
195 }
196
197 return Matrix(lu.solve(id));
198 }
199
203 std::vector<double> Matrix::Eigenvalues() {
204 if(Rows() != Columns()) {
205 std::string m = "Unable to calculate eigenvalues, the matrix is not square.";
206 throw IException(IException::Programmer, m, _FILEINFO_);
207 }
208 JAMA::Eigenvalue<double> E(p_matrix);
209 TNT::Array2D<double> D;
210 E.getD(D);
211
212 std::vector<double> eigenvalues(D.dim1());
213 for(int i = 0; i < D.dim1(); i++) {
214 eigenvalues[i] = D[i][i];
215 }
216
217 return eigenvalues;
218 }
219
225 if(Rows() != Columns()) {
226 std::string m = "Unable to calculate eigenvectors, the matrix is not square.";
227 throw IException(IException::Programmer, m, _FILEINFO_);
228 }
229 JAMA::Eigenvalue<double> E(p_matrix);
230 TNT::Array2D<double> V;
231 E.getV(V);
232
233 return Matrix(V);
234 }
235
239 ostream &operator<<(ostream &os, Matrix &matrix) {
240 for(int i = 0; i < matrix.Rows(); i++) {
241 for(int j = 0; j < matrix.Columns(); j++) {
242 os << matrix[i][j];
243 if(j < matrix.Columns() - 1) os << " ";
244 }
245 if(i < matrix.Rows() - 1) os << endl;
246 }
247 return os;
248 }
249} // end namespace isis
Isis exception class.
Definition IException.h:91
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
Matrix class.
Definition Matrix.h:34
double Determinant()
Compute the determinant of the matrix.
Definition Matrix.cpp:60
std::vector< double > Eigenvalues()
Compute the eigenvalues of the matrix.
Definition Matrix.cpp:203
Matrix Transpose()
Compute the transpose of the matrix.
Definition Matrix.cpp:170
Matrix Subtract(Matrix &matrix)
Subtract the input matrix from this matrix.
Definition Matrix.cpp:121
Matrix Eigenvectors()
Compute the eigenvectors of the matrix and return them as columns of a matrix in ascending order.
Definition Matrix.cpp:224
Matrix(const int n, const int m, const double value=0.0)
Constructs an n x m Matrix containing the specified default value.
Definition Matrix.cpp:24
double Trace()
Compute the determinant of the matrix.
Definition Matrix.cpp:72
~Matrix()
Destroys the Matrix object.
Definition Matrix.cpp:40
Matrix Inverse()
Compute the inverse of the matrix.
Definition Matrix.cpp:183
Matrix Add(Matrix &matrix)
Add the two matrices.
Definition Matrix.cpp:104
static Matrix Identity(const int n)
Create an n x n identity matrix.
Definition Matrix.cpp:45
Matrix MultiplyElementWise(Matrix &matrix)
Multiply the two matrices element-wise (ie compute C such that C[i][j] = A[i][j]*B[i][j])
Definition Matrix.cpp:140
Matrix Multiply(Matrix &matrix)
Multiply the two matrices.
Definition Matrix.cpp:87
const double E
Sets some basic constants for use in ISIS programming.
Definition Constants.h:39
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QDebug operator<<(QDebug debug, const Hillshade &hillshade)
Print this class out to a QDebug object.