My current implementation for a totally antisymmetric function is like this:
g[a__] := Signature[{a}] (g @@ Sort@{a}) /; !OrderedQ[{a}];
g[a__] := 0 /; ! Unequal[a];
So I take the list of arguments of f and calculate the signature of the permutation, and put that factor out the front. I then sort to pick a canonical ordering which I put into f.
so I want that eg. f[1,3,2] = -f[1,2,3] and f[1,2,3] = f[2,3,1], and my code above achieves this. The second line sets any f with two arguments the same to be zero.
Then you could use this f for a wedge product or a minor of a matrix for example.
My code works, but is very slow when doing many rearrangments, as it needs to keep sorting and unioning the list of arguments.
Does anyone have an idea for a faster implementation?
f[Sequence @@ Sort @ List @ a]
can be simplified to(f @@ Sort @ List @ a)
and I'd generally writeList@a
as{a}
. Also theUnion
can be avoided withUnequal[a]
(Unequal
doesn't only check for equality between consecutive pairs, but between all pairs, so it ensures all values are different.) ForSort @ {a} =!= {a}
you can useOrderedQ
, or! Less[a]
. $\endgroup$OrderedQ
sorts the list (at least I really hope it doesn't). I'm pretty sure its implementation would be similar to my! Less[a]
suggestion which should run in linear time. You are probably sorting twice to determineSignature
though. I'm not sure there's a way to avoid that, short of writing your ownSignature
that returns the sorted permutation along the way. (Probably based onOrdering
.) (Also, if you put an @ in front of my name, I'll actually get a notification for your comments.) $\endgroup$Unequal
stays unevaluated for "most" of symbolic expressions whether they contain duplicates or not e.g.Unequal[a, b, b]
,Unequal[a, b, c]
, so your currentg
function will remain unevaluated in some cases for which it could give0
e.g.g[a, b, b]
. $\endgroup$