5
$\begingroup$

I do have some multi-indexed variable, e.g. like this

\begin{align*}f_{123} &= 1\\f_{345} &= 1/2\end{align*}

where $f$ is antisymmetric under permutation of any pair of indices, i.e. e.g. $f_{132}=-1$ and so on. Also, $f_{ijk}=0$ for $(ijk)$ not being a permutation of either $(123)$ or $(345)$. I am wondering what the right "Mathematica way" is to set up such a scenario.

My current attempt:

Define all values depending on the indices

ClearAll[f, f2];
f[{1, 2, 3}] = 1;
f[{3, 4, 5}] = 1/2;

Explicitly set all f to zero if their argument is not {1,2,3} or {3,4,5}.

f[list_ /; list != {1, 2, 3} || {3, 4, 5}] := 0;

Then define an f2 which takes a 3dim list as argument, evaluates the Signature[list] and multiplies with f called with Sorted list:

 f2[list_?(VectorQ[#, NumericQ] &) /; Length[list] == 3] := Signature[list]*f[Sort@list];

This works as I want it to work. However, I feel like there must be another way to accomplish this - and I actually think that my attempt is not the best one (I have a gut feeling that it might miss certain cases and lead to errors at some point).

P.S.: If you do have better suggestions for Tags, I would much appreciate an edit/suggestion.

$\endgroup$
  • $\begingroup$ I'd have done f[idx_ /; ! MatchQ[Sort[idx], {1, 2, 3} | {4, 5, 6}]] := 0 myself. $\endgroup$ – J. M. is away Apr 1 '16 at 12:43
  • $\begingroup$ @MartinBüttner Thanks for the suggestion. Of course, it is way more practicable to just use f[_]=0, not thinking straight there :) $\endgroup$ – Lukas Apr 1 '16 at 12:47
  • $\begingroup$ That depends on your application. Would you want, say, f["stuff"] or f[{1, 2, 3, 4, 5}] to return 0 as well? $\endgroup$ – J. M. is away Apr 1 '16 at 12:49
  • $\begingroup$ @J.M. That's right. Actually, in the way I need it right now it doesn't matter whether I use f[_]:=0 or the explicitly stated "zero cases". However, it is true that this might cause issues if the code develops. So I will probably stick to explicitly stating when f should be zero and when it should stay unevaluated. $\endgroup$ – Lukas Apr 1 '16 at 12:55
3
$\begingroup$

Since v10.1 you can use also OrderlessPatternSequence like this :

f[x : {OrderlessPatternSequence[1, 2, 3]}] := Signature[x]*1
f[x : {OrderlessPatternSequence[3, 4, 5]}] := Signature[x]*1/2

then

f[{2, 1, 3}]

-1

or

f[{5, 3, 4}]

1/2

$\endgroup$
  • $\begingroup$ That is really nice! Unfortunately I am still using 10.0.1 and cannot make use of OrderlessPatternSequence. But that seems to a very elegant solution which is also exremely transparent $\endgroup$ – Lukas Apr 1 '16 at 22:09
  • $\begingroup$ I learned something! $\endgroup$ – evanb Apr 1 '16 at 23:38
  • $\begingroup$ I decided to accept this answer (although I cannot use it) since it appears to me as the most elegant approach that also differs most from how I did it. $\endgroup$ – Lukas Apr 5 '16 at 8:48
2
$\begingroup$

Not very elegant, but (hopefully) transparent:

The basic data

p1 = {1, 2, 3}; pp1 = Permutations[p1];
p2 = {4, 5, 6}; pp2 = Permutations[p2];

The function

g[x_] := Which[MemberQ[pp1, x], Signature[x], MemberQ[pp2, x], 
         Signature[x]/2, True, 0]

(* or ending with 1/2] in which case x is returned unevaluated *)

All tuples

t = Tuples[Range[6], 3];
Length[%] == 6^3

(* Out[84]= True *)

Check g on t

{#, g[#]} & /@ t;
Select[%, #[[2]] != 0 &]

(*
{{{1, 2, 3}, 1}, {{1, 3, 2}, -1}, {{2, 1, 3}, -1}, {{2, 3, 1}, 
  1}, {{3, 1, 2}, 1}, {{3, 2, 1}, -1}, {{4, 5, 6}, 1/
  2}, {{4, 6, 5}, -(1/2)}, {{5, 4, 6}, -(1/2)}, {{5, 6, 4}, 1/
  2}, {{6, 4, 5}, 1/2}, {{6, 5, 4}, -(1/2)}}
*)
$\endgroup$
  • $\begingroup$ I don't see the sign change anywhere... $\endgroup$ – J. M. is away Apr 1 '16 at 16:49
  • $\begingroup$ @J.M. oops, you are right, I missed it. Now corrected. BTW your elegant solution can't possibly be beaten. $\endgroup$ – Dr. Wolfgang Hintze Apr 1 '16 at 17:21
  • $\begingroup$ @Dr.WolfgangHintze Indeed a very transparent solution and I like (from a pedagogic point of view) the combination of Permutations and MemberQ. Thanks for this $\endgroup$ – Lukas Apr 1 '16 at 21:59
2
$\begingroup$

How about

f[{1, 2, 3}] = 1;
f[{3, 4, 5}] = 1/2;
f[list_List /; Not[OrderedQ[list]]] := Signature[list] f[Sort@list]

Only bind the last definition if the argument isn't sorted, in which case sort and use Signature to get the correct sign. Then f[{3,2,1}] yields -1 and f[{4,5,3}] yields 1/2. You can then add f[___]:=0 default, if you want. With that default, f[{1,2,3,4}] and f[{5,1,2,3,4}] yield 0.

You can instead add the default

f[list_ /; OrderedQ[list] && Not[MemberQ[{{1, 2, 3}, {3, 4, 5}}, list]]] := 0

but this line MUST come after the previous list-reordering definition.

$\endgroup$
  • $\begingroup$ Also pretty compact solution. Thank you! $\endgroup$ – Lukas Apr 1 '16 at 22:05
  • $\begingroup$ There might be a smart way to use the DownValues of f to smartly rewrite the last clause in the last line there. $\endgroup$ – evanb Apr 1 '16 at 23:39
2
$\begingroup$

depending on how you use it , it might be good performance-wise to precompute an array:

fa = SparseArray[
   Flatten[
    Function[{t},
      (  # -> t[[2]] & /@ NestList[RotateLeft, t[[1]], 2])] /@
      { {{1, 2, 3},   1},
        {{2, 1, 3},  -1},
        {{3, 4, 5}, 1/2},
        {{4, 3, 5},-1/2} }, 1] (*,{n,n,n}*) ];
                                  (* ^ add dimension spec to handle #>5 *)
f[list_?(VectorQ[#, NumericQ] &) /; Length[list] == 3 &&
     Max[list] <= 5] := Extract[fa, list]   

f /@ {{1, 2, 3}, {4, 3, 5}, {3, 2, 1},{1,4,5}}

{1, -(1/2), -1, 0}

$\endgroup$
  • $\begingroup$ That looks pretty compact. However, I do not understand what the NestList[...] part does (and consequently what it is needed for). Could you elaborate on that briefly? $\endgroup$ – Lukas Apr 1 '16 at 22:02
  • $\begingroup$ evaluate this: NestList[RotateLeft,{1, 2, 3}, 2], it should be clear. $\endgroup$ – george2079 Apr 1 '16 at 22:27
  • $\begingroup$ True. In what case do you think is the precomputed array favorable? Even for 20 nonzero values, the result is given instantly. So I suspect maybe for more than 3 indices and a few 100 nonzero values? $\endgroup$ – Lukas Apr 2 '16 at 8:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.