使用boost c ++ ublas矩阵和向量类型的元素操作

jho*_*man 7 c++ boost vector matrix linear-algebra

我想在boost矩阵和矢量类型上执行逐元素函数,例如取每个元素的对数,取幂每个元素,应用特殊函数,如gamma和digamma等等(类似于matlab对这些函数的处理应用到矩阵和向量.)

我想编写一个帮助函数,对每个所需函数强制执行此操作就足够了,但这似乎很浪费.

同样,boost wiki提供了一些代码来矢量化标准函数,但这似乎相当复杂.

valarray已被建议,但我想避免在数据类型之间进行转换,因为我需要ublas数据类型用于其他操作(矩阵乘积,稀疏矩阵等)

任何帮助是极大的赞赏.

小智 9

begin1()/ 的使用end1()不起作用,因为它提供了对默认列位置(0)中元素的访问:因此,您只需访问第一列中的所有元素.通过以下方式获得顺序访问更好(在某种意义上,您获得了预期的行为):

std::transform(mat.data().begin(), mat.data().end(),
               mat.data().begin(), boost::math::tgamma) ;
Run Code Online (Sandbox Code Playgroud)

我怀疑这可能是实施不完整的情况.

请享用!


A. *_*evy 3

警告

以下答案是不正确的。请参阅底部的编辑。我保留了原来的答案,以便为那些指出错误的人提供上下文和信任。


我对 boost 库不是特别熟悉,所以可能有更标准的方法来做到这一点,但我认为你可以使用迭代器和 STL转换函数模板来做你想做的事情。uBLAS 库文档的介绍称其类被设计为与 STL 中使用的相同迭代器行为兼容。增强矩阵和向量模板都具有可用于访问各个元素的迭代器。向量有begin()end(),矩阵有begin1(), end1(), begin2(), 和end2()。变1体是列式迭代器,2变体是行式迭代器。有关更多信息,请参阅有关VectorExpressionMatrixExpression的 boost 文档。

使用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);
Run Code Online (Sandbox Code Playgroud)

对于矩阵来说,这基本上是相同的事情,您可以使用迭代器12迭代器系列。您选择使用哪一种取决于矩阵的内存布局是行优先还是列优先。粗略浏览一下 uBLAS 文档后,我相信它可能是其中之一,因此您需要检查代码并确定正在使用哪一个,以便选择最有效的迭代顺序。

matrix<double> mat(30, 30);
.
.
.

std::transform(mat.begin1(), mat.end1(), mat.begin1(), boost::math::tgamma);
Run Code Online (Sandbox Code Playgroud)

作为最后一个参数传递的函数可以是采用单个双精度参数并返回双精度值的函数。它也可以是一个函子

这与您引用的矢量化示例并不完全相同,但看起来它应该非常接近您想要的。


编辑

看来我应该在做出建议之前测试一下我的建议。正如其他人所指出的,“1”和“2”迭代器仅沿着矩阵的单行/列进行迭代。Boost 中的概述文档对此有严重误导。它声称begin1()“返回一个指向矩阵开头的 iterator1”和end1()“返回一个指向矩阵末尾的 iterator1”。如果说“矩阵的一列”而不是“矩阵”,他们会被杀吗?我假设 aniterator1是一个按列迭代器,它将迭代整个矩阵。有关执行此操作的正确方法,请参阅Lantern Rouge 的答案