在 Mathematica 中应用特定级别的欧氏距离

发布于 2024-12-03 12:11:39 字数 749 浏览 4 评论 0原文

请考虑:

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

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

但是我需要使用 Function 来应用在正确的级别:

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

Please consider:

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

I would like to compute the distance between each point in the 2 sub-lists of that list:

Yet I need to use a Function to apply at the correct level:

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

Is there a way to avoid this heavy function there?
To specify the level avoiding my Function with seqNo as argument? :

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

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

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

发布评论

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

评论(2

水波映月 2024-12-10 12:11:39

您是否尝试过 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]}}

Have you tried the Level specification in Map?

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

gives

{{3 Sqrt[85],2 Sqrt[181],Sqrt[613],25},{3 Sqrt[85],2 Sqrt[181],7 Sqrt[13],7 Sqrt[13]}}
枫林﹌晚霞¤ 2024-12-10 12:11:39

为了补充@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}]

性能差异保持在相同的数量级,尽管矢量化解决方案由于需要进行非平凡的换位。

To complement the answer of @Markus: if your daList is very large and numerical, the following will be much faster (like 30x), although somewhat less general:

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

Here is an example:

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.}}}

The reason is that functions like Power and Sqrt are Listable, and you push the iteration into the kernel. Functions like Map can also auto-compile the mapped function in many cases, but apparently not in this case.

EDIT

Per OP's request, here is a generalization to the case of non-trivial reference point:

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

It is still fast, but not as concise as before. For comparison, here is the code based on Map- ping, which only needs a trivial modification here:

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

The performance difference remains of the same order of magnitude, although the vectorized solution slows down a bit due to the need for non-trivial transpositions.

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