LoAdSG
matrix.h
1#ifndef MATRIX_H
2#define MATRIX_H
3
4#include <iostream>
5#include <cmath>
6#include <vector>
7#include <cstdlib>
8#include <fstream>
9
10class Matrix{
11private:
12 int rows,cols;
13
14 std::vector<double> data;
15
16public:
17 Matrix(int dim1, int dim2);
18
19 Matrix(const Matrix& M);
20
21 ~Matrix(){
22 }
23 Matrix& operator=(const Matrix& M);
24
25 double operator[](int index) const;
26
27 double& operator[](int index);
28
29 Matrix operator*(const Matrix& M);
30
31 Matrix subMatrix(int i, int j);
32
33 double det();
34
35 Matrix invert();
36
37 double value(int i1, int i2) const{
38 return data[i1*cols+i2];
39 }
40
41 double& value(int i1, int i2){
42 return data[i1*cols+i2];
43 }
44
45 int getRows() const{
46 return rows;
47 }
48
49 int getCols() const{
50 return cols;
51 }
52
53 void scale(double s){
54 for(int i=0;i<rows*cols;i++){
55 data[i] = s*data[i];
56 }
57 }
58
59 void Print(){
60 for(int i=0;i<rows;i++){
61 for(int j=0;j<cols;j++){
62 std::cout<<value(i,j)<<"\t";
63 }
64 std::cout<<std::endl;
65 }
66 }
67
68 Matrix transpose();
69
70 std::vector<double> getData() const{
71 return data;
72 }
73
74 void exportToFile(const char *filename);
75
76 double norm2(){
77 double vecnorm = 0.0;
78 for(int i=0;i<rows;i++){
79 for(int j=0;j<cols;j++){
80 vecnorm += value(i,j)*value(i,j);
81 }
82 }
83 vecnorm = vecnorm/(rows*cols);
84 return(std::sqrt(vecnorm));
85 }
86
87 Matrix operator+(const Matrix& m){
88 Matrix newmat(*this);
89 for(int i=0;i<rows;i++){
90 for(int j=0;j<cols;j++){
91 newmat.value(i,j) += m.value(i,j);
92 }
93 }
94
95 return newmat;
96 }
97
98 Matrix operator-(const Matrix& m){
99 Matrix newmat(*this);
100 for(int i=0;i<rows;i++){
101 for(int j=0;j<cols;j++){
102 newmat.value(i,j) -= m.value(i,j);
103 }
104 }
105 return newmat;
106 }
107
108 double dp(const Matrix& m){
109 double res = 0.0;
110 for(int i=0;i<rows;i++){
111 res += value(i,0)*m.value(i,0);
112 }
113 return res;
114 }
115
116 Matrix sc(double val){
117 Matrix newmat(*this);
118 for(int i=0;i<rows;i++){
119 for(int j=0;j<cols;j++){
120 newmat.value(i,j) = val*newmat.value(i,j);
121 }
122 }
123 return newmat;
124 }
125
126};
127
128
129Matrix::Matrix(int dim1_, int dim2_){
130 rows = dim1_;
131 cols = dim2_;
132
133 data.resize(rows*cols);
134
135 std::fill(data.begin(),data.end(),0.0);
136}
137
138Matrix::Matrix(const Matrix &M){
139
140 rows = M.getRows();
141 cols = M.getCols();
142
143 data = M.getData();
144}
145
146Matrix& Matrix::operator=(const Matrix &M){
147
148 rows = M.getRows();
149 cols = M.getCols();
150
151 data = M.getData();
152
153 return *this;
154}
155
156double& Matrix::operator[](int index){
157 return data[index];
158}
159
160double Matrix::operator[](int index) const{
161 return data[index];
162}
163
164
165Matrix Matrix::operator*(const Matrix& M){
166 if(this->cols != M.getRows()){
167 std::cerr<<"Dimensions incompatible for matrix multiplication"<<std::endl;
168 exit(-1);
169 }
170
171 int r = this->rows;
172 int c = M.getCols();
173
174 Matrix result(r,c);
175
176
177 for(int i=0;i<r;i++){
178 for(int j=0;j<c;j++){
179 for(int k=0;k<this->cols;k++){
180 result.value(i,j) += value(i,k)*M.value(k,j);
181 }
182 }
183 }
184
185 return result;
186}
187
188Matrix Matrix::subMatrix(int r, int c){
189 Matrix sub(rows-1,cols-1);
190 int temp_i,temp_j;
191
192 for(int i=0;i<rows-1;i++){
193 for(int j=0;j<cols-1;j++){
194 temp_i = i;
195 temp_j = j;
196
197 if(i >= r){
198 temp_i = i+1;
199 }
200 if(j >= c){
201 temp_j = j+1;
202 }
203 sub.value(i,j) = value(temp_i,temp_j);
204 }
205 }
206
207 return sub;
208}
209
210Matrix Matrix::transpose(){
211 Matrix trans(cols,rows);
212
213 for(int i=0;i<cols;i++){
214 for(int j=0;j<rows;j++){
215 trans.value(i,j) = this->value(j,i);
216 }
217 }
218
219 return trans;
220}
221
222Matrix Matrix::invert(){
223 if(det() == 0){
224 std::cerr<<"Matrix not invertible"<<std::endl;
225 exit(-1);
226 }
227 Matrix inv(rows,cols);
228 for(int i=0;i<rows;i++){
229 for(int j=0; j<cols;j++){
230 Matrix temp = subMatrix(i,j);
231 inv.value(i,j) = temp.det()*pow(-1,i+j);
232 }
233 }
234
235 inv = inv.transpose();
236 inv.scale(1.0/(this->det()));
237
238 return inv;
239}
240double Matrix::det(){
241 double det = 0.0;
242 if(rows != cols){
243 std::cerr<<"Not a square matrix. Hence can't compute the determinant."<<std::endl;
244 exit(-1);
245 }
246
247 if(rows == 1){
248 return data[0];
249 }
250
251 if(rows == 2){
252 return (value(0,0)*value(1,1)-value(0,1)*value(1,0));
253 }
254
255 if(rows == 3){
256 for(int i=0;i<3;i++){
257 Matrix temp(this->subMatrix(0,i));
258
259 det += pow(-1,i)*value(0,i)*temp.det();
260 }
261 return det;
262 }
263 return 0.0;
264}
265
266void Matrix::exportToFile(const char* filename){
267 std::ofstream outfile;
268 outfile.open(filename);
269
270 for(int i=0;i<rows;i++){
271 for(int j=0;j<cols;j++){
272 outfile<<value(i,j)<<std::endl;
273 }
274 }
275
276 outfile.close();
277}
278#endif // MATRIX_H