Mathematica 大表周期插值

发布于 2024-11-10 11:24:38 字数 1143 浏览 8 评论 0原文

我在 Mathematica 中有一个来自逆 FFT 的非常大的表((dimcub-1)^3 元素)。我需要在此表上使用周期性插值。由于周期性插值要求第一个元素和最后一个元素相等,因此我手动创建一个新的 dim^3 元素表,并在插值中使用它。它可以工作,但它很难看/很慢,而且由于我多余的中间表,我很快就遇到了内存障碍。任何人都可以告诉我如何通过附加元素将我的旧表变成周期表,或者使用我的非周期表来制作周期插值函数?这是我当前的代码:

mr 1 是新表:

mr1 = Table[  0. , {i, 1, dimcub}, {j, 1, dimcub}, {k, 1, dimcub}];

Do[Do[  Do[   
      mr1[[m, n, k]] = oldtable[[m, n, k]] ;  , {m, 1, 
       dimcub - 1}]; , {n, 1, dimcub - 1}]; , {k, 1, dimcub - 1}]; 
Do[Do[     mr1[[m, n, dimcub]] =  mr1[[m, n, 1]]; 
  mr1[[m, dimcub, n]] =  mr1[[m, 1, n]];  
  mr1[[dimcub, m, n]] =  mr1[[1, m, n]];     , {m, 1, dimcub - 1}];  
 mr1[[n, dimcub, dimcub]] =  mr1[[n, 1, 1]]; 
 mr1[[dimcub, n, dimcub]] =  mr1[[1, n, 1]];  
 mr1[[dimcub, dimcub, n]] =  mr1[[1, 1, n]]; , {n, 1, dimcub - 1}]; 
mr1[[dimcub, dimcub, dimcub]] = mr1[[1, 1, 1]]; 

Remove[oldtable]; 

myinterpolatingfunction = 
 ListInterpolation[mr1, {{1, dimcub}, {1, dimcub}, {1, dimcub}}, 
  InterpolationOrder -> 1, 
  PeriodicInterpolation -> True];

 Remove[mr1];

myinterpolatingfunction 占用的内存少得多,并且在删除旧表后可以完美运行。任何帮助将不胜感激。

I have a very large table in Mathematica ((dimcub-1)^3 elements) coming from an inverse FFT. I need to use periodic interpolation on this table. Since periodic interpolation requires that the first elements and last elements are equal, I create a new table of dim^3 elements manually and use that in my interpolation. It works but it is ugly/slow and due to my superfluous intermediate table, I hit the memory barrier sooner. Can any one tell me either how to turn my old table into a periodic one somehow by appending elements or use my non periodic table to make a periodic interpolation function? Here is my current piece of code:

mr 1 is the new table:

mr1 = Table[  0. , {i, 1, dimcub}, {j, 1, dimcub}, {k, 1, dimcub}];

Do[Do[  Do[   
      mr1[[m, n, k]] = oldtable[[m, n, k]] ;  , {m, 1, 
       dimcub - 1}]; , {n, 1, dimcub - 1}]; , {k, 1, dimcub - 1}]; 
Do[Do[     mr1[[m, n, dimcub]] =  mr1[[m, n, 1]]; 
  mr1[[m, dimcub, n]] =  mr1[[m, 1, n]];  
  mr1[[dimcub, m, n]] =  mr1[[1, m, n]];     , {m, 1, dimcub - 1}];  
 mr1[[n, dimcub, dimcub]] =  mr1[[n, 1, 1]]; 
 mr1[[dimcub, n, dimcub]] =  mr1[[1, n, 1]];  
 mr1[[dimcub, dimcub, n]] =  mr1[[1, 1, n]]; , {n, 1, dimcub - 1}]; 
mr1[[dimcub, dimcub, dimcub]] = mr1[[1, 1, 1]]; 

Remove[oldtable]; 

myinterpolatingfunction = 
 ListInterpolation[mr1, {{1, dimcub}, {1, dimcub}, {1, dimcub}}, 
  InterpolationOrder -> 1, 
  PeriodicInterpolation -> True];

 Remove[mr1];

