#include <vector>
#include <iostream>
#include <initializer_list>
using namespace std;
/**
************************************************
* Matrix of float, implementation with vector<>
************************************************
*/
class Matrix {
// ==============================================
// data members
// ==============================================
protected:
int n_rows; // number of rows
int n_cols; // number of columns
typedef vector<float> RowType; // Type of a row
vector<RowType> rows;
public:
// counters
static int n_cons_calls, n_copy_calls, n_assign_calls,
n_destr_calls;
// ==============================================
// methods
// ==============================================
public:
// ------------------------------------------
// constructor with number of rows and columns
// ------------------------------------------
Matrix(int r, int c) {
n_rows = r;
n_cols = c;
for (int y = 0; y < n_rows; ++y) {
rows.push_back(RowType(n_cols));
}
++n_cons_calls;
}
// ------------------------------------------
// constructor with initializer list
// the first two values represent the number of rows and columns
// ------------------------------------------
Matrix(initializer_list<float> l) {
auto it = l.begin();
n_rows = static_cast<int>(*it++);
n_cols = static_cast<int>(*it++);
//cerr << n_rows << endl;
//cerr << n_cols << endl;
for (int y = 0; y < n_rows; ++y) {
rows.push_back(RowType(n_cols));
}
for (int y = 0; y < n_rows; ++y) {
for (int x = 0; x < n_cols; ++x) {
rows[y][x] = *it++;
}
}
++n_cons_calls;
}
// ------------------------------------------
// destructor
// ------------------------------------------
~Matrix() {
rows.clear();
++n_destr_calls;
}
// ------------------------------------------
// copy constructor
// ------------------------------------------
Matrix(const Matrix& m) {
n_cols = m.n_cols;
for (int y = 0; y < n_rows; ++y) {
rows.push_back(m.rows[y]);
}
++n_copy_calls;
}
// ------------------------------------------
// assignment operator
// ------------------------------------------
Matrix& operator=(const Matrix& m) {
if (&m != this) {
rows.clear();
n_rows = m.n_rows;
n_cols = m.n_cols;
for (int y = 0; y < n_rows; ++y) {
rows.push_back(m.rows[y]);
}
}
++n_assign_calls;
return *this;
}
// ------------------------------------------
// subscript operator definition to access row
// ------------------------------------------
RowType& operator[](int y) {
return rows[y];
}
// ------------------------------------------
// set or get element using operator ()
// ------------------------------------------
float& operator()(int y, int x) {
return rows[y][x];
}
// ------------------------------------------
// set element
// ------------------------------------------
void set(int y, int x, float v) {
rows[y][x] = v;
}
// ------------------------------------------
// gete element
// ------------------------------------------
float get(int y, int x) {
return rows[y][x];
}
// ------------------------------------------
// addition operator as friend
// ------------------------------------------
friend Matrix operator+(const Matrix& a, const Matrix& b) {
Matrix m(a.n_rows, a.n_cols);
for (int y = 0; y < a.n_rows; ++y) {
for (int x = 0; x < a.n_cols; ++x) {
m.rows[y][x] = a.rows[y][x] + b.rows[y][x];
}
}
return m;
}
// ------------------------------------------
// multiplication operator as friend
// ------------------------------------------
friend Matrix operator*(const Matrix& a, const Matrix& b) {
Matrix m(a.n_rows, b.n_cols);
for (int y = 0; y < a.n_rows; ++y) {
for (int x = 0; x < b.n_cols; ++x) {
float sum = 0.0;
for (int k = 0; k < a.n_cols; ++ k) {
sum += a.rows[y][k] * b.rows[k][x];
}
m.rows[y][x] = sum;
}
}
return m;
}
// ------------------------------------------
// print
// ------------------------------------------
ostream& print(ostream& out) {
for (int y = 0; y < n_rows; ++y) {
for (int x = 0; x < n_cols; ++x) {
out.width(7);
out << rows[y][x] << " ";
}
out << endl;
}
return out;
}
friend ostream& operator<<(ostream& out, Matrix& m) {
return m.print(out);
}
};
int Matrix::n_cons_calls = 0;
int Matrix::n_copy_calls = 0;
int Matrix::n_assign_calls = 0;
int Matrix::n_destr_calls = 0;
int main() {
// creates matrices
Matrix a({ 3, 3, 1, 2, 3, 4, 2, 0, -5, 0, -1});
Matrix b({ 3, 3, 8, 2, -1, 7, 3, -4, -2, 0, 3});
Matrix c({ 2, 3, 1, 0, -1, -2, 1, 0});
Matrix d({ 2, 2, 0.5, -0.4, 0.2, -0.3});
Matrix e(2,2);
// modify element
a[2][2] = 99;
// or
a(2,2) = 99;
// perform calculation
e = d * c * (a + b);
cout << e << endl;
cerr << "a, b and c will not be modified" << endl;
cerr << " constructor calls = " << Matrix::n_cons_calls << endl;
cerr << " destructor calls = " << Matrix::n_destr_calls << endl;
cerr << "copy constructor calls = " << Matrix::n_copy_calls << endl;
cerr << " assignment calls = " << Matrix::n_assign_calls << endl;
cerr << a << endl;
cerr << b << endl;
cerr << c << endl;
cerr << d << endl;
}