我有一个n
维数组T
,其中每个维度的长度都相同L
。此数组由1D向量v
表示(可以看作T
的“重新整形”版本,因此v
的长度为L^n
)。
以下示例显示了v
如何根据T
(其中n = 3
和L = 4
)的索引编制索引:
(例如T(0,3,2) = v[14]
)
我想要做的是创建一个代表u
维数组n
的向量S
,其中S
是通过置换/旋转{{1}获得的1,即
T
T(i1,i2,...,in) = S(i2,i3,...,in,i1)
。
(当(i1,i2,...,in)
是矩阵时,T
对应于S
)的转置。
更新:
以下代码可以更好地解释我的问题:
T
然而,在实践中,我认为直接使用矢量更好。因此,我会做这样的事情:
void permute(vector<double> &output, const vector<double> &v, int L)
{
int n = log(v.size())/log(L);
// Suppose that we have a function doing this
narray T = get_narray_from_vector(v, L);
// Get the permutation of T
narray S(T.size());
for(int i1 = 0; i1 < L; i1++){
for(int i2 = 0; i2 < L; i2++){
...
for(int in = 0; in < L; in++){
S(i2,i3,...,in,i1) = T(i1,i2,...,in);
}
}
}
// get vector from narray
output.resize(v.size());
int idx = 0;
for(int i1 = 0; i1 < L; i1++){
for(int i2 = 0; i2 < L; i2++){
...
for(int in = 0; in < L; in++){
output[idx] = S(i1,i2,...,in);
idx++;
}
}
}
}
这里的难点是嵌套循环,因为void permute(vector<double> &output, const vector<double> &v, int L)
{
int n = log(v.size())/log(L);
output.resize(v.size());
// Get the permutation
for(int i1 = 0; i1 < L; i1++){
for(int i2 = 0; i2 < L; i2++){
...
for(int in = 0; in < L; in++){
output[i2*pow(L, n-1) + i3*pow(L, n-2) + ... + in*L + i1] = v[i1*pow(L, n-1) + i2*pow(L, n-2) + ... + i_{n-1}*L + in];
}
}
}
}
是一个参数。
任何想法如何做到这一点? 预先感谢您的帮助!!
答案 0 :(得分:1)
这是一个不需要n
嵌套for循环的解决方案。
首先,我有一些旧代码可以将数字分解为基于L
的数字系统。
std::vector<int>
num2base(const int value,
const unsigned int base){
// Represents an input int VALUE in a new BASE-based number system
// n = a0*b^0 + a1*b^1 + ...
std::vector<int> base_representation;
unsigned int num_digs = (unsigned int) (floor(log(value)/log(base))+1);
base_representation.resize(num_digs);
for (unsigned int i_dig = 0; i_dig < num_digs; i_dig++){
base_representation[i_dig] =
((value % (int) pow(base,i_dig+1)) - (value % (int) pow(base, i_dig))) /
(int) pow(base, i_dig);
}
return base_representation;
}
换句话说,这是将单值索引idx
转换为i1
到in
n
- 元组索引的方法。
idx = i1*L^0 + i2*L^1 + ... in*L^(n-1)
这是代码的另一种方式
int
base2num(const std::vector<int> base_representation,
const unsigned int base){
unsigned int digit_val = 1;
int value = 0;
for (unsigned int digit = 0; digit < base_representation.size(); digit++){
value += base_representation[digit]*digit_val;
digit_val *= base;
}
return value;
}
一旦你有std::vector<int>
表示你的n
- 元组索引,就很容易置换它。
void
permute_once(std::vector<int> &base_representation){
std::vector<int>::iterator pbr = base_representation.begin();
int tmp = *pbr;
base_representation.erase(pbr);
base_representation.push_back(tmp);
return;
}
因此,要生成新的n
- 维数组S
浏览idxS
的每个索引S
。
将idxS
转换为n
- 元组(iS1
,iS2
,...,iSn
)
在T
及其n
- 元组(iT1
,iT2
,...,iTn
)中找到相关条目
将其转换为单个索引idxT
。
u[idxS] = v[idxT];