Mathematica大表周期插值

时间:2011-05-31 22:45:23

标签: wolfram-mathematica interpolation

我在Mathematica中有一个非常大的表((dimcub-1)^ 3个元素)来自逆FFT。我需要在这个表上使用周期性插值。由于周期性插值要求第一个元素和最后一个元素相等,我手动创建一个新的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占用的内存要少得多,效果也很好。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:9)

Leonid和Mr.Wizard的答案都做了太多工作。在列昂尼德的案例中,只有前三行是必要的。要显示此信息,我会将最后4 Set更改为Equal s:

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

列昂尼德所做的事情如下图所示。他的代码的第4-6行执行左侧面板中所示的操作:复制已经复制的平面(浅色)的线条(较暗的颜色)。第7行由右侧面板示出。这是对角线相对位置的单元格复制,其操作不单独包含在前三个复制操作中的任何一个中,而是它们连续操作的结果。

enter image description here

答案 1 :(得分:8)

通过如下修改原始表,您可以更快,更高效地获取内容:

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命令(数组和通用表达式索引)的扩展矢量化功能,特别是矢量化赋值。将数值数组放在Packed array形式中也很重要,通常就是这种情况。

答案 2 :(得分:5)

仅仅因为我是一个懒人,Leonid的解决方案可以写成:

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

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

答案 3 :(得分:4)

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

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]];

向导的答案对我的数学水平来说太高级了。