def subduce(self, group, j): # get the rotation angles of the conjugacy classes omegas = [_all_rotations[i].omega for i in group.rclass] omegas = np.asarray(omegas) # subduce spin j characters = np.zeros_like(omegas, dtype=complex) for k in range(int(2 * j + 1)): characters += np.exp(1.j * (j - k) * omegas) characters = utils.clean_complex(characters, self.prec) # calculate multiplicities multi = group.tchar.dot(characters * group.sclass) multi = np.real_if_close(np.rint(multi / float(group.order))) # check and yield the irrep check = multi.dot(group.tchar) if np.any((check - characters) > self.prec): print("characters:") print(characters) print("multiplicities:") print(multi) print("check = %r" % check) raise RuntimeError("subduction does not work!") for m, ir in zip(multi, group.instances): if m > self.prec: yield (m, ir)
def InsertCharTableRow(self, irrep): i = irrep.irid for k in range(self.nclasses): l = self.rclass[k] elem = irrep.mx[self.lrotations.index(l)] tr = utils.clean_complex(np.trace(elem, dtype=complex), self.prec) self.tchar[i, k] = tr
def multiplicityO3(self, group, j): # get the rotation angles omegas = [group.elements[a].omega() for a in group.crep] omegas = np.asarray(omegas) par = [group.elements[a].i for a in group.crep] par = np.asarray(par) # subduce spin j characters = np.zeros_like(omegas, dtype=complex) for k in range(int(2 * j + 1)): characters += np.exp(1.j * (j - k) * omegas) characters = utils.clean_complex(characters, self.prec) if j % 2: characters *= par # calculate multiplicities, # characters already contain the inversion, if enabled multi = group.tchar.dot(characters * group.cdim) multi = np.real_if_close(np.rint(multi / float(group.order))) # check and yield the irrep check = multi.dot(group.tchar) if np.any((check - characters) > self.prec): print("characters:") print(characters) print("multiplicities:") print(multi) print("check = %r" % check) raise RuntimeError("subduction does not work!") return multi
def gen_H(rotation): # compute a spin 3/2 rotation: # matrix elements according to # D.A. Varshalivich: Quantum Theory of Angular Momentum, # World Scientific, first reprint 1989, Table 4.25 prec = 1e-6 vector = rotation.get_vector() omega = rotation.get_omega() c = np.cos(omega / 2.) s = np.sin(omega / 2.) x, y, z = vector xp = x + 1.j * y xm = x - 1.j * y sq3 = np.sqrt(3) result = np.asarray( [[(c - 1.j * s * z)**3, -1.j * sq3 * s * xm * ((c - 1.j * s * z)**2), -sq3 * ((s * xm)**2) * (c - 1.j * s * z), 1.j * ((s * xm)**3)], [ -1.j * sq3 * s * xp * ((c - 1.j * s * z)**2), (1. - 3. * s * s * (x * x + y * y)) * (c - 1.j * s * z), -1.j * s * xm * (2. - 3. * s * s * (x * x + y * y)), -sq3 * ((s * xm)**2) * (c + 1.j * s * z) ], [ -sq3 * ((s * xp)**2) * (c - 1.j * s * z), -1.j * s * xp * (2. - 3. * s * s * (x * x + y * y)), (1. - 3. * s * s * (x * x + y * y)) * (c + 1.j * s * z), -1.j * sq3 * s * xm * ((c + 1.j * s * z)**2) ], [ 1.j * ((s * xp)**3), -sq3 * ((s * xp)**2) * (c + 1.j * s * z), -1.j * sq3 * s * xp * ((c + 1.j * s * z)**2), (c + 1.j * s * z)**3 ]]) return utils.clean_complex(result, prec)
def test_special_matrix(self): self.data = np.asarray([[complex(0.5, -0.5), complex(-0.5, -0.5)], [complex(0.5, -0.5), complex(0.5, 0.5)]]) res = ut.clean_complex(self.data, prec=1e-6) self.assertEqual(self.data, res)
def gen_G1(rotation): prec = 1e-6 vector = rotation.get_vector() omega = rotation.get_omega() result = np.cos(omega / 2) * _pauli_matrices[0] for i, p in enumerate(_pauli_matrices[1:]): result -= 1.j * np.sin(omega / 2) * vector[i] * p return utils.clean_complex(result, prec)
def calculate(self, group): basis = [] bmulti = np.zeros((self.maxj, len(self.dims)), dtype=int) for j in range(self.maxj): basis.append([]) num = self.multiplicityO3(group, j) for i, (ir, n) in enumerate(zip(group.irreps, num)): if n < 1: basis[-1].append(None) continue #basis[-1].append([]) bvec = self.calc_basis_vec(ir, j, self.dims[i], oldbase=basis[-1]) basis[-1].append(utils.clean_complex(bvec)) bmulti[j][i] += int(bvec.shape[0]) // int(self.dims[i]) return basis, bmulti
def _get_basis(self, irrep, multiplicity, j): indlml = self.get_lm_index(j, -j) indlmh = self.get_lm_index(j, j) for row in range(irrep.dim): if self.verbose > 0: print(" starting row %d ".center(40, "_") % row) m = j mult = 0 indir = self.get_ir_index(irrep.lirreps[irrep.irid], row) # get all possible base vectors and check for small entries b = self._bvecs(irrep, row, j) b = utils.clean_complex(b, self.prec) while m > -j - 1 and mult < multiplicity: if self.verbose > 0: print(" using m=%d, searching for multiplicity %d" % (m, mult)) _b = b[:, j + m] # set small values explicitly to 0 # check if all entries are zero norm = np.sqrt(np.vdot(_b, _b)) if norm < self.prec: if self.verbose > 0: print(" norm is zero, continuing") m -= 1 continue _b /= norm # check against already calculated basis accept = self._check_against_old(_b, (indlml, indlmh)) if accept == True: if self.verbose > 0: print(" accepted basis") self.basis[mult][indir][indlml:indlmh + 1] = _b mult += 1 else: if self.verbose > 0: print(" did not accept basis") m -= 1
def test_close_to_zero(self): self.data.fill(1e-20) res = ut.clean_complex(self.data) self.assertEqual(self.data, res)
def test_matrix_mixed_ones(self): self.data.fill(1.j + 1.) res = ut.clean_complex(self.data) self.assertEqual(self.data, res)