-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlinalgebra.h
More file actions
339 lines (274 loc) · 9.3 KB
/
linalgebra.h
File metadata and controls
339 lines (274 loc) · 9.3 KB
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
#ifndef LINALGEBRA_H
#define LINALGEBRA_H
#include <iostream>
#include <ctime>
#include <cmath>
#include <conio.h>
#include "exception"
#include "iostream"
#include "iomanip"
#include "QString"
#include "cassert"
#include "QVector"
#include "QList"
#include "QStringList"
typedef QVector<double> QVdouble;
typedef QVector<QVdouble> QVVdouble;
inline QString str_fill (int length, char fillChar = ' ') {
QString String_p = "";
for (int i = 0; i < length; ++i) {
String_p += fillChar;
}
return String_p;
}
inline QString str_fill (int length, QString fillStr) {
QString String_p = "";
for (int i = 0; i < length; ++i) {
String_p += fillStr;
}
return String_p;
}
enum mMatrType{
mmtNotMatr,
mmtDefault,
mmtSquare
};
class mMatrix {
// Матрица организована как вектор строк(row),
// т.е. сначала идет строка, потом обращение к колонке
protected:
// double ** data;
QVVdouble data;
int _rows;
int _columns;
mMatrType _type = mmtDefault;
int _dim;
public:
mMatrix(int rows, int columns);
mMatrix(QVVdouble matr);
mMatrix(std::initializer_list<std::initializer_list<double>> matr);
mMatrix(const mMatrix &mMatrix);
~mMatrix(){};
int rowLen() const;
int colLen() const;
int dim() const;
void resize(int newRow, int newCol, bool isSafeResize = true);
// void addRow() const;
// void addCol() const;
// void appendRow() const;
// void appendCol() const;
void copymMatrix(const mMatrix &matr);
void resizeAndCopymMatrix(const mMatrix &matr);
void print();
QString toQStr(QString sep = "|",
QString format = "6 f") const;
void setItem(int row, int columns, double value);
void setRow (int rNum, QVdouble row);
void setCol (int cNum, QVdouble col);
double it(int row, int columns) const;
QVdouble row(int indx);
QVdouble col(int indx);
const QVVdouble& matr() const{return data;} // для константных объектов
void fillZeros();
mMatrix T(); //возвращает транспонированную матрицу
mMatrix M(int row, int col); // Возвращает матрицу минора для элемента
double Minor(int row, int col); // Возвращает определитель М. минора для элемента
mMatrix MMatr(); // Возвращает матрицу минора для элемента
double det();
mMatrix adMatr(); // Матрица алгебраических дополнений
double ad(int row, int col); // Алгебраическое дополнение
mMatrix inv();
bool isE(); // Единичная ли матрица?
bool isSqr(); // Квадратная ли матрица?
static mMatrix solve(mMatrix A, mMatrix B); // Решение матричного уровнения A*X=B
public:
double& operator()(int row, int col);
const double& operator()(int row, int col) const; // для константных объектов
mMatrix& operator=(const mMatrix &mMatrix) {
copymMatrix(mMatrix);
return *this;
}
mMatrix operator+(const mMatrix &);
mMatrix operator-(const mMatrix &);
mMatrix operator*(const double &);
mMatrix operator/(const double &);
friend mMatrix operator*(const mMatrix &Matr1, const mMatrix &Matr2);
friend mMatrix operator*(const double num, const mMatrix &Matr);
friend bool operator== (const mMatrix &m1,
const mMatrix &m2){
if(m1._type == m2._type){
if (m1.rowLen()==m2.rowLen()&&
m1.colLen()==m2.colLen()) {
for(int r = 0; r < m1.rowLen(); r++){
for(int c = 0; c < m1.colLen(); c++){
if(m1(r,c) != m2(r,c)) return false;;
}
}
return true;
}
}
return false;
}
friend bool operator!= (const mMatrix &m1,
const mMatrix &m2){
if(m1._type == m2._type){
if (m1.rowLen()==m2.rowLen()&&
m1.colLen()==m2.colLen()) {
for(int r = 0; r < m1.rowLen(); r++){
for(int c = 0; c < m1.colLen(); c++){
if(m1(r,c) != m2(r,c)) return true;;
}
}
return false;
}
}
return true;
}
friend std::istream & operator>>(std::istream &, mMatrix &);
friend std::ostream & operator<<(std::ostream &, const mMatrix &);
};
inline double &mMatrix::operator()(int row, int col)
{
assert(row >= 0 && row < _rows);
assert(col >= 0 && col < _columns);
return data[row][col];
}
inline const double &mMatrix::operator()(int row, int col) const
{
assert(row >= 0 && row < _rows);
assert(col >= 0 && col < _columns);
return data[row][col];
}
mMatrix operator+(const mMatrix &firstmMatrix, const mMatrix &secondmMatrix);
enum mVecType{
mvtRow_, // horizontal vector Вектор линия
mvtColI // vertical vector Вектор столбец
};
class mVector : public mMatrix
{
public:
mVecType _vType;
mVector(int size, mVecType type = mvtColI) :
mMatrix(((type == mvtColI)?size:1),
((type == mvtRow_)?size:1)),
_vType(type){}
mVector(QVdouble vec, mVecType type = mvtColI) :
mMatrix(((type == mvtColI)?vec.size():1),
((type == mvtRow_)?vec.size():1)
),
_vType(type){
switch (type) {
case mvtRow_:{
data[0] = vec;
}break;
case mvtColI:{
for (int cIndx = 0; cIndx < vec.size(); ++cIndx) {
data[cIndx][0] = vec[cIndx];
}
}break;
}
}
mVector(std::initializer_list<double> args):
mVector(args,mvtColI){}
mVector(mMatrix M) : mMatrix(0,0){
assert((M.colLen() == 1 && M.rowLen() >= 1)||
(M.rowLen() == 1 && M.colLen() >= 1));
if (M.colLen() == 1) {
_vType = mvtColI;
this->resizeAndCopymMatrix(M);
} else if (M.rowLen() == 1){
_vType = mvtRow_;
this->resizeAndCopymMatrix(M);
}
}
mVector(const mVector& V) : mVector(V.toQVd(),V._vType){}
mVector& operator=(const mVector &V){
// Проверка на самоприсваивание
if (this == &V)
return *this;
assert(V.colLen() == 1 || V.rowLen() == 1);
if (V.colLen() == 1 || V.rowLen() == 1) {
mMatrix::operator = (V);
this->_vType = V._vType;
}
return *this;
}
mVector& operator+=(const mVector vec){
return mVector::operator=(mVector::operator+(vec));
}
mVector& operator-=(const mVector vec){
return mVector::operator=(mVector::operator-(vec));
}
mVector& operator*=(const double num){
return mVector::operator=(mVector::operator*(num));
}
mVector& operator/=(const double num){
return mVector::operator=(mVector::operator/(num));
}
mVector& operator=(const mMatrix &M){
if (M.colLen() == 1 || M.rowLen() == 1) {
this->copymMatrix(M);
}
return *this;
}
mVector operator+(const mVector &);
mVector operator-(const mVector &);
mVector operator*(const double &);
mVector operator/(const double &);
double dot(const mVector vec)const;
int len()const{return (_vType == mvtRow_)?colLen():rowLen();}
mVector T(){
mVector transposedV(len(), (_vType==mvtRow_)?mvtColI:mvtRow_);
for (int i = 0; i < len(); ++i) {
transposedV[i]=this->at(i);
}
return transposedV;
}
mMatrix toMatrix()const{
return mMatrix(data);
}
QVdouble toQVd()const {
switch (_vType) {
case mvtRow_:{
return data.at(0);
}break;
case mvtColI:{
QVdouble out(len());
for (int cIndx = 0; cIndx < len(); ++cIndx) {
out[cIndx] = data.at(cIndx).at(0);
} return out;
}break;
}
return {};
}
double at(int i) const {
return (_vType == mvtRow_)?data.at(0).at(i):data.at(i).at(0);
}
double & operator[](int i) {
return (_vType == mvtRow_)?data[0][i]:data[i][0];
}
double operator[](int i) const {
return (_vType == mvtRow_)?data[0][i]:data[i][0];
}
friend mVector operator*(const double num, const mVector &Vec);
friend mVector operator*(const mVector &Vec, const double num);
friend mMatrix operator*(const mMatrix &Matr, const mVector &Vec);
friend mMatrix operator*(const mVector &Vec , const mMatrix &Matr);
friend mMatrix operator*(const mVector &Vec1, const mVector &Vec2);
mVector& fill(double num){
for (int i = 0; i < len(); ++i) {
if (_vType == mvtRow_){
data[0][i] = num;
} else {
data[i][0] = num;
}
}
return *this;
}
};
inline mMatrix mMatrix::solve(mMatrix A, mMatrix B)
{
return A.inv() * B;
}
typedef std::function<double(mVector)> f_x;
#endif // LINALGEBRA_H