1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
| import numpy as np
class ReduceGroupRepresentation: def __init__(self) -> None: pass
def reduce_representation(self, group_rep: list[np.ndarray], tol=1e-12) -> list[list[np.ndarray]]: """ Reduce a given group representation into its irreducible components. @param group_rep: List of numpy arrays representing the group representation matrices. @param tol: Tolerance for numerical comparisons. @return: List of lists, where each sublist contains numpy arrays representing an irreducible representation. """ self.irrep = [] self.conj_table = [] self.__reduce_representation_impl(group_rep, tol) return self.irrep
def __add_to_irr_rep(self, rep: list[np.ndarray]): """ Add a new irreducible representation if it is not already present. @param rep: List of numpy arrays representing the irreducible representation matrices. """ conj_table = [] for Dg in rep: conj_table.append(np.trace(Dg)) for i, table in enumerate(self.conj_table): if np.allclose(table, conj_table): return self.conj_table.append(conj_table) self.irrep.append(rep)
def __reduce_representation_impl(self, group_rep: list[np.ndarray], tol=1e-12): """ Reduce a given group representation into its irreducible components. @param group_rep: List of numpy arrays representing the group representation matrices. @param tol: Tolerance for numerical comparisons. @return: List of lists, where each sublist contains numpy arrays representing an irreducible representation.
Note: This implementation uses the Dixon method for reducing representations. """
dim = group_rep[0].shape[0] assert all(mat.shape == (dim, dim) for mat in group_rep), "All representation matrices must have the same dimensions."
is_irr = self.is_irr_rep(group_rep, tol) print(f"Is irreducible: {is_irr}") if is_irr: self.__add_to_irr_rep(group_rep) return
res_reps = self.__decompose_into_block(group_rep, tol)
for rep in res_reps: self.__reduce_representation_impl(rep, tol)
def __get_hermitian_basis(self, r, s, dim): """ Get a Hermitian basis matrix with 1 at (r,s) and (s,r) positions. @param r: Row index. @param s: Column index. @param dim: Dimension of the square matrix. @return: Hermitian basis matrix. """ hermitian_basis = np.zeros((dim, dim), dtype=complex) if r == s: hermitian_basis[r, s] = 1 elif r > s: hermitian_basis[r, s] = 1 hermitian_basis[s, r] = 1 else: hermitian_basis[r, s] = 1j hermitian_basis[s, r] = -1j return hermitian_basis
def __decompose_into_block(self, group_rep: list[np.ndarray], tol=1e-12) -> list[list[np.ndarray]]: """ Decompose a group representation into block diagonal form. @param group_rep: List of numpy arrays representing the group representation matrices. @param tol: Tolerance for numerical comparisons. @return: List of lists, where each sublist contains numpy arrays representing a block of the representation. """ dim = group_rep[0].shape[0] g_order = len(group_rep) mat_sum = [] found_hermtian_basis = False for r in range(dim): if found_hermtian_basis: break for s in range(dim): mat_sum = np.zeros((dim, dim), dtype=complex) hermitian_basis = self.__get_hermitian_basis(r, s, dim) for g in range(g_order): mat_sum += group_rep[g].conj().T @ hermitian_basis @ group_rep[g] if not np.allclose(mat_sum, np.trace(mat_sum) / dim * np.eye(dim), atol=tol): found_hermtian_basis = True break eigvals, eigvecs = np.linalg.eigh(mat_sum) print(eigvals) rep_vectors = [] for rep_mat in group_rep: rep_vectors.append(eigvecs.conj().T @ rep_mat @ eigvecs) block_sizes = [] last_idx = 0 for i in range(1, dim): if eigvals[i] - eigvals[i-1] > tol: block_sizes.append(i - last_idx) last_idx = i if last_idx < dim: block_sizes.append(dim - last_idx) print("Block sizes:", block_sizes) res_reps = [] start_idx = 0 for size in block_sizes: sub_rep = [] for rep_mat in rep_vectors: sub_rep.append(rep_mat[start_idx:start_idx+size, start_idx:start_idx+size]) res_reps.append(sub_rep) start_idx += size return res_reps
def is_irr_rep(self, group_rep: list[np.ndarray], tol=1e-12) -> bool: """ Check if a given group representation is irreducible. @param group_rep: List of numpy arrays representing the group representation matrices. @param tol: Tolerance for numerical comparisons. @return: True if the representation is irreducible, False otherwise. Note: This implementation uses the character orthogonality relation to determine irreducibility. """ g_order = len(group_rep) dim = group_rep[0].shape[0] assert all(mat.shape == (dim, dim) for mat in group_rep), "All representation matrices must have the same dimensions."
charac_sum = 0 for g in range(g_order): charac_sum += np.abs(np.trace(group_rep[g]))**2 charac_sum /= g_order print(f"charac sum {charac_sum}") return np.abs(charac_sum - 1) < tol
if __name__ == "__main__": multi_table = [[1,2,3,4,5,6], [2,1,4,3,6,5], [3,5,1,6,2,4], [4,6,2,5,1,3], [5,3,6,1,4,2], [6,4,5,2,3,1]] from finite_group_rep import FiniteGroupRepresentation group = FiniteGroupRepresentation(multi_table) conj_class = group.find_conjugacy_classes() print("Conjugacy classes:", conj_class)
reg_rep = [] size = len(multi_table) for i in range(size): mat = np.zeros((size, size), dtype=int) for j in range(size): mat[multi_table[i][j]-1][j] = 1 reg_rep.append(mat) print("Regular representation matrices:") for mat in reg_rep: print(mat) import time start_time = time.time()
reducer = ReduceGroupRepresentation() irreps = reducer.reduce_representation(reg_rep) print(f"Found {len(irreps)} irreducible representations:") for i, irrep in enumerate(irreps): print(f"Irreducible Representation {i+1}: dim = {irrep[0].shape[0]}") for mat in irrep: print(mat)
end_time = time.time() print(f"Time taken: {end_time - start_time} seconds")
|