dre*_*ves 5 sorting wolfram-mathematica permutation
假设我有一个函数f,它接受一个向量v并返回一个新的向量,其元素以某种方式转换.它通过调用假定向量被排序的函数g来做到这一点.所以我想要像这样定义f:
f[v_] := Module[{s, r},
s = Sort[v]; (* remember the permutation applied in order to sort v *)
r = g[s];
Unsort[r] (* apply the inverse of that permutation *)
]
Run Code Online (Sandbox Code Playgroud)
做"Unsort"的最佳方法是什么?
或者我们是否真的很喜欢并且以某种方式工作:
answer = Unsort[g[Sort[v]]];
Run Code Online (Sandbox Code Playgroud)
补充:让我们以玩具为例来具体化.假设我们想要一个带有向量的函数f,并通过向每个元素添加下一个最小元素(如果有的话)来对其进行转换.如果我们假设向量已经排序,那么这很容易编写,所以让我们编写一个辅助函数g来做出这样的假设:
g[v_] := v + Prepend[Most@v, 0]
Run Code Online (Sandbox Code Playgroud)
现在对于我们真正想要的函数f,无论v是否有效,它都有效:
f[v_] := (* remember the order;
sort it;
call g on it;
put it back in the original order;
return it
*)
Run Code Online (Sandbox Code Playgroud)
一种可能的方法:
mylist = {c, 1, a, b, 2, 4, h, \[Pi]}
g /@ (Sort@mylist)[[Ordering@Ordering@mylist]]
Run Code Online (Sandbox Code Playgroud)
给
{g [c],g 1,g [a],g [b],g [2],g [4],g [h],g [[Pi]]}
那是,
(Sort@mylist)[[Ordering@Ordering@mylist]] == mylist
Run Code Online (Sandbox Code Playgroud)
我最初从Andrzej Kozlowski的一篇文章中从MathGroup,[EDITED]中学到了上述内容
http://forums.wolfram.com/mathgroup/archive/2007/Jun/msg00920.html
感谢 TomD 和 Yaroslav,这可能是最简洁/优雅的方法:
f[v_] := g[Sort@v][[Ordering@Ordering@v]]
Run Code Online (Sandbox Code Playgroud)
感谢 Janus,这里有一个可能更有效的方法:
f[v_] := With[{o = Ordering@v}, g[v[[o]]][[Ordering@o]]]
Run Code Online (Sandbox Code Playgroud)
请注意,它进行了 2 次排序,而不是 3 次。
对于后代,这是我最初的尝试,尽管我认为它没有什么值得推荐的:
f[v_] := With[{o = Ordering[v]}, Sort[Transpose[{o,g[v[[o]]]}]][[All,-1]]]
Run Code Online (Sandbox Code Playgroud)
为了解决评论中的贝利撒留问题,我不将 g 作为参数传递的原因是因为我认为 g 作为 f 的辅助函数。就像我有一个函数 f ,如果我可以假设它的参数是一个排序向量,那么它会更容易编写。所以我编写了假设的版本,然后执行这个包装技巧。