33
44// class Matrix
55
6+ // конструктор по умолчанию
67Matrix::Matrix (unsigned int size, double def) {
78 try {
89 if (size > 0 ) {
@@ -22,6 +23,7 @@ Matrix::Matrix(unsigned int size, double def) {
2223 }
2324}
2425
26+ // конструктор от двумерного массива
2527Matrix::Matrix (vector <vector <double >> temp):
2628 Matrix (get_size(temp)) {
2729 arr = temp;
@@ -47,6 +49,8 @@ Matrix& Matrix::set(unsigned int x, unsigned int y, double value) {
4749 return *this ;
4850}
4951
52+ // установить новый двумерный массив в матрицу
53+ // важно чтобы он был того же размера
5054Matrix& Matrix::set (vector <vector <double >> temp) {
5155 // TODO: сделать присваивание матрицы другого разера
5256 try {
@@ -82,17 +86,8 @@ double Matrix::get(unsigned int x, unsigned int y) {
8286 }
8387}
8488
85- void Matrix::print () {
86- for (int y = 0 ; y < arr.size (); y++) {
87- for (int x = 0 ; x < arr[y].size (); x++)
88- cout << arr[y][x] << " " ;
89- cout << endl;
90- }
91- cout << endl;
92- }
93-
94- // other functions
95-
89+ // получение размера двумерного массива (не матрицы)
90+ // если двумерный массив не квадратный - 0
9691unsigned int get_size (vector <vector <double >> arr) {
9792 unsigned int size = arr.size ();
9893 for (int i = 0 ; i < size; i++) {
@@ -103,14 +98,32 @@ unsigned int get_size(vector <vector <double>> arr) {
10398 return size;
10499}
105100
101+ void Matrix::print () {
102+ for (int y = 0 ; y < arr.size (); y++, cout << endl)
103+ for (int x = 0 ; x < arr[y].size (); x++)
104+ cout << arr[y][x] << " " ;
105+ cout << endl;
106+ }
107+
106108// преобразования
107109
110+ // унарный минус (смена знаков элементов)
111+ Matrix operator -(const Matrix &m) {
112+ Matrix temp (m);
113+ for (int x = 0 ; x < temp.arr .size (); x++)
114+ for (int y = 0 ; y < temp.arr .size (); y++)
115+ temp.arr [y][x] *= -1 ;
116+ return temp;
117+ }
118+
108119void swap (double *d1, double *d2) {
109120 double temp = *d1;
110121 *d1 = *d2;
111122 *d2 = temp;
112123}
113124
125+ // транспонирование матрицы
126+ // отзеркаливание относительно главной диагонали
114127Matrix Matrix::transpose () {
115128 Matrix temp (*this );
116129 for (int y = 0 ; y < this ->size () - 1 ; y++) {
@@ -121,6 +134,9 @@ Matrix Matrix::transpose() {
121134 return temp;
122135}
123136
137+ // нахождение минора
138+ // это короче матрица с вычеркнутым столбцом с индексом x
139+ // и вычеркнутой строкой с индексом y
124140Matrix Matrix::minor (int _y, int _x) {
125141 Matrix temp (arr.size () - 1 );
126142 bool skip_x, skip_y = 0 ;
@@ -135,27 +151,26 @@ Matrix Matrix::minor(int _y, int _x) {
135151 return temp;
136152}
137153
154+ // определитель матрицы (рекурсивно)
155+ // два базовых случая и рекурсия для матриц >= 3
138156const double Matrix::determinant () {
139- double det = 0 ;
140157 switch (arr.size ()) {
141- case 1 : {
142- det = arr[0 ][0 ];
143- break ;
144- }
145- case 2 : {
146- det = arr[0 ][0 ] * arr[1 ][1 ] - arr[1 ][0 ] * arr[0 ][1 ];
147- break ;
148- }
149- default : {
150- for (int i = 0 ; i < arr.size (); i++) {
158+ case 1 :
159+ return arr[0 ][0 ];
160+
161+ case 2 :
162+ return arr[0 ][0 ] * arr[1 ][1 ] - arr[1 ][0 ] * arr[0 ][1 ];
163+
164+ default :
165+ double det = 0 ;
166+ for (int i = 0 ; i < arr.size (); i++)
151167 det += (i % 2 ? -1 : 1 ) * arr[i][0 ] * this ->minor (i, 0 ).determinant ();
152- }
153- break ;
154- }
168+ return det;
155169 }
156- return det;
157170}
158171
172+ // матрица миноров
173+ // каждый элемент это определитель минора по индексу этого элемента
159174Matrix Matrix::minor_matrix () {
160175 Matrix temp (arr.size ());
161176 for (int y = 0 ; y < arr.size (); y ++) {
@@ -166,6 +181,8 @@ Matrix Matrix::minor_matrix() {
166181 return temp;
167182}
168183
184+ // матрица алгебраических дополнений
185+ // просто матрица миноров но с переменой знаков по диагонале
169186Matrix Matrix::algebraic_additions () {
170187 Matrix temp = this ->minor_matrix ();
171188 for (int x = 0 ; x < arr.size (); x++) {
@@ -176,6 +193,9 @@ Matrix Matrix::algebraic_additions() {
176193 return temp;
177194}
178195
196+ // обратная матрица (самое сложное)
197+ // надо поделить транспонированую матрицу алгебраических
198+ // дополнений на определитель исходной матрицы
179199Matrix Matrix::inverse () {
180200 Matrix alg_add_T = this ->algebraic_additions ().transpose ();
181201 alg_add_T /= this ->determinant ();
@@ -205,16 +225,12 @@ Matrix& Matrix::operator+=(const Matrix& m) {
205225Matrix& Matrix::operator -=(const Matrix& m) {
206226 try {
207227 if (arr.size () == m.arr .size ()) {
208- for (int x = 0 ; x < m.arr .size (); x++) {
209- for (int y = 0 ; y < m.arr .size (); y++) {
210- arr[y][x] -= m.arr [y][x];
211- }
212- }
228+ *this += -m;
213229 } else {
214230 throw " Matrices have different sizes" ;
215231 }
216232 } catch (const char *s) {
217- cerr << " Error in + operator: " << s << endl;
233+ cerr << " Error in - operator: " << s << endl;
218234 exit (1 );
219235 }
220236 return *this ;
@@ -231,17 +247,26 @@ Matrix operator-(Matrix a, const Matrix& b) {
231247}
232248
233249Matrix& Matrix::operator *=(const Matrix& right) {
234- unsigned int size = this ->size ();
235- Matrix result (size, 0 );
236- for (int result_x = 0 ; result_x < size; result_x++) {
237- for (int result_y = 0 ; result_y < size; result_y++) {
238- double summ = 0 ;
239- for (int i = 0 ; i < size; i++)
240- summ += arr[result_y][i] * right.arr [i][result_x];
241- result.arr [result_y][result_x] = summ;
250+ try {
251+ if (right.arr .size () == arr.size ()) {
252+ unsigned int size = this ->size ();
253+ Matrix result (size, 0 );
254+ for (int result_x = 0 ; result_x < arr.size (); result_x++) {
255+ for (int result_y = 0 ; result_y < arr.size (); result_y++) {
256+ double summ = 0 ;
257+ for (int i = 0 ; i < size; i++)
258+ summ += arr[result_y][i] * right.arr [i][result_x];
259+ result.arr [result_y][result_x] = summ;
260+ }
261+ }
262+ *this = result;
263+ } else {
264+ throw " Matrices have different sizes" ;
242265 }
266+ } catch (const char *s) {
267+ cerr << " Error in * operator: " << s << endl;
268+ exit (1 );
243269 }
244- *this = result;
245270 return *this ;
246271}
247272
@@ -264,16 +289,13 @@ Matrix operator*(Matrix a, const double &b) {
264289 return a;
265290}
266291
292+ // деление матрицы на матрицу
293+
267294Matrix& Matrix::operator /=(const Matrix &b) {
268295 *this *= Matrix (b).inverse ();
296+ // спросить у Линского про оптимизацию этого куска
297+ // лишнее копирование
269298 return *this ;
270-
271- /* поэлементное деление - не гуд
272- for (int x = 0; x < b.arr.size(); x++)
273- for (int y = 0; y < b.arr.size(); y++)
274- arr[y][x] /= b.arr[y][x];
275- return *this;
276- */
277299}
278300
279301Matrix operator /(Matrix a, const Matrix &b) {
@@ -282,6 +304,7 @@ Matrix operator/(Matrix a, const Matrix &b) {
282304}
283305
284306Matrix& Matrix::operator /=(const double & n) {
307+ // не нужно предупреждать о делении на ноль
285308 for (int x = 0 ; x < arr.size (); x++) {
286309 for (int y = 0 ; y < arr.size (); y++) {
287310 arr[y][x] /= n;
0 commit comments