myinterpolatingfunction takes much less memory and works perfectly once i remove the older tables. Any help will be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

稀香 2024-11-17 11:24:38

列昂尼德和巫师先生的答案都做了太多工作。在 Leonid 的例子中,只需要前三行。为了说明这一点,我将把最后 4 个 Set 更改为 Equal

In[65]:= len = 4; oldtable = 
 Partition[Partition[Range[len^3], len], len]

Out[65]= {{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 
   16}}, {{17, 18, 19, 20}, {21, 22, 23, 24}, {25, 26, 27, 28}, {29, 
   30, 31, 32}}, {{33, 34, 35, 36}, {37, 38, 39, 40}, {41, 42, 43, 
   44}, {45, 46, 47, 48}}, {{49, 50, 51, 52}, {53, 54, 55, 56}, {57, 
   58, 59, 60}, {61, 62, 63, 64}}}

In[66]:= oldtable[[All, All, -1]] = oldtable[[All, All, 1]];
oldtable[[All, -1, All]] = oldtable[[All, 1, All]];
oldtable[[-1, All, All]] = oldtable[[1, All, All]];
oldtable[[All, -1, -1]] == oldtable[[All, 1, 1]]
oldtable[[-1, All, -1]] == oldtable[[1, All, 1]]
oldtable[[-1, -1, All]] == oldtable[[1, 1, All]]
oldtable[[-1, -1, -1]] == oldtable[[1, 1, 1]]

Out[69]= True

Out[70]= True

Out[71]= True

Out[72]= True

Leonid 的作用如下图所示。他的代码的第 4-6 行执行了左侧面板中所示的操作:复制已复制的平面(浅色)的一条线(深色)。第 7 行由右侧面板所示。这是对角相对位置的单元到单元的复制,其操作不单独包含在前三个复制操作中的任何一个中,而是它们连续操作的结果。

在此处输入图像描述

Both Leonid's and Mr.Wizard's answers do too much work. In Leonid's case only the first three lines are necessary. To show this I'll change the last 4 Sets to Equals:

In[65]:= len = 4; oldtable = 
 Partition[Partition[Range[len^3], len], len]

Out[65]= {{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 
   16}}, {{17, 18, 19, 20}, {21, 22, 23, 24}, {25, 26, 27, 28}, {29, 
   30, 31, 32}}, {{33, 34, 35, 36}, {37, 38, 39, 40}, {41, 42, 43, 
   44}, {45, 46, 47, 48}}, {{49, 50, 51, 52}, {53, 54, 55, 56}, {57, 
   58, 59, 60}, {61, 62, 63, 64}}}

In[66]:= oldtable[[All, All, -1]] = oldtable[[All, All, 1]];
oldtable[[All, -1, All]] = oldtable[[All, 1, All]];
oldtable[[-1, All, All]] = oldtable[[1, All, All]];
oldtable[[All, -1, -1]] == oldtable[[All, 1, 1]]
oldtable[[-1, All, -1]] == oldtable[[1, All, 1]]
oldtable[[-1, -1, All]] == oldtable[[1, 1, All]]
oldtable[[-1, -1, -1]] == oldtable[[1, 1, 1]]

Out[69]= True

Out[70]= True

Out[71]= True

Out[72]= True

What Leonid does is illustrated in the figures below. Lines 4-6 of his code do something as illustrated in the left-hand panel: copying a line (darker color) of a plane already copied (light colors). Line 7 is illustrated by the right-hand panel. This is a cell to cell copy of diagonally opposing positions, and its operation is not included in any of the first three copy actions separately, but is a result of their successive operation.

enter image description here

七婞 2024-11-17 11:24:38

您可以通过如下修改原始表来更快、更节省内存:

oldtable[[All, All, -1]] = oldtable[[All, All, 1]];
oldtable[[All, -1, All]] = oldtable[[All, 1, All]];
oldtable[[-1, All, All]] = oldtable[[1, All, All]];
oldtable[[All, -1, -1]] = oldtable[[All, 1, 1]];
oldtable[[-1, All, -1]] = oldtable[[1, All, 1]];
oldtable[[-1, -1, All]] = oldtable[[1, 1, All]];
oldtable[[-1, -1, -1]] = oldtable[[1, 1, 1]];

