Mathematica大表周期插值

Hsn*_*Hsn 7 interpolation wolfram-mathematica

我在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];
Run Code Online (Sandbox Code Playgroud)

myinterpolatingfunction删除较旧的表后,内存少得多,工作完美.任何帮助将不胜感激.

Sjo*_*ies 9

Leonid和Mr.Wizard的答案都做了太多工作.在列昂尼德的案例中,只有前三行是必要的.为了表明这一点,我将最后4 Set秒改为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
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

  • @Sjoerd +1用于良好的视觉分析. (2认同)

Leo*_*rin 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]];
Run Code Online (Sandbox Code Playgroud)

这些赋值替换嵌套循环并且速度更快,而且您不需要内存来存储副本.这是基于Part命令(数组和一般表达式索引)的扩展矢量化功能,特别是矢量化赋值.将数值数组放在Packed数组形式中也很重要,通常就是这种情况.


Mr.*_*ard 5

仅仅因为我有点懒,Leonid的解决方案可以写成:

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

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


Hsn*_*Hsn 4

感谢所有的答案。我尝试了 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]];
Run Code Online (Sandbox Code Playgroud)

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