11.15. Реализация статической матрицы
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] << " ";
}
cout << endl;
}
template<class Matrix_T>
void initializeMatrix(Matrix_T& m) {
int k = 0;
for (int i=0; i < m.rows(); ++i) {
for (int j=0; j < m.cols(); ++j) {
m[i][j] = k++;
}
}
}
template<class Matrix_T>
void outputMatrix(Matrix_T& m) {
for (int i=0; i < m.rows(); ++i) {
cout << "Row " << i << " = ";
outputRowOrColumn(m.row(i), m.cols());
}
for (int i=0; i < m.cols(); ++i) {
cout << "Column " << i << " = ";
outputRowOrColumn(m.col(i), m.rows());
}
}
int main() {
kmatrix<int, 2, 4> m;
initializeMatrix(m); m *= 2;
outputMatrix(m);
}
Программа примера 11.31 выдает следующий результат.
Row 0 = 0 2 4 6
Row 1 = 8 10 12 14
Column 0 = 0 8
Column 1 = 2 10
Column 2 = 4 12
Column 3 = 6 14
Обсуждение
Представленные в примерах 11.30 и 11.31 определение шаблона класса kmatrix и пример его использования очень напоминают шаблон класса matrix из рецепта 11.14. Единственным существенным отличием является то, что при объявлении экземпляра kmatrix приходится передавать размерности матрицы через параметры шаблона, например;
kmatrix<int 5, 6> m; // объявляет матрицу с пятью строками и шестью
// столбцами
В приложениях многих типов часто требуется, чтобы матрицы имели размерности, известные на этапе компиляции. Передача размера строк и столбцов через параметры шаблона позволяет компилятору легче применять такую оптимизацию, как развертка цикла, встраивание функций и ускорение индексации.
Как и рассмотренный ранее шаблон статического вектора (kvector), шаблон kmatrix особенно эффективен при небольших размерах матрицы.
Смотри также
Рецепты 11.14 и 11.16.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Понятие статической и динамической веб-страницы
Понятие статической и динамической веб-страницы Ранее мы уже кратко говорили о том, что представляют собой статические и динамические веб-страницы. В данном же разделе мы рассмотрим этот вопрос более детально.Название статической страницы говорит само за себя: на такой
8.1.8. Реализация разреженной матрицы
8.1.8. Реализация разреженной матрицы Иногда бывает нужен массив, в котором определена лишь небольшая часть элементов, а остальные не определены вовсе или (даже чаще) равны 0. Подобная разреженная матрица потребляет так много памяти зря, что были найдены способы более
9.4.1. Реализация графа в виде матрицы смежности
9.4.1. Реализация графа в виде матрицы смежности Нижеприведенный пример основан на двух предыдущих. В листинге 9.3 неориентированный граф реализован в виде матрицы смежности с помощью класса ZArray (см. раздел 8.1.26). Это нужно для того, чтобы новые элементы по умолчанию получали
1.3. Сборка статической библиотеки из командной строки
1.3. Сборка статической библиотеки из командной строки ПроблемаВы хотите использовать свои инструменты командной строки для сборки статической библиотеки из набора исходных файлов С++, таких как перечисленные в примере 1.1.РешениеВо-первых, используйте компилятор для
1.8. Сборка статической библиотеки с помощью Boost.Build
1.8. Сборка статической библиотеки с помощью Boost.Build ПроблемаВы хотите использовать Boost.Build для сборки статической библиотеки из набора исходных файлов С++, таких как перечисленные в примере 1.1.РешениеВ директории, где вы хотите создать статическую библиотеку, создайте файл
1.11. Сборка статической библиотеки с помощью IDE
1.11. Сборка статической библиотеки с помощью IDE ПроблемаВы хотите использовать IDE для сборки статической библиотеки из набора исходных файлов С++, таких как перечисленные в примере 1.1.РешениеОсновная процедура выглядит следующим образом.1. Создайте новый проект и укажите,
11.14. Реализация динамической матрицы
11.14. Реализация динамической матрицы ПроблемаТребуется реализовать числовые матрицы, размерности которых (количество строк и столбцов) неизвестны на этапе компиляции.РешениеВ примере 11.28 показана универсальная и эффективная реализация класса динамической матрицы,
Разрешение матрицы
Разрешение матрицы Мы знаем, что матрица состоит из мельчайших светочувствительных элементов. Количество таких элементов в матрице – это и есть ее разрешение. Разрешение матрицы получают умножением количества элементов по горизонтали и вертикали. Самые
Физический размер матрицы
Физический размер матрицы Выбирая цифровую камеру, неплохо поинтересоваться физическим размером ее матрицы, ведь именно эта характеристика определяет качество камеры. Чем сенсор больше, тем больше он содержит ПЗС-элементов, тем выше его разрешение и, следовательно,
Динамический диапазон матрицы
Динамический диапазон матрицы Динамический диапазон светочувствительной матрицы – это ее способность воспринимать градации каждого из цветов. Говоря проще, динамический диапазон определяет, сколько ступеней разности контраста может увидеть и зафиксировать матрица.
Облет повисшего объекта, или Эффект «Матрицы»
Облет повисшего объекта, или Эффект «Матрицы» Несмотря на современные достижения компьютерной техники, для получения некоторых визуальных эффектов используются старые проверенные методы фотографии. Казалось бы, что общего может иметь фотография с таким современным
12.10. РЕАЛИЗАЦИЯ
12.10. РЕАЛИЗАЦИЯ Обычно на этапе кодирования всплывают все неприятные проблемы, которые только можно себе представить. Чем больше проект, тем больше проблем. Вот почему первые три шага так важны.Если все из вышеописанных шагов полностью пройдены, то реализация программы
Чистка матрицы зеркальной камеры
Чистка матрицы зеркальной камеры У владельцев зеркальных камер к радости от возможности смены объективов прибавляется забота о чистоте матрицы. Что делать, если вы заметили на снимках ровной светлой поверхности соринки и пятна? В некоторых моделях зеркальных камер
Чистка матрицы зеркальной камеры
Чистка матрицы зеркальной камеры В зеркальной камере, в отличие от компактной, приходится чистить матрицу. Хотите вы или нет, но рано или поздно на матрицу попадает пыль, мелкие соринки. Насколько скоро это произойдет, зависит от частоты смены объективов, условий
ТЕМА НОМЕРА: Реформирование матрицы
ТЕМА НОМЕРА: Реформирование матрицы Автор: Леонид Левкович-МаслюкГде-то в конце 1980-х или начале 1990-х я читал в "Независимой газете" обзор событий в мире книг. Автор отмечал, что на прилавках появилось оригинальнейшее сочинение по истории древнего мира, которое написал