使用Armadillo库

时间:2016-03-14 09:31:22

标签: c++ armadillo

我有一个带有成员arma::mat(矩阵)的(数据/存储)类,我只想访问该矩阵的一列(arma::colvec),但我不想要在列中创建数据的副本。有没有办法实现这个目标?

我的第一次尝试是使用.col(i),但这会返回一个临时的,因此使用引用不起作用。

使用.colptr(i)不会创建副本,但它也会返回double*而不是vec,所以这会让我的生活变得有点困难。

struct Data
{
    mat A;

    /* constructors etc. */

    // reference to temporary (this is bad)
    const vec& getColumn(const uint i) { return A.col(i); }

    // doesn't create a copy, but doesn't return a vec either
    const double* getColumn2(const uint i) const { return A.colptr(i); }
}

想要这个的原因是该类有向量和矩阵,我想制作统一的getter和setter方法,它们可以访问其中一个向量,或者一个矩阵中的列,具体取决于索引(用于迭代)目的)。

一个例子:

struct Data
{
    mat A;
    vec b;

    // getter
    const vec& operator()(const uint i) const
    {
        if (i == 0)
        {
            return b;
        }
        else if (i == 1)
        {
            // return first column of A
        }
        // etc.
    }

    // setter
    vec& operator()(const uint i)
    {
        // similar to above
    }
}

解决方案

基于answer by zauguin,我找到了以下方法来实现所需的功能:

struct Data
{
    mat A;
    vec b;

    // getter
    subview_col<mat::elem_type> operator()(const uint i)
    {
        if (i == 0)
        {
            return b.col(0);
        }
        else if (i > 0 && i < (1 + A.n_cols()))
        {
            return A.col(i - 1);
        }
        else
        {
            // should probably do some error checking here
        }
    }

    // setter
    vec& operator()(const uint i)
    {
        // same as the above, but without consts in declaration
    }
}

这会返回subview_col<mat::elem_type>而不是vec,但功能与我的目的相似/相同。我不确定在.col(0)上使用vec对性能的影响,但我并不担心。

1 个答案:

答案 0 :(得分:2)

在arma中,A.col(i)不会返回引用,而是临时引用。您可以返回此临时值以获取引用语义。使用C ++ 14,只需编写

//...
.map(t => generatePairs(...))
.flatMap(pair => pair.map(x => x -> 1))
.reduceByKey((x, y) => x + y)
//...

否则,您必须返回代理类型,它是

    auto getColumn(const uint i) { return A.col(i); }

如果您必须返回 subview_col<mat::elem_type> getColumn(const uint i) { return A.col(i); } 而不是vec,则可以使用subview_col<...>,但您必须确保不要尝试使用它在A.unsafe_col(i)的生命周期结束后。 see here