This is the code I use:
Options[symmDot] = {Variables -> {\[FormalX], \[FormalY], \[FormalZ]}};
symmDot[s1_List, sn___List, opts : OptionsPattern[]] /;
MatchQ[Dimensions[{s1, sn}], {_, 1 | 2 | 3}] :=
Fold[sd[##1, opts] & , s1, {sn}]
sd[s1_, s2_, OptionsPattern[symmDot]] :=
s2 /. Thread[Take[OptionValue[Variables], Length[s1]] -> s1]
(s1_List) \[CircleDot] (sn___List) := symmDot[s1, sn]
generateGroup[generators : {{__} ..}, times_ : symmDot] /;
MatchQ[Dimensions[generators], {_, 1 | 2 | 3}] :=
Module[{group = generators, new},
While[
MatchQ[
new = Complement[
Apply[Join, {Outer[times, group, generators, 1],
Outer[times, generators, group, 1]}, {0, 1}] /.
Plus[n : (_Integer | _Rational), a__] :>
Plus[Mod[n, 1], a],
group](* // Echo[#, "|new| ", Length@#&]&*),
{__}],
group = Join[group, new](* // Echo[#, "|group| ", Length]&*)
];
Sort @ group
]
I use formal symbols, such as \[FormalX]
, so that they are guaranteed to be without a value.
Taking the space group Pcc2 (No. 27) as an example, there are two generators:
In[7]:= elements = generateGroup[{{-\[FormalX], -\[FormalY], -\[FormalZ]},
{\[FormalX], -\[FormalY], \[FormalZ] + 1/2}}]
Out[7]= {{-\[FormalX], -\[FormalY], -\[FormalZ]}, {-\[FormalX], \[FormalY],
1/2 - \[FormalZ]}, {\[FormalX], -\[FormalY],
1/2 + \[FormalZ]}, {\[FormalX], \[FormalY], \[FormalZ]}}
The multiplication table can be generated with Outer
:
In[8]:= mulTable = Outer[symmDot, elements, elements, 1]
Out[8]= {{{\[FormalX], \[FormalY], \[FormalZ]}, {\[FormalX], -\
\[FormalY], 1/2 + \[FormalZ]}, {-\[FormalX], \[FormalY],
1/2 - \[FormalZ]}, {-\[FormalX], -\[FormalY], -\[FormalZ]}}, {{\
\[FormalX], -\[FormalY], -(1/
2) + \[FormalZ]}, {\[FormalX], \[FormalY], \[FormalZ]}, {-\
\[FormalX], -\[FormalY], 1 - \[FormalZ]}, {-\[FormalX], \[FormalY],
1/2 - \[FormalZ]}}, {{-\[FormalX], \[FormalY], -(1/
2) - \[FormalZ]}, {-\[FormalX], -\[FormalY], -\[FormalZ]}, {\
\[FormalX], \[FormalY], 1 + \[FormalZ]}, {\[FormalX], -\[FormalY],
1/2 + \[FormalZ]}}, {{-\[FormalX], -\[FormalY], -\[FormalZ]}, {-\
\[FormalX], \[FormalY], 1/2 - \[FormalZ]}, {\[FormalX], -\[FormalY],
1/2 + \[FormalZ]}, {\[FormalX], \[FormalY], \[FormalZ]}}}
And displayed with TableForm
:
TableForm[mulTable, TableHeadings -> {elements, elements},
TableDepth -> 2]
