2

考えてください:

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

そのリストの2つのサブリストの各ポイント間の距離を計算したいと思います:

それでもFunction、正しいレベルで適用するには a を使用する必要があります。

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

その理由は、 と のような関数でPowerあり、反復をカーネルにプッシュするためです。のような関数は、多くの場合、マップされた関数を自動コンパイルすることもできますが、この場合は明らかにそうではありません。SqrtListableMap

編集

OPのリクエストによると、重要な基準点の場合の一般化は次のとおりです。

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

まだ高速ですが、以前ほど簡潔ではありません。比較のために、-ping に基づくコードを次に示します。ここではMap簡単な変更のみが必要です。

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

ベクトル化されたソリューションは、重要な転置が必要なため少し遅くなりますが、パフォーマンスの違いは同じ程度です。

于 2011-09-07T14:03:11.180 に答える