我正在研究建立分布熵的函数。它使用copula,如果有的话熟悉它。我需要根据哪些维度“关心”来总结数组中的值。
示例:请考虑以下示例...
Dimension 0 (across) _ _ _ _ _ _ _ _ _ _ _ _ _ |_ 0 _|_ 0 _|_ 0 _|_ 2 _| Dimension 1 |_ 1 _|_ 0 _|_ 2 _|_ 0 _| (down) |_ 0 _|_ 3 _|_ 0 _|_ 6 _| |_ 0 _|_ 0 _|_ 0 _|_ 0 _| I "care about" dimension 0 only, and "don't care" about the rest (dim 1). Summing this array with the above specifications will "collapse" the "stacks" of dimension 1 down to a single 4 x 1 array: _ _ _ _ _ _ _ _ _ _ _ _ _ |_ 1 _|_ 3 _|_ 2 _|_ 8 _| This can then be summed, or have any operation performed.
我需要使用'n'维的数组来做这个,这可能是20个。另外,我需要能够做到这一点,关心某些维度,并折叠其余的维度。我对此特别困难,因为我无法想象出20个维度:p。如果有人可以帮我设置一些c / c ++代码来折叠/求和,我会非常感激。
回到家。以下是回答您问题的一些信息:
感谢大家的支持。
答案 0 :(得分:2)
@Jeff
我实际上认为这是一个有趣的问题。我不确定它有多有用,但这是一个有效的问题。
@Ed
你能提供一些关于这个问题的更多信息吗?你说数组的维度是动态的,但是动态元素的数量是多少?
编辑:我打算尝试回答这个问题。我不能把你的代码放在头顶上(这台PC上没有任何编译器需要一段时间才能完成它),但我可以指出你正确的方向......让我们使用索引0到3的8维(0-7)作为示例。你只关心1,2和6.这意味着你有两个数组。首先,array_care[4][4][4]
代表1,2和6. array_care[4][4][4]
将保留最终结果。
接下来,我们希望以非常具体的方式进行迭代。我们要解析数组input[4][4][4][4][4][4][4][4]
,我们关心维度1,2和6。
我们需要定义一些临时索引:
int dim[8] = {0,0,0,0,0,0,0,0};
我们还需要存储我们想要增加索引的顺序:
int increase_index_order[8] = {7,5,4,3,0,6,2,1};
int i = 0;
此顺序对于按照您的要求执行操作非常重要。
定义终止标志:
bool terminate=false;
现在我们可以创建循环:
while (terminate)
{
array_care[dim[1]][dim[2]][dim[6]] += input[dim[0]][dim[1]][dim[2]][dim[3]][dim[4]][dim[5]][dim[6]][dim[7]];
while ((dim[increase_index_order[i]] = 3) && (i < 8))
{
dim[increase_index_order[i]]=0;
i++;
}
if (i < 8) {
dim[increase_index_order[i]]++; i=0;
} else {
terminate=true;
}
}
这应该适用于8个维度,关注3个维度。它需要更多的时间才能让它变得动态,我没有时间。希望这可以帮助。我道歉,但我还没有学习代码标记。 :(
答案 1 :(得分:2)
如果您使用STL容器,或者Boost.MultiArray,这种事情会容易得多。但是如果你必须使用数组:
#include <iostream>
#include <boost/foreach.hpp>
#include <vector>
int sum(int x) {
return x;
}
template <class T, unsigned N>
int sum(const T (&x)[N]) {
int r = 0;
for(int i = 0; i < N; ++i) {
r += sum(x[i]);
}
return r;
}
template <class T, unsigned N>
std::vector<int> reduce(const T (&x)[N]) {
std::vector<int> result;
for(int i = 0; i < N; ++i) {
result.push_back(sum(x[i]));
}
return result;
}
int main() {
int x[][2][2] = {
{ { 1, 2 }, { 3, 4 } },
{ { 5, 6 }, { 7, 8 } }
};
BOOST_FOREACH(int v, reduce(x)) {
std::cout<<v<<"\n";
}
}
答案 2 :(得分:2)
这可能有应用程序。假设您实现了2D康威的生命游戏(定义了2D平面,1代表'活着',0代表'死')并且您存储了每次迭代的游戏历史记录(然后定义了3D立方体)。如果你想知道历史上有多少细菌活着,你会使用上面的算法。您可以将相同的算法用于生命游戏网格的3D,(和4D,5D等)版本。
我说这是递归的问题,我不是C程序员,但我知道它可能在C中。在python中,
def iter_arr(array):
sum = 0
for i in array:
if type(i) == type(list()):
sum = sum + iter_arr(i)
else:
sum = sum + i
return sum
然后,您可以将其应用于“关注”维度中的每个元素。
由于鸭子打字,这在python中更容易......
答案 3 :(得分:0)
实际上,通过折叠已经对它们进行求和的列,所以维度对于您的示例根本不重要。我错过了什么或是你吗?
答案 4 :(得分:0)
我认为在这里做的最好的事情是两件事中的一件事:
答案 5 :(得分:0)
我不同意,总有另一种方式......
如果你真的不能重构,那么你需要将问题分解成更小的部分。就像我说的那样,确定你需要求和的维度,然后一次点击一个。
此外,停止更改修改,他们正在纠正您的拼写错误,他们正试图帮助您;)
答案 6 :(得分:0)
当你说你不知道有多少维度时,你究竟是如何定义数据结构的呢?
在某些时候,有人需要创建这个数组,为此,他们需要知道数组的维度。您可以强制创建者将此数据与数组一起传递。
除非问题是定义这样的数据结构......
答案 7 :(得分:0)
你在c / c ++中这样做...所以你有一个数组数组...你不必可视化20维,因为这不是数据在内存中的布局,对于二维:
[1] --> [1,2,3,4,5,6,...]
[2] --> [1,2,3,4,5,6,...]
[3] --> [1,2,3,4,5,6,...]
[4] --> [1,2,3,4,5,6,...]
[5] --> [1,2,3,4,5,6,...]
. .
. .
. .
所以,为什么你不能迭代第一个总结它的内容?如果您要查找大小,那么sizeof(array)/sizeof(int)
是一种冒险的方法。您必须知道能够处理此数据的维度,并设置内存,因此您需要知道递归的深度。这是一些伪代码,你应该做什么,
sum( n_matrix, depth )
running_total = 0
if depth = 0 then
foreach element in the array
running_total += elm
else
foreach element in the array
running_total += sum( elm , depth-1 )
return running_total
答案 8 :(得分:0)
x = number_of_dimensions;
while (x > 1)
{
switch (x)
{
case 20:
reduce20DimensionArray();
x--;
break;
case 19:
.....
}
}
(抱歉,无法抗拒。)
答案 9 :(得分:0)
如果我理解正确,您希望将沿每个维度在每个“bin”中定义的横截面中的所有值相加。我建议为你的目的地制作一个数组,然后循环遍历数组中的每个元素,将值添加到目标,并使用感兴趣的维度索引。
如果你使用任意数量的维度,你必须有一种解决元素的方法(我很好奇你是如何实现这个)。您的实现将影响您设置目标索引的方式。但显而易见的方法是在迭代循环中检查if语句。