我正在研究建立分布熵的函数。 它使用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 ++代码来折叠/求和,我会非常感激。

更新:

刚到家。 以下是回答您问题的一些信息:

  1. 很抱歉回滚编辑,我希望当我点击回滚它会告诉我更改,所以我可以看到我搞砸了,有点像维基百科。 事实并非如此,正如我所发现的那样。
  2. @jeff - 什么没有意义? 我正在使用这项伟大的服务(我认为)是一个合理的理由。 我希望自己的爱好变得更好,就像我在高中时一样。 我的很多帖子都认为实现遗传算法(这篇文章,sparsearray,排名数组,指针操作)。
  3. 我正在使用稀疏数组表示,因为有可能使用传统(密集)数组超过宇宙中的分子数。 目前,sparsearray本身的实现并不重要,因为我正在努力使它在使用标准数组之前进入稀疏表示。 对于那些没有看过我之前的问题的人,我使用二叉搜索树作为包含稀疏数组点的结构,并使用“驱动程序”函数来根据需要遍历树,返回任何函数的设计。 这很灵活,所以我可以容纳很多不同的访问阵列的方法。
  4. 结构是一个超立方体,维度的数量是在运行时指定的,以及每个维度的长度(它们都是相同的,因为它是一个超立方体)。

谢谢大家的支持。

===============>>#1 票数: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个维度。 它需要更多的时间才能让它变得动态,我没有时间。 希望这可以帮助。 我道歉,但我还没有学习代码标记。 :(

===============>>#2 票数: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";
    }
}

===============>>#3 票数: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 
  1. 迭代数组中的每个元素
  2. 如果element是另一个数组,请再次调用该函数
  3. 如果element不是数组,请将其添加到总和中
  4. 归还总和

然后,您可以将其应用于“关注”维度中的每个元素。

由于鸭子打字,这在python中更容易...

===============>>#4 票数:0

实际上,通过碰撞你已经将它们相加的柱子,所以尺寸对你的例子来说根本不重要。 我错过了什么或者你做过吗?

===============>>#5 票数:0

我认为在这里做的最好的事情是两件事中的一件事:

  1. 重新思考设计,如果它太复杂,找到一个不太复杂的方式。
  2. 停止尝试将其可视化..:P只需存储您需要求和的维度,然后一次执行一个。 获得基本代码后,请考虑提高算法的效率。

===============>>#6 票数:0

我不同意,总有另外一种方式..

如果你真的无法重构,那么你需要将问题分解成更小的部分。就像我说的那样,确定你需要求和的尺寸,然后一次点击一个。

此外,停止更改编辑,他们正在纠正您的拼写错误,他们正试图帮助您;)

===============>>#7 票数:0

当你说你不知道有多少维度时,你究竟是如何定义数据结构的呢?

在某些时候,有人需要创建这个数组,为此,他们需要知道数组的维度。 您可以强制创建者将此数据与数组一起传递。

除非问题是定义这样的数据结构......

===============>>#8 票数:0

你在c / c ++中这样做...所以你有一个数组数组的数组...你不必可视化20维,因为这不是数据在内存中的布局方式,对于2维:

[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

===============>>#9 票数:0

x = number_of_dimensions;
while (x > 1)
{
  switch (x)
  {
    case 20:
      reduce20DimensionArray();
      x--;
    break;
    case 19:
      .....
  }
}

(抱歉,无法抗拒。)

===============>>#10 票数:0

如果我理解正确,您希望将沿每个维度在每个“bin”中定义的横截面中的所有值相加。 我建议为目标创建一个数组,然后循环遍历数组中的每个元素,将值添加到目标,并使用感兴趣的维度索引。

如果你使用任意数量的维度,你必须有一种解决元素的方法(我很好奇你是如何实现这个)。 您的实现将影响您设置目标索引的方式。 但显而易见的方法是在迭代循环中检查if语句。

  ask by Ed. translate from so

未解决问题?本站智能推荐: