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
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
| #include "Matrix.h"
#include <iostream>
// Конструктор с параметрами
// rows - количество строк матрицы (по-умолчанию 1)
// cols - количество столбцов матрицы (по-умолчанию 1)
// fill - значение, которым изначально будет заполнена матрица (по-умолчанию 0)
Matrix::Matrix(unsigned rows, unsigned cols, double fill):
// устанавливаем размеры матрицы
_rows(rows),
_cols(cols)
{
// Выделяем память под массив строк
_matrix = new Row [_rows];
// Устанавливаем необходимы размер для каждой строки
// и заполняем матрицу желаемым значением
for (unsigned i = 0; i < _rows; ++i)
_matrix[i].resize(_cols, fill);
}
// Конструктор копирования
Matrix::Matrix(const Matrix &original):
// Устанавливаем размеры матрицы
_rows(original._rows),
_cols(original._cols)
{
// Выделяем память под массив строк
_matrix = new Row [_rows];
// Каждую строку новой матрицы
// инициализируем соответствующей
// строкой матрицы original
for (unsigned i = 0; i < _rows; ++i)
_matrix[i] = original._matrix[i];
}
// Деструктор
Matrix::~Matrix()
{
// Удаляем память, отведуннёю под массив строк
delete [] _matrix;
}
// Функция изменения резмера матрицы
void Matrix::resize(unsigned rows, unsigned cols, double fill)
{
// Если исходные размеры матрицы
// не совпадают с желаемыми
if (_rows != rows || _cols != cols)
{
// Освобождаем память из-под исходной матрицы
delete [] _matrix;
// Устанавливаем размеры матрицы
// равными желаемому
_rows = rows;
_cols = cols;
// Выделяем память под матрицу нового размера
_matrix = new Row [_rows];
}
// Устанавливаем необходимы размер для каждой строки
// и заполняем матрицу желаемым значением
for (unsigned i = 0; i < _rows; ++i)
_matrix[i].resize(_cols, fill);
}
// Функция, вычисляющая определитель матрицы
// Используется метод Гаусса-Жордана. Суть метода состоит в
// том, что если из данной матрицы получить с помощью элементарных
// преобразований верхнюю треугольную, то определитель исходной
// матрицы будет равен произведению элементов на главной диагонали
// полученной матрицы.
// Используются следующие свойства определителя:
// 1. Определитель не изменится, если к элементам одного ряда
// прибавить элементы другого ряда, умноженные на произвольное
// число
// 2. При перестановке двух параллельных рядов определитель
// меняет знак
double Matrix::det() const
{
Matrix copy(*this); // Копия исходной матрицы
double result = 1.0; // Результат
unsigned dim = copy._rows; // Размерность матрицы
int sign = 1; // Знак определителя
bool key = true; // Вспомогательная переменная - индикатор,
// была ли найдена строка с ненулевым элементом
// в k-ом столбце
// Дальнейшие действия выполняются, только если
// исходная матрица - квадратная
if (copy._rows == copy._cols)
{
// Проходим по строкам матрицы (назовём их исходными)
for (unsigned k = 0; k < dim; ++k)
{
// Если элемент на главной диагонали в исходной
// строке - нуль, то ищем строку, где элемент
// того же столбца не нулевой, и меняем строки
// местами, а так же (исходя из свойства 2
// определителя), меняем знак результата на
// противоположный, или, если такую строку
// найти не удалось - определитель равен нулю
// и функция завершает работу
if (copy._matrix[k][k] == 0.0)
{
// Изначально устанавливаем индикатор
// в положение "Не найдено"
key = false;
// Идём по строкам, расположенным ниже исходной
for (unsigned i = k + 1; i < dim; ++i)
{
// Если нашли строку, где в том же столбце
// имеется не нулевой элемент
if (copy._matrix[i][k] != 0.0)
{
// Устанавливаем индикатор в положение "Найдено"
key = true;
// Меняем найденную и исходную строки местами
swap(copy._matrix[k], copy._matrix[i]);
// Меняем знак результата
sign *= -1;
break;
}
}
}
// Если на каком-то этапе не нашли столбца с ненулевыми элементами
// ниже k-ой позиции - определитель равен нулю
if (!key)
return 0.0;
// Идём по строкам, которые расположены ниже исходной
for (unsigned i = k + 1; i < dim; ++i)
{
// Запоминаем множитель - отношение элемента очередной
// строки, расположенного под диагональным элементом
// исходной строки, к диагональному элементу исходной
// строки (для того, чтобы постепенно формировать
// верхнетреугольную матрицу, ведь на каждом шаге
// внешнего цикла по k внутри данного цикла будет
// зануляться столбец элементов, расположенных
// ниже диагонального)
double multi = copy._matrix[i][k] / copy._matrix[k][k];
// Отнимаем от очередной строки исходную, умноженную
// на сохранённый ранее множитель
for (unsigned j = 0; j < dim; ++j)
copy._matrix[i][j] -= multi * copy._matrix[k][j];
}
// Добавляем к результату очередное вычисленное значение
// на главной диагонали, поскольку оно больше не изменится
result *= copy._matrix[k][k];
}
}
else
return 0.0;
// Окончательно формируем результат с учётом получившегося знака
return sign * result;
}
// Функция, вычисляющая обратную матрицу
// Используется метод Гаусса-Жордана. Суть метода состоит в
// том, что если из данной матрицы получить с помощью
// элементарных преобразований единичную, а затем все те же
// преобразования применить к единичной матрице, то полученная
// на месте единичной матрица будет обратной матрицей для
// исходной.
Matrix Matrix::inverse() const
{
Matrix E(_rows, _rows); // Единичная матрица
Matrix copy(*this); // Копия исходной матрицы
unsigned dim = _rows; // Размернойсть матрицы
// Все дальнейшие действия выполняются,
// только если определитель исходной
// матрицы не равен нулю
if (det() != 0.0)
{
// Формируем единичную матрицу из нулевой
// добавлением единиц на главную диагональ
for (unsigned i = 0; i < dim; ++i)
E._matrix[i][i] = 1.0;
// Проходим по строкам матрицы (назовём их исходными)
// сверху вниз. На данном этапе происходит прямой ход
// и исходная матрица превращается в верхнюю треугольную
for (unsigned k = 0; k < dim; ++k)
{
// Если элемент на главной диагонали в исходной
// строке - нуль, то ищем строку, где элемент
// того же столбца не нулевой, и меняем строки
// местами
if (copy._matrix[k][k] == 0.0)
{
// Идём по строкам, расположенным ниже исходной
for (unsigned i = k + 1; i < dim; ++i)
{
// Если нашли строку, где в том же столбце
// имеется не нулевой элемент
if (copy._matrix[i][k] != 0.0)
{
// Меняем найденную и исходную строки местами
// как в исходной матрице, так и в единичной
swap(copy._matrix[k], copy._matrix[i]);
swap(E._matrix[k], E._matrix[i]);
break;
}
}
}
// Запоминаем делитель - диагональный элемент
double div = copy._matrix[k][k];
// Все элементы исходной строки делим на диагональный
// элемент как в исходной матрице, так и в единичной
for (unsigned j = 0; j < dim; ++j)
{
copy._matrix[k][j] /= div;
E._matrix[k][j] /= div;
}
// Идём по строкам, которые расположены ниже исходной
for (unsigned i = k + 1; i < dim; ++i)
{
// Запоминаем множитель - элемент очередной строки,
// расположенный под диагональным элементом исходной
// строки
double multi = copy._matrix[i][k];
// Отнимаем от очередной строки исходную, умноженную
// на сохранённый ранее множитель как в исходной,
// так и в единичной матрице
for (unsigned j = 0; j < dim; ++j)
{
copy._matrix[i][j] -= multi * copy._matrix[k][j];
E._matrix[i][j] -= multi * E._matrix[k][j];
}
}
}
// Проходим по вернхней треугольной матрице, полученной
// на прямом ходе, снизу вверх
// На данном этапе происходит обратный ход, и из исходной
// матрицы окончательно формируется единичная, а из единичной -
// обратная
for (unsigned k = dim - 1; k > 0; --k)
{
// Идём по строкам, которые расположены выше исходной
for (unsigned i = k - 1; i + 1 > 0; --i)
{
// Запоминаем множитель - элемент очередной строки,
// расположенный над диагональным элементом исходной
// строки
double multi = copy._matrix[i][k];
// Отнимаем от очередной строки исходную, умноженную
// на сохранённый ранее множитель как в исходной,
// так и в единичной матрице
for (unsigned j = 0; j < dim; ++j)
{
copy._matrix[i][j] -= multi * copy._matrix[k][j];
E._matrix[i][j] -= multi * E._matrix[k][j];
}
}
}
}
// Иначе, если определитель исходной матрицы
// равен нулю, изменяем матрицу E так, чтобы
// она имела одну строку и один столбец, т.е.
// единственный элемент со значением 0
else
E.resize();
// Возвращаем полученную на месте единичной
// обратную матрицу или нуль в случае, если
// обратной для данной матрицы не существует
return E;
}
// Функция, вычисляющая ранг матрицы
// Используется метод элементарных преобразований.
// Суть метода состоит в том, что если из данной матрицы
// получить с помощью элементарных преобразований трапециевидную,
// а затем в полученной матрице посчитать количество нулевых строк
// и отнять его от общего количества строк, то в результате получим
// ранг матрицы
int Matrix::rang() const
{
Matrix copy(*this); // Копия исходной матрицы
int count = 0; // Количество нулевых строк
bool key = true; // Вспомогательная переменная - индикатор,
// была ли найдена строка с ненулевым элементом
// в k-ом столбце. Также служит для определения
// того, является ли строка матрице нулевой
// (на заключительном этапе)
// Проходим по строкам матрицы (назовём их исходными)
// сверху вниз и приводим матрицу к трапециевидной
for (unsigned k = 0; k < _rows; ++k)
{
// Если элемент на главной диагонали в исходной
// строке - нуль, то ищем строку, где элемент
// того же столбца не нулевой, и меняем строки
// местами, или, если такую строку найти не удалось,
// прерываем цикл
if (copy._matrix[k][k] == 0.0)
{
// Изначально устанавливаем индикатор
// в положение "Не найдено"
key = false;
// Идём по строкам, расположенным ниже исходной
for (unsigned i = k + 1; i < _rows; ++i)
{
// Если нашли строку, где в том же столбце
// имеется не нулевой элемент
if (copy._matrix[i][k] != 0.0)
{
// Устанавливаем индикатор в положение "Найдено"
key = true;
// Меняем найденную и исходную строки местами
swap(copy._matrix[k], copy._matrix[i]);
break;
}
}
}
// Если на каком-то этапе не нашли столбца с ненулевыми элементами
// ниже k-ой позиции - прерываем цикл
if (!key)
break;
// Идём по строкам, которые расположены ниже исходной
for (unsigned i = k + 1; i < _rows; ++i)
{
// Запоминаем множитель - элемент очередной строки,
// расположенный под диагональным элементом исходной
// строки, делённый на диагональный элемент исходной
// строки
double multi = copy._matrix[i][k] / copy._matrix[k][k];
// Отнимаем от очередной строки исходную, умноженную
// на сохранённый ранее множитель
for (unsigned j = 0; j < _cols; ++j)
copy._matrix[i][j] -= multi * copy._matrix[k][j];
}
}
// Считаем количество нулевых строк
for (unsigned i = 0; i < _rows; ++i)
{
// Изначально ключ нулевой строки
// устанавливаем в положение "Нулевая"
key = false;
// Если при проходе по строке встретился
// ненулевой элемент, устанавливаем ключ
// в положение "Не нулевая"
for (unsigned j = 0; j < _cols; ++j)
if (copy._matrix[i][j] != 0.0)
key = true;
// Если после прохода по строке ключ остался
// в положении "Нулевая", увеличиваем счётчик
// нулевых строк
if (!key)
count++;
}
// Возвращаем ранг матрицы - результат вычитания
// из общего количества строк количества нулевых
// строк, полученных после элементарных преобразований
// исходной матрицы
return _rows - count;
}
// Функция транспонирования матрицы
Matrix Matrix::transpose() const
{
Matrix result(this->_cols, this->_rows); // Результирующая матрица, размеры которой
// противоположны размерам исходной матрицы
// В цикле идём по всем элементам исходной матрицы
// и записываем их на места соответствующих элементов
// результирующей матрицы (в результирующей матрице в
// итоге будут элементы исходной матрицы, отражённые
// относительно главной диагонали)
for (unsigned i = 0; i < _cols; ++i)
for (unsigned j = 0; j < _rows; ++j)
result._matrix[i][j] = _matrix[j][i];
// Возвращаем результат транспонирования
return result;
}
// Перегруженный оператор взятия строки по индексу
Row &Matrix::operator[](unsigned index)
{
// Возвращаем ссылку на желаемую строку
return _matrix[index];
}
// Перегруженный оператор взятия строки по индексу (константный)
const Row &Matrix::operator[](unsigned index) const
{
// Возвращаем константную ссылку на желаемую строку
return _matrix[index];
}
// Перегруженный оператор вывода из потока input
std::istream &operator>>(std::istream &input, Matrix &rhs)
{
// Идём по строкам матрицы
for (unsigned i = 0; i < rhs._rows; ++i)
// Вводим очередную строку матрицы
input >> rhs._matrix[i];
// Возвращаем ссылку на поток input
return input;
}
// Перегруженный оператор ввода в поток output
std::ostream &operator<<(std::ostream &output, const Matrix &rhs)
{
// Идём по строкам матрицы
for (unsigned i = 0; i < rhs._rows; ++i)
// Выводим очередную строку матрицы
output << rhs._matrix[i] << std::endl;
// Возвращаем ссылку на поток output
return output;
}
// Перегруженный оператор сложения матриц, результат отдельно
Matrix Matrix::operator+(const Matrix &rhs) const
{
Matrix result(*this); // Результирующая матрица, равна
// изначально первой матрице
// Если количество строк и столбцов первой матрицы
// совпадает с количеством соответственно строк и
// столбцов второй матрицы
if (_rows == rhs._rows && _cols == rhs._cols)
{
// Идём по строкам матрицы
for (unsigned i = 0; i < _rows; ++i)
// Идём по элементам очередной строки
for (unsigned j = 0; j < _cols; ++j)
// Прибавляем к каждому элементу результируещей
// матрицы (который изначально совпадает с
// соответствующим элементом первой матрицы)
// соответствующий элемент второй матрицы
result._matrix[i][j] += rhs._matrix[i][j];
}
// Если размеры левой и правой матриц не совпадают,
// результатом операции сложения будет число 0
else
result.resize();
// Возвращаем результирующую матрицу
return result;
}
// Перегруженный оператор сложения матриц, результат в правой матрице
const Matrix &Matrix::operator+=(const Matrix &rhs)
{
// Сохраняем в правую матрицу результат
// сложения правой и левой матриц посредством
// перегруженной операции сложения матриц
*this = *this + rhs;
return *this;
}
// Перегруженный оператор вычитания матриц, результат отдельно
Matrix Matrix::operator-(const Matrix &rhs) const
{
// Используется уже реализованный оператор
// умножения матрицы на число и оператор
// сложения матриц
return *this + (-1.0) * rhs;
}
// Перегруженный оператор вычитания матриц, результат в левой матрице
const Matrix &Matrix::operator-=(const Matrix &rhs)
{
// Используется уже реализованный оператор
// вычитания матриц
*this = *this - rhs;
return *this;
}
// Перегруженный оператор умножения двух матриц, результат отдельно
Matrix Matrix::operator*(const Matrix &rhs) const
{
Matrix result(_rows, rhs._cols); // Результирующая матрица будет иметь столько же
// строк, сколько и левая матрица, и столько же
// столбцов, сколько правая
// Умножение матриц возможно, только если
// количество столбцов левой матрицы и
// количество строк правой совпадают
if (_cols == rhs._rows)
{
// Идём по строкам левой матрицы
for (unsigned i = 0; i < _rows; ++i)
// Идём по столбцам правой матрицы
for (unsigned j = 0; j < rhs._cols; ++j)
// Идём по столбцам левой (и по строка правой) матрицы
for (unsigned k = 0; k < _cols; ++k)
// Формируем очередной элемент результирующей матрицы
result._matrix[i][j] += _matrix[i][k] * rhs._matrix[k][j];
}
// Если количество столбцов левой и количество
// строк правой матрицы не совпадают, то
// результатом выполнения операции будет
// число 0
else
result.resize();
// Возвращаем результат умножения
return result;
}
// Перегруженный оператор умножения двух матриц, результат в левой матрице
const Matrix &Matrix::operator*=(const Matrix &rhs)
{
// Используется уже реализованный оператор
// умножения матриц
*this = *this * rhs;
return *this;
}
// Перегруженный оператор умножения матрицы на число
// (матрица слева, число справа), результат отдельно
Matrix operator*(const Matrix &lhs, const double rhs)
{
Matrix result(lhs); // Изначально результирующая матрица
// совпадает с исходной
// Каждый элемент исходной матрицы умножаем на требуемое число
for (unsigned i = 0; i < lhs._rows; ++i)
for (unsigned j = 0; j < lhs._cols; ++j)
result._matrix[i][j] *= rhs;
// Возвращаем результирующую матрицу
return result;
}
// Перегруженный оператор умножения матрицы на число
// (матрица слева, число справа), результат в матрице
const Matrix &operator*=(Matrix &lhs, const double rhs)
{
// Используется уже реализованный оператор
// умножения матрицы на число
lhs = lhs * rhs;
return lhs;
}
// Перегруженный оператор умножения матрицы на число
// (матрица справа, число слева), результат отдельно
Matrix operator*(const double lhs, const Matrix &rhs)
{
// Используется уже реализованный оператор
// умножения матрицы на число
return rhs * lhs;
}
// Перегруженный оператор деления матриц (т.е. умножения левой
// матрицы на обратную для правой матрицу), результат отдельно
Matrix Matrix::operator/(const Matrix &rhs) const
{
// Используется уже реализованный оператор умножения
// матриц, а так же функция, находящая обратную матрицу
return *this * rhs.inverse();
}
// Перегруженный оператор деления матриц (т.е. умножения левой
// матрицы на обратную для правой матрицу), результат в левой матрице
const Matrix &Matrix::operator/=(const Matrix &rhs)
{
// Используется уже реализованный оператор деления матриц
*this = *this / rhs;
return *this;
}
// Перегруженный оператор деления матрицы на число (т.е.
// умножение матрицы на обратное число), результат отдельно
Matrix operator/(const Matrix &lhs, const double rhs)
{
// Используется уже реализованный оператор умножения
// матрицы на число
return lhs * (1.0 / rhs);
}
// Перегруженный оператор деления матрицы на число (т.е. умножения
// матрицы на обратное число), результат в матрице
const Matrix &operator/=(Matrix &lhs, const double rhs)
{
// Используется уже реализованный оператор деления
// матрицы на число
lhs = lhs / rhs;
return lhs;
}
// Перегруженный оператор деления числа на матрицу (т.е. умножения
// числа на обратную матрицу), результат отдельно
Matrix operator/(const double lhs, const Matrix &rhs)
{
// Используется уже реализованный оператор умножения
// матрицы на число, а так же функция, находящая
// обратную матрицу
return lhs * rhs.inverse();
}
// Перегруженная операция возведения матрицы в целую степень
// (положительную или отрицательную), результат отдельно
Matrix Matrix::operator^(const int power) const
{
Matrix result(*this); // Изначально в результирующую матрицу копируем исходную
unsigned _power = power > 0 ? power : -power; // Сохраняем абсолютное значение показателя степени
// Продолжаем, только если матрица квадратная
if (_rows == _cols)
{
// Если показатель степени равен нулю, то результирующей матрицей
// будет являться единичная матрица той же размерности, что и исходная
if (_power == 0)
{
// Заполняем результирующую матрицу нулями
result.resize(_rows, _cols, 0.0);
// Устанавливаем единицы на главной диагонали
for (unsigned i = 0; i < _rows; ++i)
result._matrix[i][i] = 1.0;
}
// Если показатель степени ненулевой
else
{
// Возводим матрицу в нужную степень
for (unsigned i = 1; i < _power; ++i)
result *= *this;
// Если исходный показатель был отрицательным,
// обращаем полученную матрицу
if (power < 0)
result = result.inverse();
}
}
// Если матрица неквадратная, результатом выполнения
// операции будет число 0
else
result.resize();
// Возвращаем результат возведения матрицы в степень
return result;
}
// Перегруженная операция возведения матрицы в целую степень
// (положительную или отрицательную), результат в матрице
const Matrix &Matrix::operator^=(const int power)
{
// Используется уже реализованный оператор возведения
// матрицы в целую степень
*this = *this ^ power;
return *this;
}
// Перегруженный оператор сравнения матриц
bool Matrix::operator==(const Matrix &rhs) const
{
// Если размеры матриц не совпадают, то матрицы заведомо не равны
if (_rows != rhs._rows || _cols != rhs._cols)
return false;
// Если на какие-либо строки матриц различаются,
// то матрицы не равны
for (unsigned i = 0; i < _rows; ++i)
if (_matrix[i] != rhs._matrix[i])
return false;
// Если как размеры, так и все элементы матриц совпадают,
// то матрицы равны
return true;
}
// Перегруженный оператор неравенства матриц
bool Matrix::operator!=(const Matrix &rhs) const
{
// Используется уже реализованный оператор сравнения матриц
return !(*this == rhs);
}
// Перегруженный оператор присваивания одной матрицы другой
const Matrix &Matrix::operator=(const Matrix &rhs)
{
// Проверка на самоприсваивание
if (this != &rhs)
{
// Если размеры матриц не совпадают
if (_rows != rhs._rows || _cols != rhs._cols)
{
// Очищаем память из-под старой матрицы
delete [] _matrix;
// Устанавливаем новые размеры
_rows = rhs._rows;
_cols = rhs._cols;
// Выделяем память под новую матрицу
_matrix = new Row [_rows];
// Устанавливаем необходимы размер для каждой строки
for (unsigned i = 0; i < _rows; ++i)
_matrix[i].resize(_cols);
}
// Заполняем новую матрицу элементами из
// присваиваемой
for (unsigned i = 0; i < _rows; ++i)
_matrix[i] = rhs._matrix[i];
}
return *this;
}
// Шаблонная функция обмена двух элементов местами
template< typename T >
void swap(T &a, T &b)
{
// Стандартный обмен переменных местами
T temp = a;
a = b;
b = temp;
} |