ΠΡΠΈΠΌΠ΅Ρ 11.28. matrix.hpp
#ifndef MATRIX_HPP
#define MATRIX_HPP
#include "stride_iter.hpp" // ΡΠΌ. ΡΠ΅ΡΠ΅ΠΏΡ 11.12
#include <valarray>
#include <numeric>
#include <algorithm>
template<class Value_T>
class matrix {
public:
// ΠΎΡΠΊΡΡΡΡΠ΅ ΠΈΠΌΠ΅Π½Π°, Π²Π²ΠΎΠ΄ΠΈΠΌΡΠ΅ typedef
typedef Value_T value_type;
typedef matrix self;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef Value_T* row_type;
typedef stride_iter<value_type*> col_type;
typedef const value_type* const_row_type;
typedef stride_iter<const value_type*> const_col_type;
// ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΡ
matrix() : nrows(0), ncols(0), m() {}
matrix(int r, int c) : nrows(r), ncols(c), m(r * Ρ) {}
matrix(const self& x) : m(x.m), nrows(x.nrows), ncols(x.ncols) {}
template<typename T>
explicit matrix(const valarray<T>& x)
: m(x.size() + 1), nrows(x.size()), ncols(1) {
for (int i=0; i<x.size(); ++i) m[i] = x[i];
}
// ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡΡ ΠΊΠΎΠ½ΡΡΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈΠ· ΠΌΠ°ΡΡΠΈΡ Π΄ΡΡΠ³ΠΈΡ ΡΠΈΠΏΠΎΠ²
template<typename T> explicit matrix(const matrix<T>& x)
: m(x.size() + 1), nrows(x.nrows), ncols(x.ncols) {
copy(x.begin(), x.end(), m.begin());
}
// ΠΎΡΠΊΡΡΡΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ
int rows() const { return nrows; }
int cols() const { return ncols; }
int size() const { return nrows * ncols; }
// Π΄ΠΎΡΡΡΠΏ ΠΊ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°ΠΌ
row_type row begin(int n) { return &m[n * cols()]; }
row_type row_end(int n) { return row_begin() + cols(); }
col_type col_begin(int n) { return col_type(&m[n], cols()); }
col_type col_end(int n) { return col_begin(n) + cols(); }
const_row_type row_begin(int n) const { return &m[n * cols()]; }
const_row_type row_end(int n) const { return row_begin() + cols(); }
const_col_type col_begin(int n) const { return col_type(&m[n], cols()); }
const_col_type col_end(int n) const { return col_begin() + cols(); }
iterator begin() { return &m[0]; }
iterator end() { return begin() + size(); }
const_iterator begin() const { return &m[0]; }
const_iterator end() const { return begin() + size(); }
// ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΡ
self& operator=(const self& x) {
m = x.m;
nrows = x.nrows;
ncols = x.ncols;
return *this;
}
self& operator=(value_type x) { m = x; return *this; }
row_type operator[](int n) { return row_begin(n); }
const_row_type operator[](int n) const { return row_begin(n); }
self& operator+=(const self& x) { m += x.m; return *this; }
self& operator-=(const self& x) { m -= x.m; return *this; }
self& operator+=(value_type x) { m += x; return *this; }
self& operator-=(value_type x) { m -= x; return *this; }
self& operator*=(value_type x) { m *= x; return *this; }
self& operator/=(value_type x) { m /= x; return *this; }
self& operator%=(value_type x) { m %= x; return *this; }
self operator-() { return -m; }
self operator+() { return +m; }
self operator!() { return !m; }
self operator~() { return ~m; }
// Π΄ΡΡΠΆΠ΅ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΡ
friend self operator+(const self& x, const self& y) { return self(x) += y; }
friend self operator-(const self& x, const self& y) { return self(x) -= y; }
friend self operator+(const self& x, value_type y) { return self(x) += y; }
friend self operator-(const self& x, value_type y) { return self(x) -= y; }
friend self operator*(const self& x, value type y) { return self(x) *= y; }
friend self operator/(const self& x, value_type y) { return self(x) /= y; }
friend self operator%(const self& x, value_type y) { return self(x) %= y; }
private:
mutable valarray<Value_T> m;
int nrows;
int ncols;
};
#endif
ΠΡΠΈΠΌΠ΅Ρ 11.29 ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅Ρ, ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ°Π±Π»ΠΎΠ½Π½ΡΠΉ ΠΊΠ»Π°ΡΡ matrix.
ΠΡΠΈΠΌΠ΅Ρ 11.29. ΠΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡΠ°Π±Π»ΠΎΠ½Π° matrix
#include "matrix.hpp"
#include <iostream>
using namespace std;
int main() {
matrix<int> m(2,2);
m = 0;
m[0][0] = 1;
m[1][1] = 1;
m *= 2;
cout << "(" << m[0][0] << "," << m[0][1] << ")" << endl;
cout << "(" << m[1][0] << "," << m[1][1] << ")" << endl;
}
ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΠΏΡΠΈΠΌΠ΅ΡΠ° 11.29 Π²ΡΠ΄Π°Π΅Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ.
(2,0)
(0,2)
ΠΠ±ΡΡΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΡΠΎΠ΅ΠΊΡ ΡΠ°Π±Π»ΠΎΠ½Π° ΠΌΠ°ΡΡΠΈΡΡ, ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½Π½ΡΠΉ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ΅ 11.28, Π² Π·Π½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎΠΉ ΡΡΠ΅ΠΏΠ΅Π½ΠΈ ΠΈΠ½ΡΠΏΠΈΡΠΈΡΠΎΠ²Π°Π½ ΡΠ°Π±Π»ΠΎΠ½ΠΎΠΌ ΠΌΠ°ΡΡΠΈΡΡ ΠΡΠ΅ΡΠ½Π° Π‘ΡΡΠ°ΡΡΡΡΡΠΏΠ° (Bjarne Stroustrup) ΠΈΠ· Π΅Π³ΠΎ ΠΊΠ½ΠΈΠ³ΠΈ Β«The C++ Programming LanguageΒ», 3-Π΅ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅ (ΠΈΠ·Π΄Π°ΡΠ΅Π»ΡΡΡΠ²ΠΎ Β«Addison WesleyΒ»). Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Π‘ΡΡΠ°ΡΡΡΡΡΠΏΠ° ΠΎΡΠ»ΠΈΡΠ°Π΅ΡΡΡ ΡΠ΅ΠΌ, ΡΡΠΎ Π΅Π³ΠΎ ΠΈΡΠ΅ΡΠ°ΡΠΎΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ ΠΊΠ»Π°ΡΡ slice ΠΈ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° valarray Π΄Π»Ρ ΠΈΠ½Π΄Π΅ΠΊΡΠ°ΡΠΈΠΈ. Π Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Π°Ρ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ΅ 11.27 ΠΌΠ°ΡΡΠΈΡΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Π²ΠΌΠ΅ΡΡΠΎ Π½ΠΈΡ ΠΈΡΠ΅ΡΠ°ΡΠΎΡ Ρ ΡΠ°Π³ΠΎΠΌ ΠΈΠ· ΡΠ΅ΡΠ΅ΠΏΡΠ° 11.12, ΡΡΠΎ Π΄Π΅Π»Π°Π΅Ρ ΠΈΡΠ΅ΡΠ°ΡΠΎΡΡ Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΠΌΠΏΠ°ΠΊΡΠ½ΡΠΌΠΈ ΠΈ ΠΏΡΠΈ Π½Π΅ΠΊΠΎΡΠΎΡΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡΡ Π±ΠΎΠ»Π΅Π΅ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΡΠΌΠΈ.
Π¨Π°Π±Π»ΠΎΠ½Π½ΡΠΉ ΠΊΠ»Π°ΡΡ matrix ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΈΠ½Π΄Π΅ΠΊΡΠΈΡΠΎΠ²Π°ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½Ρ i-ΠΉ ΡΡΡΠΎΠΊΠΈ ΠΈ j-Π³ΠΎ ΡΡΠΎΠ»Π±ΡΠ°, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ Π΄Π²ΠΎΠΉΠ½ΠΎΠΉ ΠΈΠ½Π΄Π΅ΠΊΡΠ°ΡΠΈΠΈ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ:
matrix<int> m(100,100);
cout << "the element at row 24 and column 42 is " << m[24][42] << endl;
Π¨Π°Π±Π»ΠΎΠ½Π½ΡΠΉ ΠΊΠ»Π°ΡΡ matrix ΡΠ°ΠΊΠΆΠ΅ ΠΈΠΌΠ΅Π΅Ρ ΡΡΠ½ΠΊΡΠΈΠΈ-ΡΠ»Π΅Π½Ρ begin ΠΈ end, Ρ.Π΅. Π΅Π³ΠΎ Π»Π΅Π³ΠΊΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π² ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ Π°Π»Π³ΠΎΡΠΈΡΠΌΠ°Ρ STL.
ΠΡΠΈΠΌΠ΅Ρ 11.28 ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΡΡΡΠΎΠΊΡ, ΠΊΠΎΡΠΎΡΠ°Ρ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π²ΡΠ·ΡΠ²Π°Π΅Ρ Ρ Π²Π°Ρ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠ΅ ΡΠ΄ΠΈΠ²Π»Π΅Π½ΠΈΠ΅. ΠΠΌΠ΅Π΅ΡΡΡ Π² Π²ΠΈΠ΄Ρ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π΅ ΠΎΠ±ΡΡΠ²Π»Π΅Π½ΠΈΠ΅.
mutable valarray<Value_T> m;
ΠΠ±ΡΡΠ²Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ»Ρ-ΡΠ»Π΅Π½Π° m ΡΠΎ ΡΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ mutable Π²ΡΠ½ΡΠΆΠ΄Π΅Π½Π½ΠΎ. Π ΠΏΡΠΎΡΠΈΠ²Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Ρ Π½Π΅ ΠΌΠΎΠ³ Π±Ρ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΡΡ ΠΈΡΠ΅ΡΠ°ΡΠΎΡΡ ΡΠΎ ΡΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ const, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ Π½Π΅Π»ΡΠ·Ρ ΡΠΎΠ·Π΄Π°ΡΡ ΠΈΡΠ΅ΡΠ°ΡΠΎΡ Π΄Π»Ρ const valarray.
Π‘ΠΌΠΎΡΡΠΈ ΡΠ°ΠΊΠΆΠ΅Π Π΅ΡΠ΅ΠΏΡΡ 11.15 ΠΈ 11.16.
11.15. Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΠΌΠ°ΡΡΠΈΡΡ
Π’ΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΠΌΠ°ΡΡΠΈΡΡ, ΠΊΠΎΠ³Π΄Π° Π΅Π΅ ΡΠ°Π·ΠΌΠ΅ΡΠ½ΠΎΡΡΡ (Ρ.Π΅. ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΡΡΠΎΠΊ ΠΈ ΡΡΠΎΠ»Π±ΡΠΎΠ²) ΠΏΠΎΡΡΠΎΡΠ½Π½Π° ΠΈ ΠΈΠ·Π²Π΅ΡΡΠ½Π° Π½Π° ΡΡΠ°ΠΏΠ΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ.
Π Π΅ΡΠ΅Π½ΠΈΠ΅ΠΠΎΠ³Π΄Π° ΡΠ°Π·ΠΌΠ΅ΡΠ½ΠΎΡΡΡ ΠΌΠ°ΡΡΠΈΡΡ ΠΈΠ·Π²Π΅ΡΡΠ½Π° Π½Π° ΡΡΠ°ΠΏΠ΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ, ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ ΠΌΠΎΠΆΠ΅Ρ Π»Π΅Π³ΠΊΠΎ ΠΎΠΏΡΠΈΠΌΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΡΡΠΎΠΊ ΠΈ ΡΡΠΎΠ»Π±ΡΠΎΠ² Π·Π°Π΄Π°Π΅ΡΡΡ Π² Π²ΠΈΠ΄Π΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΡΠ°Π±Π»ΠΎΠ½Π°, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ΅ 11.30.
ΠΡΠΈΠΌΠ΅Ρ 11.30. kmatrix.hpp
#ifndef KMATRIX_HPP
#define KMATRIX_HPP
#include "kvector.hpp"
#include "kstride_iter.hpp"
template<class Value_T, int Rows_N, int Cols_N>
class kmatrix {
public:
// ΠΎΡΠΊΡΡΡΡΠ΅ ΠΈΠΌΠ΅Π½Π°, Π²Π²ΠΎΠ΄ΠΈΠΌΡΠ΅ typedef
typedef Value_T value_type;
typedef kmatrix self;
typedef Value_T* iterator;
typedef const Value_T* const_iterator;
typedef kstride_iter<Value_T*, 1> row_type;
typedef kstride_iter<Value_T*, Cols_N> col_type;
typedef kstride_iter<const Value_T*, 1> const_row_type;
typedef kstride_iter<const Value T*, Cols_N> const_col_type;
// ΠΎΡΠΊΡΡΡΡΠ΅ ΠΊΠΎΠ½ΡΡΠ°Π½ΡΡ
static const int nRows = Rows_N;
static const int nCols = Cols_N;
// ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΡ
kmatrix() { m = Value_T(); }
kmatrix(const self& x) { m = x.m; }
explicit kmatrix(Value_T& x) { m = x.m; }
// ΠΎΡΠΊΡΡΡΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ
static int rows() { return Rows_N; }
static int cols() { return Cols_N; }
row_type row(int n) { return row_type(begin() * (n * Cols_N)); }
col_type col(int n) { return col_type(begin() + n); }
const_row_type row(int n) const {
return const_row_type(begin() + (n * Cols_N));
}
const_col_type col(int n) const {
return const_col_type(begin() + n);
}
iterator begin() { return m.begin(); }
iterator end() { return m.begin() + size(); }
const_iterator begin() const { return m; }
const_iterator end() const { return m + size(); }
static int size() { return Rows_N * Cols_N; }
// ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΡ
row_type operator[](int n) { return row(n); }
const_row_type operator[](int n) const { return row(n); }
// ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΠΏΡΠΈΡΠ²Π°ΠΈΠ²Π°Π½ΠΈΡ
self& operator=(const self& x) { m = x.m; return *this; }
self& operator=(value_type x) { m = x; return *this; }
self& operator+=(const self& x) { m += x.m; return *this; }
self& operator-=(const self& x) { m -= x.m; return *this; }
self& operator+={value_type x) { m += x; return *this; }
self& operator-=(value_type x) { m -= x; return *this; }
self& operator*=(value_type x) { m *= x; return *this; }
self& operator/=(value_type x) { m /= x; return *this; }
self operator-() { return self(-m); }
// Π΄ΡΡΠ·ΡΡ
friend self operator+(self x, const self& Ρ) { return x += y; }
friend self operator-(self x, const self& y) { return x -= y; }
friend self operator+(self x, value_type y) { return x += y; }
friend self operator-(self x, value type y) { return x -= y; }
friend self operator*(self x, value_type y) { return x *= y; }
friend self operator/(self x, value_type y) { return x /= y; }
friend bool operator==(const self& x, const self& y) { return x == y; }
friend bool operator!=(const self& x, const self& y) { return x.m != y.m; }
private:
kvector<Value_T, (Rows_N + 1) * Cols_N> m;
};
#endif
Π ΠΏΡΠΈΠΌΠ΅ΡΠ΅ 11.31 ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ°, Π΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΡΡΡΠ°Ρ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡΠ°Π±Π»ΠΎΠ½Π½ΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ° kmatrix.
ΠΡΠΈΠΌΠ΅Ρ 11.31. ΠΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ kmatrix
#include "kmatrix.hpp"
#include <iostream>
using namespace std;
template<class Iter_T>
void outputRowOrColumn(Iter_T iter, int n) {
for (int i=0; i < n; ++i) {
cout << iter[i] << " ";