Еще один простой способ сделать 3-тусклый массив (арма :: куб) перестановка ниже один. Это не очень элегантно, но легко понять.
Поскольку перестановка 3 уникальных чисел равна 6 (а точнее 5 без ссылочного порядка), быстро избежать алгоритмического метода.
Перестановка тусклым 1, 2, 3:
123 (основание) порядка 213 231 132 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;
}
Порядок tuple находится в стиле matlab (на основе 1), а armadillo - на основе нуля.
Функция формы (куба) - это лишь небольшой помощник, который возвращает эквивалент размера() в матрице Mlab, массив 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;
Вы бы ожидать simplePermute работать на 'арма :: cx_cube' тоже? – dangom
@ ДаниэльG, да, главное здесь - количество измерений. –
На самом деле функция перестановки не работает должным образом. Он не дает те же результаты, что и matlab. В качестве простого примера, если матрица является идеальным кубом, 'simplePermute' ничего не сделает с ней. – dangom