这些赋值替换了嵌套循环并且速度更快,而且您不需要内存来存储副本。这是基于 Part 命令的扩展矢量化功能(数组和通用表达式)索引),特别是矢量化分配。将数值数组采用 压缩数组 形式也很重要,这通常是案件。

You can get it much faster and more memory-efficiently by modifying the original table as follows:

oldtable[[All, All, -1]] = oldtable[[All, All, 1]];
oldtable[[All, -1, All]] = oldtable[[All, 1, All]];
oldtable[[-1, All, All]] = oldtable[[1, All, All]];
oldtable[[All, -1, -1]] = oldtable[[All, 1, 1]];
oldtable[[-1, All, -1]] = oldtable[[1, All, 1]];
oldtable[[-1, -1, All]] = oldtable[[1, 1, All]];
oldtable[[-1, -1, -1]] = oldtable[[1, 1, 1]];

These assignments replace nested loops and are much faster, plus you don't need memory to store the copy. This is based on an extended vectorized functionality of the Part command (array and general expression indexing), particularly vectorized assignments. It also matters to have your numerical array in a Packed array form, which is often the case.

在巴黎塔顶看东京樱花 2024-11-17 11:24:38

只是因为我有点傻,Leonid 的解决方案可以写成:

a = {0, 1}~Tuples~3~SortBy~Tr // Rest;

MapThread[
  (oldtable[[Sequence @@ #]] = oldtable[[Sequence @@ #2]]) &,
  {-a, a} /. 0 -> All
];

Just because I'm a bit of a loon, Leonid's solution can be written as:

a = {0, 1}~Tuples~3~SortBy~Tr // Rest;

MapThread[
  (oldtable[[Sequence @@ #]] = oldtable[[Sequence @@ #2]]) &,
  {-a, a} /. 0 -> All
];
旧情勿念 2024-11-17 11:24:38

感谢所有的答案。我尝试了 leonid 的建议,但是当我打印我的旧表时,它仍然是 (dimcub -1)^3 维。定义了新元素,我可以单独看到它们,但当我打印整个表时,它们不会显示为旧表的一部分。所以我最终得到了类似的东西,它正是我所需要的:

oldtable= PadRight[oldtable, {dimcub, dimcub, dimcub}];
oldtable[[All, All, dimcub]] = oldtable[[All, All, 1]];
oldtable[[All, dimcub, All]] = oldtable[[All, 1, All]];
oldtable[[dimcub, All, All]] = oldtable[[1, All, All]];
oldtable[[All, dimcub, dimcub]] = oldtable[[All, 1, 1]];
oldtable[[dimcub, All, dimcub]] = oldtable[[1, All, 1]];
oldtable[[dimcub, dimcub, All]] = oldtable[[1, 1, All]];
oldtable[[dimcub, dimcub, dimcub]] = oldtable[[1, 1, 1]];

向导的答案对于我的数学水平来说太先进了..

Thanks for all the answers. I tried the suggestion by leonid but when I print my oldtable, it was still (dimcub -1)^3 dimensional. New elements were defined and I can see them individually but they do not show up as part of the oldtable when I print the whole table. So I ended up with something similar which is doing exactly what I needed:

oldtable= PadRight[oldtable, {dimcub, dimcub, dimcub}];
oldtable[[All, All, dimcub]] = oldtable[[All, All, 1]];
oldtable[[All, dimcub, All]] = oldtable[[All, 1, All]];
oldtable[[dimcub, All, All]] = oldtable[[1, All, All]];
oldtable[[All, dimcub, dimcub]] = oldtable[[All, 1, 1]];
oldtable[[dimcub, All, dimcub]] = oldtable[[1, All, 1]];
oldtable[[dimcub, dimcub, All]] = oldtable[[1, 1, All]];
oldtable[[dimcub, dimcub, dimcub]] = oldtable[[1, 1, 1]];

The answer by Wizard is far too advanced for my level of mathematica..

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文