|
Программирование >> Разработка устойчивых систем
A именно Blitz (http: www.oonumerics.org/blitz/), Matrix Template Library (http: www.osl.iu.edu/ research/mtl) и РООМА (http: www.acl.lanl.gov/pooma/). Речь идет о векторах в математическом смысле, то есть одномерных числовых массивах фиксированной длины. зировать некоторые виды вычислений и получить код, который по скорости как минимум не уступает вручную оптимизированному коду языка Фортран, но при этом сохраняет естественную математическую запись за счет перегрузки операторов. Хотя вряд ли вы будете использовать эту методику в повседневном программировании, она заложена в основу многих сложных, высокопроизводительных математических библиотек, написанных на С++. Чтобы было понятно, зачем нужны шаблоны выражений, рассмотрим типичные операции линейной алгебры, такие, как сложение матриц или векторов: D = А + В + С: В примитивной реализации этого выражения создаются временные объекты для А + В и (А + В) + С. Если переменные представляют матрицы или векторы очень больших размеров, затраты ресурсов на хранение временных объектов могут оказаться неприемлемыми. Шаблоны выражений позволяют использовать аналогичные выражения без временных объектов. В следующей программе определяется класс MyVector для представления математических векторов произвольного размера. Длина вектора определяется нетиповым аргументом шаблона. Мы таюке определяем промежуточный класс MyVectorSum для хранения суммы объектов MyVector. Это позволяет вьпюлнять отложенные вычисления, чтобы векторы-компоненты можно было добавлять по мере необходимости без создания временных объектов. : СОБ:MyVector.срр Оптимизация посредством шаблонов с исключением временных объектов linclude <cstddef> linclude <cstdlib> linclude <ctime> linclude <iostream> using namespace std: Промежуточный класс для суммы векторов tempiate<class. size t> class MyVectorSum: tempiate<class T. size t N> class MyVector { T data[N]: public: MyVector<T.N>& operator=(const MyVector<T.N>& right) { for (size t i =0: i < N: ++i) data[i] = right.data[i]: return *this: MyVector<T,N>& operator=(const MyVectorSum<T,N>& right): const T& operator[](size t i) const { return data[i]: } T& operator[](size t i) { return data[i]: } Промежуточный класс содержит ссылки и использует отложенное суммирование, template <class Т. size t N> class MyVectorSum { const MyVector<T.N>& left: const MyVector<T.N>& right: public: MyVectorSumCconst MyVector<T.N>& Ihs. const MyVector<T.N>& rhs) : left(lhs). right(rhs) {} T operator[](si2e t i) const { return left[i] + right[i]: Operator- для операций v3 - vl + v2 tempiate<class T, si2e t N> MyVector<T,N>& MyVector<T.N>::operator-(const MyVectorSum<T,N>& right) { for (si2e t i - 0; i < N: ++1) data[i] - right[i]; return *this: Operator+ просто сохраняет ссылки tempiate<class T. sl2e t N> inline MyVectorSu[n<T.N> operator+(const MyVector<T,N>& left. const MyVector<T,N>& right) { return My\/ectorSum<T.N>(left. right): Вспомогательные функции для тестовой программы tempiate<class Т. size t N> void init(tyVector<T.N>& v) { for (si2e t 1 - 0: i < N: ++i) v[i] - randO !i! 100: template<class T. size t N> void pг1nt(tyVectoг<T.N>& v) { for (si2e t 1 - 0: i < N: ++i) cout v[1] : cout endl: int mainO { srand(time(0)): MyVector<int. 5> vl; in1t(vl): prlnt(vl): My\/ector<int. 5> v2: 1nit(v2): pr1nt(v2): My\/ector<1nt. 5> v3; v3 - vl + v2: print(v3): MyVector<1nt. 5> v4: Пока не поддерживается: ! v4 - vl + v2 + v3: } III- Класс MyVectorSum при создании ничего не вычисляет; он просто сохраняет ссылки на два суммируемых объекта. Вычисление производится только при обращении к компоненту суммы векторов (см. операторную функцию operator[]()). Перегрузка оператора присваивания MyVector с аргументом MyVectorSum предназначена для выражений вида vl - v2 + v3: Суммирование двух векторов При вычислении vl + v2 возвращается myVectorSum - компактный объект фиксированного размера, содержащий только две ссылки. Затем вызывается упоминавшийся выше оператор присваивания: v3.operator-<int.5>(MyVectorSum<int.5>(v2. v3)): Тем самым каждому элементу v3 присваивается сумма соответствующих элементов vl и v2, вычисляемая в реальном времени. Временные объекты MyVector при этом не создаются. Однако приведенная программа не поддерживает выражения, содержащие более двух операндов: v4 = vl + v2 + v3: Дело в том, что после первого суммирования делается следующая попытка (vl + v2) + v3: Для нее требуется функция operator+() с аргументами MyVectorSum и аргументом MyVector. Можно определить несколько перегруженных версий для всех случаев, но лучше поручить работу шаблонам, как в следующей версии программы: : C05:MyVector2.cpp Вычисление сумм произвольной длины с использованием шаблонов выражений linclude <cstddef> linclude <cstdlib> linclude <ctime> linclude <iostreani> using namespace std: Промежуточный класс для суммы векторов tempiate<class. si2e t. class. class> class MyVectorSum: tempiate<class T. size t N> class MyVector { T dataCN]: public: MyVector<T.N>& operator=(const MyVector<T.N>& right) { for (si2e t i = 0: i < N: ++i) data[i] = right.data[i]: return *this: tempiate<class Left, class Right> MyVector<T.N>& operator=(const MyVectorSum<T.N.Left.Right>& right): const T& operator[](si2e t i) const { return dataCi]: T& operator[](size t i) { return data[i]: Позволяет смешивать MyVector с MyVectorSum template <class T. size t N. class Left, class Right> class MyVectorSum { const Left& left: const Rights right; public: MyVectorSum(const Left& Ihs. const Right& rhs) : left(lhs). right(rhs) {} T operator[](si2e t i) const { return left[i] + right[i]:
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.002
При копировании материалов приветствуются ссылки. |