【问题标题】:C++ Armadillo: arrays of indices from 2D-matrixC ++ Armadillo:来自二维矩阵的索引数组
【发布时间】:2018-11-29 16:39:52
【问题描述】:

我来自 Python。我有一个要在 C++ 中处理的线性代数问题,我选择使用 Armadillo 来解决这个问题,因为它宣称自己类似于 MATLAB,因此类似于 SciPy。

我正在寻找一种填充两个矩阵的方法,一个带有行,一个带有给定形状的二维矩阵的列(在 Python 中,这将是 numpy.indices)。

例如,如果我有一个 4 行/3 列的矩阵形状,我想要构建一个行矩阵:

0 0 0
1 1 1
2 2 2
3 3 3

还有一个列矩阵:

0 1 2
0 1 2
0 1 2
0 1 2

为了以后做一些计算。

它类似于C++ Armadillo Generate Indices uvec of a given vec or matrix without looping it,但使用矩阵而不是一维向量。

有没有办法在没有太多循环的情况下做到这一点?我知道 linspace 来填充向量,但我不希望循环一堆向量以将它们合并到矩阵中。我刚开始使用犰狳,我还没有真正意识到它的功能(基本上,我只是要做矩阵产品和求逆)。

【问题讨论】:

    标签: c++ armadillo


    【解决方案1】:

    @茄子。 犰狳 库对于科学计算非常有用且易于上手。我会鼓励通过其文档页面armadillo documentation

    关于您的特定问题,我提出以下解决方案:

    #include<iostream>
    #include<armadillo>
    
    using namespace std;
    using namespace arma;
    
    int main(int argc, char **argv)
    {
        // Create two matrices A and B of shape 4x3 filled with zeros
        imat A = zeros<imat>(4, 3);
        imat B = zeros<imat>(4, 3);
    
        // Fill each row
        for(int i=0; i < 4; i++)
        {
            A.row(i) = i * ones<ivec>(3).t();  // 
        }
    
        // Fill each column
        for(int i=0; i < 3; i++)
        {
            B.col(i) = i * ones<ivec>(4);
        }
        cout << "A = \n" << A << endl;
        cout << "B = \n" << B << endl;
    
        return 0;
    }
    

    在我的电脑(Mac OSX 和 Ubuntu)上编译是这样的:

    g++ -std=c++11 -O2 `pkg-config --cflags --libs armadillo` testArmadillo.cpp -o a.out
    

    然后,我们只需键入以下内容即可运行可执行文件:

    ./a.out
    

    输出如下:

    A =
        0        0        0
        1        1        1
        2        2        2
        3        3        3
    
    B =
        0        1        2
        0        1        2
        0        1        2
        0        1        2
    

    有关imativec的更多信息,请参阅imativec

    【讨论】:

    • 然后循环播放!我看了看文档,但在标准 C++ 方面我也有很多东西要赶上。我使用 umat 而不是 imat 因为我只需要正整数;奇迹般有效。谢谢你:)
    【解决方案2】:

    虽然给出的答案确实生成了请求的矩阵,但 OP 要求提供不使用循环的解决方案。此答案使用 regspace 和 repmat,并且在概念上可能更简单:

    #include <iostream>
    #include <armadillo>
    
    using namespace std;
    using namespace arma;
    
    int main (int argc, char const* argv[])
    {
        ivec a_col = regspace<ivec>(0, 3);
        imat A = repmat(a_col, 1, 3);
    
        irowvec b_row = regspace<irowvec>(0,2);
        imat B = repmat(b_row, 4, 1);
    
        cout << A << endl;
        cout << B << endl;
        return 0;
    }
    

    我不得不承认我对犰狳有点陌生,所以我不能保证这会很快或遵循最佳实践,但我认为它可能最接近等效的 SciPy 代码。

    【讨论】:

    • auto 与犰狳对象一起使用可能会导致问题。犰狳的FAQ page 有更多详细信息。
    • @hbrerkere 我最近才发现这个。谢谢你的澄清,我会改变它。 =)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    • 2016-08-13
    • 2021-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多