警告
以下答案不正确。请参阅底部的编辑。我保留了原始答案,以便为指出错误的人提供上下文和信誉。
我对 boost 库不是特别熟悉,所以可能有更标准的方法可以做到这一点,但我认为你可以使用迭代器和 STL转换函数模板做你想做的事。uBLAS 库文档的介绍说它的类被设计为与 STL 中使用的相同迭代器行为兼容。boost 矩阵和向量模板都有迭代器,可用于访问各个元素。向量有begin()
和end()
,矩阵有begin1()
、end1()
、begin2()
和end2()
。品种是按列的1
迭代器,2
品种是按行的迭代器。请参阅VectorExpression上的 boost 文档和MatrixExpression了解更多信息。
使用 STLtransform
算法,您可以将函数应用于可迭代序列的每个元素,并将结果分配给具有相同长度或相同序列的不同可迭代序列。因此,要在 boost 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);
作为最后一个参数传递的函数可以是一个接受单个双精度参数并返回双精度值的函数。它也可以是函子。
这与您引用的矢量化示例并不完全相同,但它似乎应该非常接近您想要的。
编辑
看起来我应该在提出建议之前测试一下我的建议。正如其他人所指出的,“1”和“2”迭代器仅沿矩阵的单行/列进行迭代。Boost 中的概述文档在这方面存在严重误导。它声称begin1()
“返回指向矩阵开头的 iterator1”和end1()
“返回指向矩阵末尾的 iterator1”。说“矩阵的一列”而不是“矩阵”会杀死他们吗?我假设 aniterator1
是一个按列迭代的迭代器,它将迭代整个矩阵。有关执行此操作的正确方法,请参阅Lantern Rouge 的回答。