-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLinearAlgebra.cpp
139 lines (123 loc) · 3.98 KB
/
LinearAlgebra.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "LinearAlgebra.h"
Matrix pow (const Matrix& m, int e){
if (m.GetColSize() != m.GetRowSize()){
throw std::runtime_error("ERROR: THE MATRIX MUST BE A 2X2 MATRIX SQUARE MATRIX");
}
Matrix result(m);
for(int i =0;i<e;++i){
result = result * m;
}
return result;
}
Matrix inverse2x2 (const Matrix& m){
if(m.GetRowSize() != 2 || m.GetColSize() != 2){
throw std::runtime_error("ERROR: THE MATRIX MUST BE A 2X2 MATRIX");
}
Rational detVal(det(m));
if(detVal == Rational()){
throw std::runtime_error("ERROR: NON-INVERTIBLE MATRIX");
}
Matrix result (2, 2);
result.SetElement(1, 1, m.GetElement(2, 2));
result.SetElement(2, 2, m.GetElement(1, 1));
result.SetElement(1, 2, m.GetElement(1, 2) * -1);
result.SetElement(2, 1, m.GetElement(2, 1) * -1);
return result*(detVal.Inverse());
}
Matrix inverse (const Matrix& m){
return adj(m) * det(m).Inverse();
}
Matrix diag(const std::initializer_list<Rational> elements){
Matrix diag(static_cast<int>(elements.size()));
const Rational* iter = elements.begin();
for(int i=1;i<=elements.size();++i){
diag.SetElement(i, i, *iter);
++iter;
}
return diag;
}
Matrix diag(const std::initializer_list<int> elements){
Matrix diag(static_cast<int>(elements.size()));
const int* iter = elements.begin();
for(int i=1;i<=elements.size();++i){
diag.SetElement(i, i, Rational(*iter));
++iter;
}
return diag;
}
Rational tr(const Matrix& m){
if (not m.IsSquare()){
throw std::runtime_error("ERROR: THE MATRIX MUST BE A SQUARE MATRIX");
}
Rational sum;
for(int i=1;i<=m.GetRowSize();++i){
sum = sum + m.GetElement(i, i);
}
return sum;
}
Rational srrusRule(const Matrix& m) {
if (m.GetRowSize() != 3 || m.GetColSize() != 3) {
throw std::runtime_error("ERROR: THE MATRIX MUST BE A 3X3 MATRIX");
}
Rational det;
det = m.GetElement(1, 1) * m.GetElement(2, 2) * m.GetElement(3, 3)
+ m.GetElement(1, 2) * m.GetElement(2, 3) * m.GetElement(3, 1)
+ m.GetElement(1, 3) * m.GetElement(2, 1) * m.GetElement(3, 2)
- m.GetElement(1, 3) * m.GetElement(2, 2) * m.GetElement(3, 1)
- m.GetElement(1, 2) * m.GetElement(2, 1) * m.GetElement(3, 3)
- m.GetElement(1, 1) * m.GetElement(2, 3) * m.GetElement(3, 2);
return det;
}
Rational det(const Matrix& m){
if (not m.IsSquare()){
throw std::runtime_error("ERROR: THE MATRIX MUST BE A SQUARE MATRIX");
}
Rational result;
if(m.GetColSize() == 2){
result = (m.GetElement(1, 1) * m.GetElement(2, 2)) - (m.GetElement(1, 2) * m.GetElement(2, 1));
return result;
}
for(int i=1;i<=m.GetRowSize();++i){
result = result + (m.GetElement(1, i) * cofactor(m, 1, i));
}
return result;
}
Rational cofactor(const Matrix& m, int a, int b) {
if (not m.IsSquare()){
throw std::runtime_error("ERROR: THE MATRIX MUST BE A SQUARE MATRIX");
}
Rational c = pow(Rational(-1), a+b);
Matrix d(m.GetRowSize()-1, m.GetColSize()-1);
int di = 1;
for (int i = 1; i <=m.GetRowSize(); ++i) {
if (i == a) {continue;}
int dj = 1;
for (int j = 1; j <= m.GetColSize(); ++j) {
if (j == b) {continue;}
d.SetElement(di, dj, m.GetElement(i, j));
++dj;
}
++di;
}
return det(d) * c;
}
Matrix adj(const Matrix& m){
Matrix result(m);
for(int i=1;i<=m.GetRowSize();++i){
for(int j=1;j<=m.GetColSize();++j){
result.SetElement(i, j, cofactor(m, i, j));
}
}
return result.Transpose();
}
Matrix cramerRule (const Matrix& m, const Matrix& b){
if(b.GetColSize()!=1) {
throw std::runtime_error("ERROR: THE SECOND MATRIX MUST BE A COLUMN VECTOR");
}
Matrix x(m.GetColSize(),1);
Rational detVal = det(m);
for(int i =1;i<=b.GetRowSize();++i){
x.SetElement(i, 1, det(m.SetColVector(i, b)) / detVal);
}
return x;
}