# Obtain a minimal set of parameters from a large number of rules

### Problem statement

I have a matrix $$D(\vec{k})=\sum_\vec{R}\tilde{D}(\vec{R})\cos(\vec{k}\cdot\vec{R})$$ where $\vec{R}$ is summed over all atoms positions and $\tilde{D}$ are 3x3 matrices. $D(k)$ is called the dynamical matrix in solid state physics.

We have several rules for the $\tilde{D}$ matrices. (ref. Ashcroft and Mermin, Solid State Physics)

1. All the $\tilde{D}$ matrices are symmetric.
2. $\sum_{\vec{R}}\tilde{D}(\vec{R})=0$
3. $X^T\tilde{D}(X\vec{R})X = \tilde{D}(\vec{R}) \;\forall\; X,\vec{R}$ where $X$ is a symmetry matrix for the lattice.

The task is to find a minimal set out of $\{\tilde{D}_{ij}(\vec{R})\}$ (not considering linear combinations) which can be used to express $D(\vec{k})$.

### Attempt

reciprocalBasis[basis_] :=
Table[2 \[Pi] (
basis[[Mod[i + 1, 3] + 1]]\[Cross]basis[[Mod[i + 2, 3] + 1]])/
(basis[[1]].(basis[[2]]\[Cross]basis[[3]])), {i, 1, 3}];
Generate[Rs_] :=
Union[Flatten[
Table[Dot[Rs[[i]], Rs[[j]]], {i, 1, Length[Rs]}, {j, 1,
Length[Rs]}], 1]]
fccStandardBasis = a*{{0, 1/2, 1/2}, {1/2, 0, 1/2}, {1/2, 1/2, 0}};
(* a > 0 is the lattice constant*)
one = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
Rxy = {{0, 1, 0}, {-1, 0, 0}, {0, 0, 1}};
Rxz = {{0, 0, 1}, {0, 1, 0}, {-1, 0, 0}};
Inv = -1*one;
fccRbase = {one, Rxy, Rxz, Inv};
fccSymmetries = FixedPoint[Generate, fccRbase];
fccAtom = Prepend[Union[Map[#.fccStandardBasis[[1]] &, fccSymmetries]], {0,0,0}];
(*Atoms upto first nearest neighbours*)

DtildeMat[R_] := {
{Dtilde[R][1][1], Dtilde[R][1][2], Dtilde[R][1][3]},
{Dtilde[R][1][2], Dtilde[R][2][2], Dtilde[R][2][3]},
{Dtilde[R][1][3], Dtilde[R][2][3], Dtilde[R][3][3]}
};

DtildesList = Map[DtildeMat, fccAtom];
DMatDefn[kx_, ky_, kz_] :=
Plus @@ Map[DtildeMat[#]*Cos[ {kx, ky, kz} . #] &, fccAtom];
rulesRotation = {};
For[j = 1, j <= Length[fccAtom], j++,
d = DtildeMat[fccAtom[[j]]];
For[i = 1, i <= Length[fccSymmetries], i++,
rotMat = fccSymmetries[[i]];
eqns = (Transpose[rotMat].DtildeMat[rotMat.fccAtom[[j]]].rotMat ==
d) // Simplify;
rulesRotation =
Prepend[rulesRotation, ToRules[Reduce[eqns] // Simplify]];
]
]
Clear[DMat]
DMat[kx_, ky_, kz_] :=
Simplify[DMatDefn[kx, ky, kz] //.
Flatten[Join[rulesRotation,
Simplify[ToRules[Reduce[Plus @@ DtildesList == 0]], a > 0]]], a > 0]


After this, one might expect that the minimal set of parameters can be found as:

params = Select[Union[
Flatten[
Table[Simplify[Variables[DMat[kx, ky, kz][[i]][[j]]], a > 0],
{i, 1, 3}, {j, 1, 3}]]
], StringContainsQ[ToString[#], "Dtilde"] &]


This gives a list of length 4:

{Dtilde[{a/2, -(a/2), 0}][1][2], Dtilde[{a/2, a/2, 0}][1][2],
Dtilde[{a/2, a/2, 0}][2][2], Dtilde[{a/2, a/2, 0}][3][3]}


### Issue

The final result is not a minimal set of parameters. It can be easily checked: DMat[0,0,0] gives a zero matrix (as it should because of rule 2. earlier) but DMat[kx,ky,kz]/.{kx->0,ky->0,kz->0} gives off-diagonal terms containing Dtilde[{a/2, -(a/2), 0}][1][2]+Dtilde[{a/2, a/2, 0}][1][2]. So the minimal set of parameters should be at most 3 in size, whereas my approach is giving the answer to be 4.

I suspect this issue is arising because //. only works till a fixed point is reached, which might not necessarily be the one with minimal number of parameters.

The ideal solution should work for a general sum over $\vec{R}$, not just the nearest neighbour example considered here.