Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
 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
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
 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)
Exemplo n.º 6
0
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)
Exemplo n.º 7
0
 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
Exemplo n.º 8
0
    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
Exemplo n.º 9
0
 def test_close_to_zero(self):
     self.data.fill(1e-20)
     res = ut.clean_complex(self.data)
     self.assertEqual(self.data, res)
Exemplo n.º 10
0
 def test_matrix_mixed_ones(self):
     self.data.fill(1.j + 1.)
     res = ut.clean_complex(self.data)
     self.assertEqual(self.data, res)