犰狳相当于Matlab的置换?

时间:2016-03-04 12:35:49

标签: c++ matlab armadillo

我有一个arma::cube mycube(5,10,15);,我想要改变它的尺寸,就像在matlab中做的那样:

mycube = ones(5,10,15);
mycube = permute(mycube,[3 1 2]);
size(mycube) % returns (15 5 10)

有办法吗?
会效率太低吗?

我实际上想要进行3D FFT,因此我考虑将第一和第三维置换,以便能够使用arma::fft,然后进行置换。

2 个答案:

答案 0 :(得分:5)

制作3-dim数组(arma :: cube)排列的​​另一种简便方法是下面的方法。这不是很优雅,但容易理解。

因为3个唯一数字的排列是6(确切地说是没有参考顺序的5),所以很快就可以避免使用算法。

dim 1,2,3的排列:

123(基本订单)132 213 231 312 321。

所以在不同的排列之间进行简单的切换:

template <typename T>
static Cube<T> permute (Cube<T>& cube, const std::tuple<uword,uword,uword>& order)
{
    uword idx1 = std::get<0>(order);
    uword idx2 = std::get<1>(order);
    uword idx3 = std::get<2>(order);

    u32_vec dimension = shape(cube);

    uword rows = dimension(idx1 - 1);
    uword cols = dimension(idx2 - 1);
    uword slis = dimension(idx3 - 1);

    Cube<T> output; 
    output.zeros(rows, cols, slis);

    uword perm = idx1*100 + idx2*10 + idx3;

    switch (perm)
    {
        case 123:
        {
            output = cube; // identity
        }
        break;
        case 132:
        {
            for (int c = 0; c < cube.n_cols; ++c)
                for (int r = 0; r < cube.n_rows; ++r)
                    for (int s = 0; s < cube.n_slices; ++s)
                        output(r, s, c) = cube(r, c, s);
        }
        break;
        case 213:
        {
            for (int c = 0; c < cube.n_cols; ++c)
                for (int r = 0; r < cube.n_rows; ++r)
                    for (int s = 0; s < cube.n_slices; ++s)
                        output(c, r, s) = cube(r, c, s);
        }
        break;
        case 231:
        {
            for (int c = 0; c < cube.n_cols; ++c)
                for (int r = 0; r < cube.n_rows; ++r)
                    for (int s = 0; s < cube.n_slices; ++s)
                        output(c, s, r) = cube(r, c, s);
        }
        break;
        case 312:
        {
            for (int c = 0; c < cube.n_cols; ++c)
                for (int r = 0; r < cube.n_rows; ++r)
                    for (int s = 0; s < cube.n_slices; ++s)
                        output(s, r, c) = cube(r, c, s);
        }
        break;
        case 321:
        {
            for (int c = 0; c < cube.n_cols; ++c)
                for (int r = 0; r < cube.n_rows; ++r)
                    for (int s = 0; s < cube.n_slices; ++s)
                        output(s, c, r) = cube(r, c, s);
        }
        break;
    }

    return output;
}

订单元组采用matlab风格(基于1),而armadillo是基于零的数组。

形状(立方体)函数只是一个小帮手,在matlab中返回等效的Size(),这是一个每个尺寸大小的N-dim数组。

template <typename T> 
inline u32_vec shape (const Cube<T>& x) 
{ 
    return { x.n_rows, x.n_cols, x.n_slices };
}

代码需要与:

一起使用
using namespace arma;

答案 1 :(得分:1)

Armadillo ibrary不包含这样的功能,但您可以实现简化版本。例如:

driver.findElement(By.id("cntMain_chkPrimaryInvestigator_A")).click();