5
$\begingroup$

Imagine having an Association

Av = <|{1, 4, 2, 3} -> a, {2, 4, 2, 4} -> b|> 

It can be much longer. I am searching for an idiomatic and transparent way to construct a SparseArray out of it: Sv=buildSA[Av] The caveat is that each value corresponds to 8 possible permutation of indices. In particular, given the entry {i,j,k,l}->v, the sparse array should also contain

{i,j,k,l}->v
{l,j,k,i}->v
{l,k,j,i}->v
{i,k,j,l}->v
{j,i,l,k}->v
{k,i,l,j}->v
{k,l,i,j}->v
{j,l,i,k}->v

These symmetry properties come from the underlying definition

Sv[[i,j,k,l]]=Integrate[f[i][x] f[j][y] f[k][y] f[l][x] v[x,y],{x,...},{y,...}]

and the fact that v[x,y]==v[y,x].

I have a way to do that,

buildSA[a_] := Module[{b, ki, vi},
  b = <||>;
  Do[
   vi = a[ki];
   AssociateTo[b, ki[[{1, 2, 3, 4}]] -> vi];
   AssociateTo[b, ki[[{4, 2, 3, 1}]] -> vi];
   AssociateTo[b, ki[[{4, 3, 2, 1}]] -> vi];
   AssociateTo[b, ki[[{1, 3, 2, 4}]] -> vi];
   AssociateTo[b, ki[[{2, 1, 4, 3}]] -> vi];
   AssociateTo[b, ki[[{3, 1, 4, 2}]] -> vi];
   AssociateTo[b, ki[[{3, 4, 1, 2}]] -> vi];
   AssociateTo[b, ki[[{2, 4, 1, 3}]] -> vi];
   ,
   {ki, Keys[a]}];
  SparseArray[b // Normal]
  ]

but it looks very artificial. What would be the natural way to do it?

$\endgroup$
  • 1
    $\begingroup$ Why specifically these 8 permutations? $\endgroup$ – Szabolcs Sep 18 at 8:01
  • $\begingroup$ @Szabolcs The elements of the sparse array I am constructing are essentially integrals of the product of 4 functions. The permutation symmetry comes from the symmetry of integrals with respect to the permutation of functions. $\endgroup$ – yarchik Sep 18 at 8:14
  • 1
    $\begingroup$ @Szabolcs I have updated the post with the explanation of the reason for symmetries and my own messy implementation. $\endgroup$ – yarchik Sep 18 at 8:22
7
$\begingroup$

Maybe with SymmetrizedArray?

size = 4;
rank = 4;
Av = <|{1, 4, 2, 3} -> a, {2, 4, 2, 4} -> b|>;
symmetries = {
   {{4, 2, 3, 1}, 1},
   {{4, 3, 2, 1}, 1},
   {{1, 3, 2, 4}, 1},
   {{2, 1, 4, 3}, 1},
   {{3, 1, 4, 2}, 1},
   {{3, 4, 1, 2}, 1},
   {{2, 4, 1, 3}, 1}
   };
A = SparseArray[
  SymmetrizedArray[Normal[Av], ConstantArray[n, rank], symmetries]
  ]

In the list symmetries, each entry is a pair {p,s} of a permutation p that can be applied and a sign s (1, -1) that tells us whether the array is meant to be symmetric (s = 1 means symmetric, s = -1 means antisymmetric).

In fact, it suffices to provide only a set of generators of the symmetry group. For example,

symmetries = {
   {{4, 2, 3, 1}, 1},
   {{1, 3, 2, 4}, 1},
   {{2, 4, 1, 3}, 1}
   };

would lead to the same result

| improve this answer | |
$\endgroup$
  • $\begingroup$ Very nice! Especially appealing is the possibility to only provide a list of generators. $\endgroup$ – yarchik Sep 18 at 8:48
  • $\begingroup$ Thank you very much! =) $\endgroup$ – Henrik Schumacher Sep 18 at 9:19
5
$\begingroup$
pg = PermutationGroup[{{1, 2, 3, 4}, {4, 2, 3, 1}, {4, 3, 2, 1}, {1, 
     3, 2, 4}, {2, 1, 4, 3}, {3, 1, 4, 2}, {3, 4, 1, 2}, {2, 4, 1, 3}}];

ClearAll[sAbuild]
sAbuild = SparseArray[KeyValueMap[Alternatives @@ 
         GroupOrbits[pg, {#}, Permute][[1]] -> #2 &]@#, #2] &;

dims = {4, 4, 4, 4};

sAbuild[Av, dims]

enter image description here

Based on Henrik's answer, we can use a smaller set of generators to get the same result:

pg = PermutationGroup @ {{4, 2, 3, 1}, {1, 3, 2, 4}, {2, 4, 1, 3}};
| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you, I was thinking in this direction, but could not figure it out the KeyValueMap with Alternatives construction. I guess the group should be possible to build from the constructors somehow. $\endgroup$ – yarchik Sep 18 at 8:47

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.