ПРЕДУПРЕЖДЕНИЕ
Следующий ответ неверен. Смотрите Редактировать внизу. Я оставил оригинальный ответ, чтобы дать контекст и кредит тем, кто указал на ошибку.
Я не особо знаком с библиотеками boost, поэтому может быть более стандартный способ сделать это, но я думаю, что вы можете делать то, что хотите, с помощью итераторов и шаблона функции STL transform . В введении к документации библиотеки uBLAS говорится, что его классы разработаны так, чтобы быть совместимыми с тем же поведением итератора, которое используется в STL. Матрица усиления и векторные шаблоны имеют итераторы , которые можно использовать для доступа к отдельным элементам. Вектор имеет begin()
и end()
, а матрица имеет begin1()
, end1()
, begin2()
и end2()
. Разновидности 1
являются итераторами по столбцам, а разновидности 2
- итераторами по строкам. См. Дополнительную документацию по VectorExpression и MatrixExpression для получения дополнительной информации.
Используя алгоритм STL transform
, вы можете применить функцию к каждому элементу итерируемой последовательности и назначить результат другой итерируемой последовательности той же длины или той же последовательности. Таким образом, чтобы использовать это для вектора усиления UBLAS, вы можете сделать это:
using namespace boost::numeric::ublas;
// Create a 30 element vector of doubles
vector<double> vec(30);
// Assign 8.0 to each element.
std::fill(vec.begin(), vec.end(), 8.0);
// Perform the "Gamma" function on each element and assign the result back
// to the original element in the vector.
std::transform(vec.begin(), vec.end(), vec.begin(), boost::math::tgamma);
Для матрицы это было бы одно и то же: вы должны использовать итераторы семейства 1
или 2
. Какой из них вы выберете, зависит от того, будет ли структура вашей матрицы основной или основной. Беглый просмотр документации uBLAS заставляет меня поверить, что это может быть любой из них, поэтому вам нужно изучить код и определить, какой из них используется, чтобы выбрать наиболее эффективный порядок итераций.
matrix<double> mat(30, 30);
.
.
.
std::transform(mat.begin1(), mat.end1(), mat.begin1(), boost::math::tgamma);
Функция, которую вы передаете в качестве последнего аргумента, может быть функцией, принимающей один двойной аргумент и возвращающей двойное значение. Это также может быть функтор .
Это не совсем то же самое, что и приведенный вами пример векторизации, но, похоже, он должен быть очень близок к тому, что вы хотите.
EDIT
Похоже, мне следовало проверить свою рекомендацию, прежде чем ее делать. Как указывалось другими, итераторы '1' и '2' выполняют итерацию только по одной строке / столбцу матрицы. Обзорная документация в Boost серьезно вводит в заблуждение по этому поводу. Он утверждает, что begin1()
«Возвращает iterator1, указывающий на начало матрицы», а end1()
«Возвращает iterator1, указывающий на конец матрицы». Разве это убило бы их, чтобы сказать «столбец матрицы» вместо «матрицы»? Я предположил, что iterator1
был итератором по столбцам, который будет перебирать всю матрицу. Чтобы узнать, как это сделать, см. ответ Lantern Rouge .