2

请考虑:

daList = {{{21, 18}, {20, 18}, {18, 17}, {20, 15}}, 
          {{21, 18}, {20, 18}, {21, 14}, {21, 14}}};

我想计算该列表的 2 个子列表中每个点之间的距离:

但是我需要使用 aFunction来申请正确的级别:

Function[seqNo, 
         EuclideanDistance[#, {0, 0}] & /@ daList[[seqNo]]] /@ 
         Range[Length@daList]

out = {{3 Sqrt[85], 2 Sqrt[181], Sqrt[613], 25}, {3 Sqrt[85], 2 Sqrt[181], 
        7 Sqrt[13], 7 Sqrt[13]}}

有没有办法避免这种繁重的功能?使用 seqNo 作为参数来指定避免我的函数的级别?:

EuclideanDistance[#, {0, 0}] & /@ daList

out={EuclideanDistance[{{21, 18}, {20, 18}, {18, 17}, {20, 15}}, {0, 0}], 
     EuclideanDistance[{{21, 18}, {20, 18}, {21, 14}, {21, 14}}, {0, 0}]}
4

2 回答 2

6

您是否尝试过 Map 中的 Level 规范?

Map[EuclideanDistance[#, {0, 0}] &, daList, {2}]

{{3 Sqrt[85],2 Sqrt[181],Sqrt[613],25},{3 Sqrt[85],2 Sqrt[181],7 Sqrt[13],7 Sqrt[13]}}
于 2011-09-07T13:08:28.463 回答
6

为了补充@Markus的答案:如果你daList的数字很大,那么下面的速度会快得多(比如30x),虽然不太一般:

Sqrt@Total[daList^2,{3}]

这是一个例子:

In[17]:= largeDaList = N@RandomInteger[30,{100000,4,2}];
In[18]:= Map[EuclideanDistance[#,{0,0}]&,largeDaList,{2}]//Short//Timing
Out[18]= {0.953,{{31.7648,34.6699,20.3961,31.305},<<99998>>,{<<18>>,<<2>>,0.}}}

In[19]:= Sqrt@Total[largeDaList^2,{3}]//Short//Timing
Out[19]= {0.031,{{31.7648,34.6699,20.3961,31.305},<<99998>>,{<<18>>,<<2>>,0.}}}

原因是函数喜欢PowerSqrtListable并且您将迭代推送到内核中。在许多情况下,类似Map的函数也可以自动编译映射函数,但在这种情况下显然不是。

编辑

根据 OP 的要求,这里是对非平凡参考点情况的概括:

refPoint = {3, 5};
Sqrt@Total[#^2, {3}] &@Transpose[Transpose[daList, {3, 2, 1}] - refPoint, {3, 2, 1}]

它仍然很快,但不像以前那样简洁。对比一下,这里是基于Map-ping的代码,这里只需要简单的修改:

Map[EuclideanDistance[#, refPoint] &, daList, {2}]

性能差异保持在同一数量级,尽管由于需要非平凡的转置,矢量化解决方案会减慢一点。

于 2011-09-07T14:03:11.180 回答