Skip to content

Commit 392a6b9

Browse files
inplement number field with all square roots
define a unitary version of the SGA DFT By ensuring every representation of G is unitary, the overall DFT can be made unitary by including \sqrt{d_\rho/|G|} in front of each Fourier coefficient. To make the rep'ns unitary, we make use of Weyl's unitary trick. Rather than using Gram-Schmidt orthonormalization, we opt to compute the "sum of squares" matrix P = \sum_{g \in G} \rho(g)\rho(g)*dg and set Q=\sqrt{P} where Q is the principal square root. use self.group() instead of G remove a def lines maintaining readability include form option for "unitary" remove whitespace remove whitespace in doctest remove all whitespace Revert "remove all whitespace" This reverts commit b6d289c. remove all whitespace one line before nested def more whitespace proper usage of order, cardinality, degree for 1/|G|, should use G.cardinality for n, one should use n = G.degree() simplify the output which is in symbolic ring SR compute a square root in the base ring of Q note Q is the change-of-basis matrix making the representation unitary. when we extend to positive characteristic, we will need to ensure square roots are computable in that field simplify conjugate_transpose_pos_char remove .simplify_full() from doctest need to be computing square roots in some ring. some problems may be occurring if the working over the symbolic ring just use sqrt manually use principal_square_root need to ensure that the resulting matrix is defined over some field rather than just the SymbolicRing. use self instead of "SGA" remove blank line before def remove whitespace add blank line before def just remove comments self instead of SGA just return with simplify_full() for now working over a ring which contains all required square roots will take some time slight difference in expected output change polynomial ring notation to remove lint error work over a number field when working over \Q or extensions thereof, we need to ensure all required square roots are available. precompute a field extension of self.base_ring() containing all roots, which are the roots on the diagonal in the unitary change-of-basis matrix square root, as well as the unitary factors \sqrt{d_\rho/|G|}.
1 parent 79c047c commit 392a6b9

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

src/sage/combinat/symmetric_group_algebra.py

+59
Original file line numberDiff line numberDiff line change
@@ -2068,8 +2068,67 @@ def dft(self, form=None, mult='l2r'):
20682068
return self._dft_seminormal(mult=mult)
20692069
if form == "modular":
20702070
return self._dft_modular()
2071+
if form == "unitary":
2072+
return self._dft_unitary()
20712073
raise ValueError("invalid form (= %s)" % form)
20722074

2075+
def _dft_unitary(self):
2076+
"""
2077+
Return the unitary form of the discrete Fourier transform for ``self``.
2078+
2079+
EXAMPLES::
2080+
2081+
sage: QS3 = SymmetricGroupAlgebra(QQ, 3)
2082+
sage: QS3._dft_unitary()
2083+
[-1/6*sqrt2*sqrt3 -1/6*sqrt2*sqrt3 -1/6*sqrt2*sqrt3 -1/6*sqrt2*sqrt3 -1/6*sqrt2*sqrt3 -1/6*sqrt2*sqrt3]
2084+
[ -1/3*sqrt3 0 1/2 1/6*sqrt3 1/6*sqrt3 -1/2]
2085+
[ 0 -1/3*sqrt3 1/6*sqrt3 1/2 -1/2 1/6*sqrt3]
2086+
[ 0 -1/3*sqrt3 1/6*sqrt3 -1/2 1/2 1/6*sqrt3]
2087+
[ -1/3*sqrt3 0 -1/2 1/6*sqrt3 1/6*sqrt3 1/2]
2088+
[-1/6*sqrt2*sqrt3 1/6*sqrt2*sqrt3 1/6*sqrt2*sqrt3 -1/6*sqrt2*sqrt3 -1/6*sqrt2*sqrt3 1/6*sqrt2*sqrt3]
2089+
"""
2090+
from sage.matrix.special import diagonal_matrix
2091+
from sage.misc.functional import sqrt
2092+
from sage.misc.flatten import flatten
2093+
2094+
def all_roots_field():
2095+
required_square_roots = []
2096+
for partition in Partitions(self.group().degree()):
2097+
specht_module = self.specht_module(partition)
2098+
rho = specht_module.representation_matrix
2099+
group_size = self.group().cardinality()
2100+
P = (1/group_size)*sum(rho(g)*rho(g).conjugate().transpose() for g in self.group())
2101+
d, L = P.eigenmatrix_left()
2102+
required_square_roots += [specht_module.dimension(),self.group().cardinality()] + d.diagonal()
2103+
required_square_roots = flatten([[QQ(q).numerator(),QQ(q).denominator()] if q in QQ else q for q in required_square_roots])
2104+
K = self.base_ring()
2105+
for n in set(required_square_roots):
2106+
R = PolynomialRing(K, 'x')
2107+
x = R.gen()
2108+
if (x**2 - n).is_irreducible():
2109+
gen_name = "sqrt"+str(n).replace("/","over")
2110+
K = K.extension(sqrt(n).minpoly(),names=gen_name)
2111+
return K
2112+
2113+
def unitary_change_of_basis(partition,K):
2114+
rho = self.specht_module(partition).representation_matrix
2115+
group_size = self.group().cardinality()
2116+
P = (1/group_size)*sum(rho(g)*rho(g).conjugate().transpose() for g in self.group())
2117+
d, L = P.eigenmatrix_left()
2118+
return L.inverse() * diagonal_matrix([sqrt(K(a)) for a in d.diagonal()]) * L
2119+
2120+
def hat(f,partition,K):
2121+
specht_module = self.specht_module(partition)
2122+
rho = specht_module.representation_matrix
2123+
Q = unitary_change_of_basis(partition,K)
2124+
unitary_factor = specht_module.dimension()/self.group().cardinality()
2125+
sqrt_unitary_factor = sqrt(K(unitary_factor))
2126+
return sqrt_unitary_factor*sum(f(g)*Q.inverse()*rho(g)*Q for g in self.group())
2127+
2128+
K = all_roots_field()
2129+
delta = lambda s: lambda t: 1 if t == s else 0
2130+
return matrix(K,[flatten([hat(delta(g),partition,K).list() for partition in Partitions(self.group().degree())]) for g in self.group()]).transpose()
2131+
20732132
def _dft_seminormal(self, mult='l2r'):
20742133
"""
20752134
Return the seminormal form of the discrete Fourier transform for ``self``.

0 commit comments

Comments
 (0)