![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
uBLAS operations overviewBoost , ,
|
A, B, C |
являются матрицами |
u, v, w |
являются векторами |
i, j, k |
являются целыми значениями |
t, t1, t2 |
скалярные значения |
r, r1, r2 |
диапазоны, например диапазон(0, 3) |
s, s1, s2 |
slices, например slice(0, 1, 3) |
C = A + B; C = A - B; C = -A;
w = u + v; w = u - v; w = -u;
C = t * A; C = A * t; C = A / t;
w = t * u; w = u * t; w = u / t;
C += A; C -= A;
w += u; w -= u;
C *= t; C /= t;
w *= t; w /= t;
t = inner_prod(u, v);
C = outer_prod(u, v);
w = prod(A, u); w = prod(u, A); w = prec_prod(A, u); w = prec_prod(u, A);
C = prod(A, B); C = prec_prod(A, B);
w = element_prod(u, v); w = element_div(u, v);
C = element_prod(A, B); C = element_div(A, B);
w = conj(u); w = real(u); w = imag(u);
C = trans(A); C = conj(A); C = herm(A); C = real(A); C = imag(A);
t = norm_inf(v); i = index_norm_inf(v);
t = norm_1(v); t = norm_2(v);
t = norm_inf(A); i = index_norm_inf(A);
t = norm_1(A); t = norm_frobenius(A);
axpy_prod(A, u, w, true); // w = A * u
axpy_prod(A, u, w, false); // w += A * u
axpy_prod(u, A, w, true); // w = trans(A) * u
axpy_prod(u, A, w, false); // w += trans(A) * u
axpy_prod(A, B, C, true); // C = A * B
axpy_prod(A, B, C, false); // C += A * B
Примечание: Последний аргумент (bool init
) axpy_prod
является необязательным. В настоящее время он по умолчанию истинно
, но это может измениться в будущем. Настройка init
на true
эквивалентна вызову w.clear()
перед axpy_prod
. Существует некоторая специализация для продуктов сжатых матриц, которые дают большую скорость по сравнению с prod
.
w = block_prod<matrix_type, 64> (A, u); // w = A * u
w = block_prod<matrix_type, 64> (u, A); // w = trans(A) * u
C = block_prod<matrix_type, 64> (A, B); // C = A * B
Примечание: Блокиз может быть любым целым числом. Однако фактическая скорость очень сильно зависит от комбинации блоков, процессора и компилятора. Функция block_prod
предназначена для больших плотных матриц.
opb_prod(A, B, C, true); // C = A * B
opb_prod(A, B, C, false); // C += A * B
Примечание: Последний аргумент (bool init
) opb_prod
является необязательным. В настоящее время он по умолчанию истинно
, но это может измениться в будущем. Эта функция может дать ускорение, если A
имеет меньше столбцов, чем строк, потому что продукт вычисляется как сумма внешних продуктов.
Доступ к субматрицам и субвекторам через proxies с использованием функций project
:
w = project(u, r); // the subvector of u specifed by the index range r
w = project(u, s); // the subvector of u specifed by the index slice s
C = project(A, r1, r2); // the submatrix of A specified by the two index ranges r1 and r2
C = project(A, s1, s2); // the submatrix of A specified by the two index slices s1 and s2
w = row(A, i); w = column(A, j); // a row or column of matrix as a vector
Назначение субматриц и субвекторов через proxies с использованием функций project
:
project(u, r) = w; // assign the subvector of u specifed by the index range r
project(u, s) = w; // assign the subvector of u specifed by the index slice s
project(A, r1, r2) = C; // assign the submatrix of A specified by the two index ranges r1 and r2
project(A, s1, s2) = C; // assign the submatrix of A specified by the two index slices s1 and s2
row(A, i) = w; column(A, j) = w; // a row or column of matrix as a vector
Примечание: Диапазон r = диапазон (старт, стоп)
содержит все индексы i
с старт <= i<стоп
. Срез — это нечто более общее. Срез s = срез (старт, шаг, размер)
содержит индексы start, start+stride, ..., start+(size-1)*stride
. Шаг может быть 0 или отрицательным! Если start >= stop
для диапазона или size == 0
для среза, то он не содержит элементов.
Поддиапазоны и подсрезы векторов и матриц могут быть созданы непосредственно с функциями subrange
и sublice
:
w = subrange(u, 0, 2); // the 2 element subvector of u
w = subslice(u, 0, 1, 2); // the 2 element subvector of u
C = subrange(A, 0,2, 0,3); // the 2x3 element submatrix of A
C = subslice(A, 0,1,2, 0,1,3); // the 2x3 element submatrix of A
subrange(u, 0, 2) = w; // assign the 2 element subvector of u
subslice(u, 0, 1, 2) = w; // assign the 2 element subvector of u
subrange(A, 0,2, 0,3) = C; // assign the 2x3 element submatrix of A
subrange(A, 0,1,2, 0,1,3) = C; // assigne the 2x3 element submatrix of A
Существует несколько способов доступа к некоторым матричным элементам в качестве вектора:
matrix_vector_range<matrix_type> (A, r1, r2);
matrix_vector_slice<matrix_type> (A, s1, s2);
Примечание: Эти прокси матрицы берут последовательность элементов матрицы и позволяют получить доступ к ним в качестве вектора. В частности, matrix_vector_slice
может сделать это очень общим способом. matrix_vector_range
менее полезен, так как элементы должны лежать по диагонали.
Пример: Чтобы получить доступ к первым двум элементам подколонки матрицы, мы получаем доступ к строке с срезом с шагом 1 и столбцу с срезом с шагом 0 таким образом:
matrix_vector_slice
Если вы точно знаете, что выражение левой руки и выражение правой руки не имеют общего хранилища, то назначение не имеет сглаживания . Более эффективное назначение может быть указано в этом случае:
noalias(C) = prod(A, B);
Это позволяет избежать создания временной матрицы, которая требуется при обычном назначении. Назначение «ноалии» требует, чтобы левая и правая стороны соответствовали размеру.
Функция доступа к матричным элементам A(i1,i2)
или эквивалентные функции доступа к векторным элементам (v(i) или v[i]
) обычно создают «прокси отдельных элементов» при применении к разреженной матрице или вектору. Эти прокси позволяют получить доступ к элементам без необходимости беспокоиться о неприятных проблемах C++, когда ссылки недействительны.
Эти прокси-элементы могут быть реализованы более эффективно при применении к объектам const
. К сожалению, в C++ нет способа отличить доступ к элементу с левой и правой стороны задания. Чаще всего элементы с правой стороны не будут изменены и поэтому лучше использовать прокси const
. Мы можем сделать это, сделав матрицу или вектор const
перед доступом к его элементам. Например:
value = const_cast<const VEC>(v)[i]; // VEC is the type of V
Если необходимо получить доступ к более чем одному элементу const_iterator
, то по этой же причине следует использовать элемент iterator
. Для более смелых «прокси-элементов» можно полностью отключить в uBLAS, определив конфигурационный макрос BOOST_UBLAS_NO_ELEMENT_PROXIES
.
Какая сложность (количество операций сложения и умножения) требуется для вычисления следующего?
R = prod(A, prod(B,C));
Во-первых, сложность зависит от размера матрицы. Кроме того, поскольку prod является транзитивным (не коммутативным), порядок скобок влияет на сложность.
uBLAS оценивает выражения без матрицы или векторных временных интервалов и соблюдает структуру скобки. Однако избегание временных рамок для вложенного продукта излишне увеличивает сложность. С другой стороны, используя временные матрицы, сложность вложенного продукта может быть уменьшена.
uBLAS предоставляет 3 альтернативных синтаксиса для этой цели:
temp_type T = prod(B,C); R = prod(A,T); // Preferable if T is preallocated
prod(A, temp_type(prod(B,C));
prod(A, prod<temp_type>(B,C));
Важное значение имеет «темп_тип». А, В, С – все они одного типа. Скажем, matrix
Авторское право (©) 2000-2007 Йорг Уолтер, Матиас Кох, Гюнтер Уинклер, Майкл Стивенс
На использование, модификацию и распространение распространяется лицензия Boost Software License, Version 1.0. (См. сопроводительный файл LICENSE_1_0.txt или копию по адресу ) http://www.boost.org/LICENSE_1_0.txt .
Статья uBLAS operations overview раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: ::
реклама |