Esempio n. 1
0
    def transform_to_uncoupled(self):
        F = self.F
        mF = self.mF
        F1 = self.F1
        J = self.J
        I1 = self.I1
        I2 = self.I2

        mF1s = np.arange(-F1, F1 + 1, 1)
        mJs = np.arange(-J, J + 1, 1)
        m1s = np.arange(-I1, I1 + 1, 1)
        m2s = np.arange(-I2, I2 + 1, 1)

        uncoupled_state = State()

        for mF1 in mF1s:
            for mJ in mJs:
                for m1 in m1s:
                    for m2 in m2s:
                        amp = CG(J, mJ, I1, m1, F1, mF1).doit() * CG(
                            F1, mF1, I2, m2, F, mF).doit()
                        basis_state = UncoupledBasisState(
                            J, mJ, I1, m1, I2, m2)
                        uncoupled_state = uncoupled_state + State(
                            [(amp, basis_state)])

        return uncoupled_state.normalize()
Esempio n. 2
0
    def calc_beta(self):
        '''
        Method to calculate beta array to convert from blm to alm
        '''

        ## initialize beta array
        beta_vals = np.zeros(
            (self.alm_size, 2 * self.blm_size - self.blmax - 1,
             2 * self.blm_size - self.blmax - 1))

        for ii in range(beta_vals.shape[0]):
            for jj in range(beta_vals.shape[1]):
                for kk in range(beta_vals.shape[2]):

                    l1, m1 = self.idxtoalm(self.blmax, jj)
                    l2, m2 = self.idxtoalm(self.blmax, kk)
                    L, M = self.idxtoalm(self.almax, ii)

                    ## clebs gordon coeffcients
                    cg0 = (CG(l1, 0, l2, 0, L, 0).doit()).evalf()
                    cg1 = (CG(l1, m1, l2, m2, L, M).doit()).evalf()

                    beta_vals[ii, jj, kk] = np.sqrt(
                        (2 * l1 + 1) * (2 * l2 + 1) /
                        ((4 * np.pi) * (2 * L + 1))) * cg0 * cg1

        self.beta_vals = beta_vals
Esempio n. 3
0
 def transform_to_uncoupled(self):
     F = self.F 
     mF  = self.mF
     F1 = self.F1
     J = self.J
     I1 = self.I1
     I2 = self.I2
     electronic_state = self.electronic_state
     P = self.P
     Omega = self.Omega
     
     mF1s = np.arange(-F1,F1+1,1)
     mJs = np.arange(-J,J+1,1)
     m1s = np.arange(-I1,I1+1,1)
     m2s = np.arange(-I2,I2+1,1)
 
     uncoupled_state = State() 
     
     for mF1 in mF1s:
         for mJ in mJs:
             for m1 in m1s:
                 for m2 in m2s:
                     amp = (complex(CG(J, mJ, I1, m1, F1, mF1).doit()
                             *CG(F1, mF1, I2, m2, F, mF).doit()))
                     basis_state = UncoupledBasisState(J, mJ, I1, m1, I2, m2, P = P, Omega=Omega, electronic_state = electronic_state)
                     uncoupled_state = uncoupled_state + State([(amp, basis_state)])
     
     return uncoupled_state.normalize()
Esempio n. 4
0
    def calc_component(self, j, mj, l, ml, s, ms):
        def _r1(rm, p, p1, p2):
            if self.p1 == 0:
                return 0., 0.
            k = rm.dot(p1)
            kn = np.vdot(k, k)
            theta = np.arccos(k[2]/kn)
            phi = np.arctan2(k[1], k[0])
            return theta, phi

        _s1, _s2 = int(2*self.s1+1), int(2*self.s2+1)
        # sympy uses its on version of float, convert to normal floats
        c1 = float(CG(s, ms, l, ml, j, mj).doit())
        res = np.zeros((self.mlength,_s1, _s2), dtype=complex)
        for m1, m2 in it.product(range(_s1), range(_s2)):
            c2 = float(CG(self.s1, m1-self.s1, self.s2, m2-self.s2, s, ms).doit())
            #for i, ang in zip(self.rot_index[0], self.angles):
            #    res[i,m1,m2] += c2*sp.sph_harm(ml, l, ang[0], ang[1]).conj()
            for i, q in enumerate(self.elements):
                #rm = q.rotation_matrix(inv=True)
                for j, pvecs in enumerate(self.allmomenta):
                    #theta, phi = _r1(rm, *pvecs)
                    _r = self.rot_index[j, i]
                    theta, phi = self.angles[j,i]
                    res[_r,m1,m2] += c2*sp.sph_harm(ml, l, theta, phi).conj()
        return c1*res
def overlap_mpmq(pp, theta, Ms, MJ, phi, lam):  #overlap of -p-q/2
    if lam == 100:
        return math.sqrt(2./Pi)* sum(
                                    sph_harmY(L, MJ-Ms, theta_prime2(pp, theta), phi+Pi)*\
                                    float(CG(S(L), S(MJ - Ms), S(1), S(Ms), 1, MJ).doit())*(I**L)*\
                                    psi_interpolated[L](np.sqrt(pp**2 + pp* qq* np.cos(theta)+ qq**2/4))/norm
                                    for L in range(0,3,2)
                                    )
    if lam == 2:
        return math.sqrt(2./Pi)* sum(
                                    sph_harmY(L, MJ-Ms, theta_prime2(pp, theta), phi+Pi)*\
                                    float(CG(S(L), S(MJ - Ms), S(1), S(Ms), 1, MJ).doit())*(I**L)*\
                                    psi_interpolated2[L](np.sqrt(pp**2 + pp* qq* np.cos(theta)+ qq**2/4))/norm2
                                    for L in range(0,3,2)
                                    )
Esempio n. 6
0
def comp_sph_harm_to_relativistic_harm(dim_ms):
    '''transformation matrix from spin-complex spherical harmonics
    (orbital fast) to relativistic harmonics
    '''
    csh2relh = np.zeros((dim_ms, dim_ms), dtype=complex)
    dim_m = dim_ms // 2
    l = dim_m // 2
    # set the orbital index
    iy = range(dim_m)
    for i in range(l):
        iy += [iy.pop(0)]
    # add slow spin index
    # for spin: up, then dn. wien2k convention.
    iys = {0.5: iy, -0.5: [iy[i] + dim_m for i in range(dim_m)]}
    # j=l-1/2 block
    # relativistic_harmonics index
    i_jm = -1
    for i in [-0.5, 0.5]:
        _j = l + i
        for mj in np.arange(-_j, _j + 1):
            i_jm += 1
            for s in [-0.5, 0.5]:
                csh2relh[iys[s][int(round(mj-s))], i_jm] = \
                        CG(l,mj-s,0.5,s,_j,mj).doit()
    return csh2relh
Esempio n. 7
0
def _cg(l1, l2, L):
    """Computes CG coefficients from sympy
    <l1 m1; l2 m2| L M>
    and converts them to numerical values.
    Returns a full (2 * l1 + 1, 2 * l2 + 1, 2 * L + 1) array, which
    is mostly zeros.
    """
    try:
        from sympy.physics.quantum.cg import CG
    except ModuleNotFoundError:
        raise ModuleNotFoundError(
            "Calculation of Clebsch-Gordan coefficients requires a sympy installation"
        )

    rcg = np.zeros((2 * l1 + 1, 2 * l2 + 1, 2 * L + 1), dtype=np.double)
    if np.abs(l1 - l2) > L or np.abs(l1 + l2) < L:
        return rcg
    for m1 in range(-l1, l1 + 1):
        for m2 in range(-l2, l2 + 1):
            if np.abs(m1 + m2) > L:
                continue
            rcg[l1 + m1, l2 + m2, L + (m1 + m2)] += np.double(
                CG(l1, m1, l2, m2, L, m1 + m2).doit()
            )
    return rcg
Esempio n. 8
0
def get_coefficients(j3, m3, cutoff=3):
    """Reverse Clebsch-Gordan coupling

    This function returns a list of a list with all quantum numbers and
    coefficients leading to a fixed J,M combination

    Arguments
    ---------
    j3, m3: integers, Right hand side of CG-coefficients: <j1 j2 m1 m2|j3 m3>
    cutoff: (optional) integer, cutoff where to stop looking for couplings

    Returns
    -------
    sqm: a list of lists for each combination j1,j2,m1,m2, CG-coeff found for j3
         and m3
    """
    # Perhaps a 2d numpy array is better suited, no that needs to be fixed
    # length
    # List of lists: Each inner list holds j1,j2,m1,m2 and the coefficient
    sqm = []
    for j1 in range(0, cutoff):
        for j2 in range(0, cutoff):
            #Check boundaries of j3
            if np.abs(j1 - j2) <= j3 and j1 + j2 >= j3:
                for m1 in range(-j1, j1 + 1):
                    for m2 in range(-j2, j2 + 1):
                        if m1 + m2 == m3:
                            sqm.append([
                                j1, j2, m1, m2,
                                CG(j1, m1, j2, m2, j3, m3).doit()
                            ])

    return sqm
Esempio n. 9
0
def Clebsch(j1, m1, j2, m2, J, M) : 
  """
    Return Clebsch-Gordan coefficient. Note that all arguments should be multiplied by 2
    (e.g. 1 for spin 1/2, 2 for spin 1 etc.). Needs sympy.
  """
  from sympy.physics.quantum.cg import CG
  from sympy import Rational
  return CG(Rational(j1,2), Rational(m1,2), Rational(j2,2), Rational(m2,2), Rational(J,2), Rational(M,2) ).doit().evalf()
Esempio n. 10
0
def _clebsch_gordan_coefficient(recipe: dict) -> float:
    return (CG(
        recipe["j1"],
        recipe["m1"],
        recipe["j2"],
        recipe["m2"],
        recipe["J"],
        recipe["M"],
    ).doit().evalf())
Esempio n. 11
0
def cg_coef(jb, jc, mb, mc, ja, ma):
    """
    It returns the CG coefficient :math:`\\langle j_bm_bj_cm_c|j_am_a\\rangle`, as in a decay from particle *a* to *b*
    and *c*. It will either call **sympy.physics.quantum.cg()** or **get_cg_coef()**.
    """
    if has_sympy:
        return float(CG(jb, mb, jc, mc, ja, ma).doit().evalf())
    else:
        return get_cg_coef(jb, jc, mb, mc, ja, ma)
Esempio n. 12
0
def test_doit():
    assert (Wigner3j(S.Half, Rational(-1, 2), S.Half, S.Half, 0,
                     0).doit() == -sqrt(2) / 2)
    assert Wigner6j(1, 2, 3, 2, 1, 2).doit() == sqrt(21) / 105
    assert Wigner6j(3, 1, 2, 2, 2, 1).doit() == sqrt(21) / 105
    assert (Wigner9j(2, 1, 1, Rational(3, 2), S.Half, 1, S.Half, S.Half,
                     0).doit() == sqrt(2) / 12)
    assert CG(S.Half, S.Half, S.Half, Rational(-1, 2), 1,
              0).doit() == sqrt(2) / 2
Esempio n. 13
0
def test_doit():
    assert Wigner3j(1 / 2, -1 / 2, 1 / 2, 1 / 2, 0, 0).doit() == -sqrt(2) / 2
    assert Wigner6j(1, 2, 3, 2, 1, 2).doit() == sqrt(21) / 105
    assert Wigner9j(2, 1, 1,
                    S(3) / 2,
                    S(1) / 2, 1,
                    S(1) / 2,
                    S(1) / 2, 0).doit() == sqrt(2) / 12
    assert CG(1 / 2, 1 / 2, 1 / 2, -1 / 2, 1, 0).doit() == sqrt(2) / 2
Esempio n. 14
0
def get_decay_part(decay, ls, lambda_list, symbol_list):
    """
    .. math::
        \\sqrt{\\frac{ 2 l + 1 }{ 2 j_a + 1 }}
        \\langle j_b, j_c, \\lambda_b, - \\lambda_c | s, \\lambda_b - \\lambda_c \\rangle
        \\langle l, s, 0, \\lambda_b - \\lambda_c | j_a, \\lambda_b - \\lambda_c \\rangle

    .. math::
        D_{\\lambda_a, \\lambda_b - \\lambda_c}^{J_{A}*} (\\phi, \\theta, 0)

    """
    a = decay.core
    b, c = decay.outs
    l, s = ls
    lambda_list = {k: spin_int(v) for k, v in lambda_list.items()}
    delta = lambda_list[b] - lambda_list[c]
    if abs(delta) > a.J:
        return 0
    d_part = WignerD(
        spin_int(a.J),
        lambda_list[a],
        delta,
        symbol_list[decay]["alpha"],
        symbol_list[decay]["beta"],
        0,
    )
    # print(lambda_list)
    cg_part = sym.sqrt((2 * l + 1)) / sym.sqrt((2 * spin_int(a.J) + 1))
    cg_part = cg_part * CG(l, 0, spin_int(s), delta, spin_int(a.J), delta)
    cg_part = cg_part * CG(
        spin_int(b.J),
        lambda_list[b],
        spin_int(c.J),
        -lambda_list[c],
        spin_int(s),
        delta,
    )
    return simplify(d_part.conjugate() * cg_part)
Esempio n. 15
0
def cg_prod(jmag, jpol, mpol, fac=2, log=None):
    r'''Compute a single coefficient :math:`<\vec{j}\vec{m}|\vec{j}\vec{j}^\prime>`,
        where :math:`\sum_k j_k^\prime=j_{\rm{tot}}`, :math:`\sum_k m_k=m_{\rm{tot}}`,
        and :math:`-j_{\rm{tot}}\le m_{\rm{tot}}\le j_{\rm{tot}}` by multiplying Clebsch-Gordan coefficients.

        Args:
            jmag: list of N nonnegative spin magnitudes, :math:`\vec{j}`
            jpol: list of N spin magnitude couplings from left to right
                Must have jcoup[0] == jmag[0] and sum (jcoup[:k]) >= 0 for all k<N
            mpol: list of N spin polarizations, -sum (jcoup) <= sum (mpol) <= sum(jcoup)

        Kwargs:
            fac: integer
                Divide jmag, jpol, and mpol by this to get the actual quantum #s.
                Default (2) means that you actually provided 2*j, 2*m, etc., so
                as to avoid data type ambiguities and floating-point rounding
                issues with half-integer quantum numbers. (Internally, everything
                is multiplied by 2 until we get to the actual Clebsch-Gordan
                cruncher.)
            log: PySCF logger object
                For logging output

        Returns:
            coeff: floating-point
    '''
    ### Throat-clearing ###
    fac = 2 // fac
    jmag = np.around(np.asarray(jmag) * fac).astype(np.int32)
    jpol = np.around(np.asarray(jpol) * fac).astype(np.int32)
    mpol = np.around(np.asarray(mpol) * fac).astype(np.int32)
    _assert_j2m2(jmag, jpol, True)
    _assert_j2m2(jmag, mpol, False)
    mtot = mpol.sum()
    jtot = jpol.sum()
    assert (mtot in range(-jtot, jtot + 1, 2)), 'mpol and jpol mismatch'
    if log is None: log = logger.Logger(verbose=logger.DEBUG4)

    coeff = S(1)
    jrun = np.cumsum(jpol)
    mrun = np.cumsum(mpol)
    for i in range(1, len(jmag)):
        coeff *= CG(
            S(jrun[i - 1]) / 2,
            S(mrun[i - 1]) / 2,  # j1, m1
            S(jmag[i]) / 2,
            S(mpol[i]) / 2,  # j2, m2
            S(jrun[i]) / 2,
            S(mrun[i]) / 2).doit()  # j3, m3 = m1 + m2
    return coeff.evalf()
Esempio n. 16
0
 def _recurse(m2a_str, coeffs_in, j2, m2c_max, m2c_min):
     m2c_str = []
     coeffs_out = []
     logger.debug4(
         log,
         'Entering _recurse with {} strings, {} coeffs, and {} <= m2c <= {}'
         .format(len(m2a_str), len(coeffs_in), m2c_min, m2c_max))
     for m2a_vec, coeff in zip(m2a_str, coeffs_in):
         m2a = m2a_vec.sum()
         m2b_max = min(m2c_max - m2a, j2[1])
         m2b_min = max(m2c_min - m2a, -j2[1])
         logger.debug4(
             log,
             'For this string, {} <= m2b <= {}'.format(m2b_min, m2b_max))
         for m2b in range(m2b_min, m2b_max + 1, 2):
             m2c = m2a + m2b
             m2 = np.array([m2a, m2b, m2c])
             cgfac = CG(
                 S(j2[0]) / 2,
                 S(m2a) / 2,
                 S(j2[1]) / 2,
                 S(m2b) / 2,
                 S(j2[2]) / 2,
                 S(m2c) / 2).doit()
             logger.debug4(
                 log, 'Computing <{},{};{},{}|{},{}> = {}'.format(
                     str(S(j2[0]) / 2), str(S(m2a) / 2), str(S(j2[1]) / 2),
                     str(S(m2b) / 2), str(S(j2[2]) / 2), str(S(m2c) / 2),
                     str(cgfac)))
             m2c_str.append(np.append(m2a_vec, m2b))
             try:
                 coeffs_out.append(float(coeff * cgfac.evalf()))
             except TypeError as e:
                 assert (j2.sum() %
                         2 == 0), 'Coupling parity error? {}'.format(j2)
     return m2c_str, coeffs_out
Esempio n. 17
0
def cg_matrix(n_l):
    """ Returns the Clebsch-Gordan coefficients for maximum angular momentum n_l-1
    """
    lmax = n_l - 1
    cgs = np.zeros([n_l, 2 * lmax + 1, n_l, 2 * lmax + 1, n_l, 2 * lmax + 1],
                   dtype=complex)

    for l in range(n_l):
        for l1 in range(n_l):
            for l2 in range(n_l):
                for m in range(-n_l, n_l + 1):
                    for m1 in range(-n_l, n_l + 1):
                        for m2 in range(-n_l, n_l + 1):
                            # cgs[l1,l2,l,m1,m2,m] = N(CG(l1,l2,l,m1,m2,m).doit())
                            cgs[l1, m1, l2, m2, l,
                                m] = N(CG(l1, m1, l2, m2, l, m).doit())
    return cgs
Esempio n. 18
0
def clebsch2(j1, m1, j2, m2, j3, m3):
    """
  Computes <j1 m1 j2 m2 | j3 m3>, where all spins are given as double their values (contrary to the usual convention in this code).
  """
    # https://docs.sympy.org/latest/modules/physics/quantum/cg.html
    # https://mattpap.github.io/scipy-2011-tutorial/html/numerics.html
    # This is kind of silly, using a symbolic math package to compute these things numerically, but I couldn't find a convenient
    # numerical routine for this that was licensed appropriately and packaged for ubuntu.
    # Performance is actually fine, because this is memoized. We take a ~1 second hit in startup time just from loading sympy.
    # Looking for a better alternative: https://scicomp.stackexchange.com/questions/32744/plug-and-go-clebsch-gordan-computation-in-python
    return CG(
        sympy.S(j1) / 2,
        sympy.S(m1) / 2,
        sympy.S(j2) / 2,
        sympy.S(m2) / 2,
        sympy.S(j3) / 2,
        sympy.S(m3) / 2).doit().evalf()
def CalcTensor(Cx, l, l1, l2):
    Ten = [[0 for x in range(1)] for x in range(2 * l + 1)]
    result = 0
    #if (l>(l1+l2) or l<abs(l1-l2)):
    # print('Invalid tensor')
    # Ten = -1
    if (l1 == 0):
        s1 = 1
    elif (l1 == 2):
        s1 = 4
    elif (l1 == 4):
        s1 = 11
    elif (l1 == 6):
        s1 = 22
    elif (l1 == 8):
        s1 = 37

    if (l2 == 0):
        s2 = 1
    elif (l2 == 2):
        s2 = 4
    elif (l2 == 4):
        s2 = 11
    elif (l2 == 6):
        s2 = 22
    elif (l2 == 8):
        s2 = 37

    #column of length 2l+1
    jj = 0
    for m in range(-l, l + 1):
        for m1 in range(-l1, l1 + 1):
            for m2 in range(-l2, l2 + 1):
                el = float(CG(l1, m1, l2, m2, l, m).doit())
                Ten[jj][0] = Ten[jj][0] + el * np.conjugate(
                    Cx[m1 + s1 - 1]) * np.conjugate(Cx[m2 + s2 - 1])
        jj = jj + 1
    return Ten
Esempio n. 20
0
def compute_cg_matrix(k, l):
    """
    Computes the matrix that block-diagonilizes the Kronecker product of Wigner D matrices of degree k and l respectively
    Output size (2k+1)(2l+1)x(2k+1)(2l+1)
    """
    c_kl = np.zeros([(2 * k + 1) * (2 * l + 1), (2 * k + 1) * (2 * l + 1)])

    n_off = 0
    for J in range(abs(k - l), k + l + 1):
        m_off = 0
        for m1_i in range(2 * k + 1):
            m1 = m1_i - k
            for m2_i in range(2 * l + 1):
                m2 = m2_i - l
                for n_i in range(2 * J + 1):
                    n = n_i - J
                    if m1 + m2 == n:
                        c_kl[m_off + m2_i,
                             n_off + n_i] = CG(k, m1, l, m2, J,
                                               m1 + m2).doit()
            m_off = m_off + 2 * l + 1
        n_off = n_off + 2 * J + 1

    return c_kl
Esempio n. 21
0
def CGmatrix_to_file(SA,SB,S,directory):
    ##Define a ClebschGordan matrix using sympy library, returns  an array of tuples, (p,q,CG(SA,MA[q],SB,MB[q],S,M[p])) 
    ##which can be converted into the desired matrix  matrix that changes for |S,M> basis to |SA,MA;SB,MB>
    if S > SA+SB:
        raise Exception('S should be less than SA+SB')
    ##directory='data/CGmats/'
    if not os.path.exists(directory):
        os.makedirs(directory)
    filename=directory+'CGmat_SA_'+str(float(SA))+'_SB_'+str(float(SB))+'_S_'+str(float(S))+'.hdf5'
    if not os.path.exists(filename):   
        cgmat_data=[]
        MAarr=np.matlib.repmat(np.linspace(-SA,SA,int(2*SA+1)),1,int(2*SB+1))[0,:]
        MBarr=np.reshape(np.matlib.repmat(np.linspace(-SB,SB,int(2*SB+1)),int(2*SA+1),1),(1,int((2*SA+1)*(2*SB+1))),order='F')[0,:]
        Marr=np.linspace(-S,S,int(2*S+1))
        for p in range(np.size(Marr)):
            Msumlist=np.where(MAarr+MBarr==Marr[p])[0]
            #print(p, end='\r', flush=True)
            for q in Msumlist:
                    cgmat_data.append([p,q,CG(SA,MAarr[q],SB,MBarr[q],S,Marr[p]).doit().evalf()])
        cgmat_datanp=np.array([cgmat_data_i for cgmat_data_i in cgmat_data])
        cgmat_datanpf=cgmat_datanp.astype(float)
        print("Saving to file: "+filename) 
        with h5py.File(filename, "w") as f:
            f.create_dataset("cgmat_data", cgmat_datanpf.shape, dtype=cgmat_datanpf.dtype, data=cgmat_datanpf)   
Esempio n. 22
0
def couple(tp):
    """ Couple an uncoupled spin states

    This function can be used to couple an uncoupled tensor product of spin
    states. All of the eigenstates to be coupled must be of the same class. It
    will return a linear combination of eigenstates that are subclasses of
    CoupledSpinState.

    Parameters
    ==========

    tp: TensorProduct
        TensorProduct of spin states to be coupled

    Examples
    ========

    Couple a tensor product of numerical states:

        >>> from sympy.physics.quantum.spin import JzKet, couple
        >>> from sympy.physics.quantum.tensorproduct import TensorProduct
        >>> couple(TensorProduct(JzKet(1,0), JzKet(1,1)))
        -sqrt(2)*|1,1,1,1>/2 + sqrt(2)*|2,1,1,1>/2

    Couple a tensor product of symbolic states:

        >>> from sympy import symbols
        >>> j1,m1,j2,m2 = symbols('j1 m1 j2 m2')
        >>> couple(TensorProduct(JzKet(j1,m1), JzKet(j2,m2)))
        Sum(CG(j1, m1, j2, m2, j, m1 + m2)*|j,m1 + m2>, (j, 0, j1 + j2))

    """
    states = tp.args
    evect = states[0].__class__
    if not all([arg.__class__ is evect for arg in states]):
        raise TypeError('All operands must be of the same class')
    evect = evect.coupled_class()
    if all(state.j.is_number for state in states):
        # Numerical coupling
        vect = TensorProduct(*[state._represent() for state in states])
        maxj = states[0].j + states[1].j
        j1, j2 = states[0].j, states[1].j
        if maxj == int(maxj):
            minj = 0
        else:
            minj = S(1) / 2
        result = []
        for i in range(maxj - minj + 1):
            j = maxj - i
            for k in range(2 * j + 1):
                m = j - k
                max_m1 = min(j1, m + j2)
                min_m1 = max(-j1, m - j2)
                min_m2 = m - max_m1
                result.append(
                    Add(*[
                        vect[(j1 - (max_m1 - l)) * (2 * j2 + 1) +
                             (j2 - (min_m2 + l)), 0] *
                        CG(j1, max_m1 - l, j2, min_m2 + l, j, m) *
                        evect(j, m, j1, j2) for l in range(max_m1 - min_m1 + 1)
                    ]))
        if all(state.m.is_number for state in states):
            return Add(*result).doit()
        else:
            return Add(*result)
    else:
        # Symbolic coupling
        maxj = Add(*[state.j for state in states])
        m = Add(*[state.m for state in states])
        j = symbols('j')
        if not maxj.is_number or maxj == int(maxj):
            minj = 0
        else:
            minj = S(1) / 2
        j1 = states[0].j
        j2 = states[1].j
        m1 = states[0].m
        m2 = states[1].m
        return Sum(CG(j1, m1, j2, m2, j, m) * evect(j, m), (j, minj, maxj))
Esempio n. 23
0
def uncouple(*args):
    """ Uncouple a coupled spin state

    Gives the uncoupled representation of a coupled spin state. Arguments must
    be either a spin state that is a subclass of CoupledSpinState or a spin
    state that is a subclass of SpinState and an array giving the j values
    of the spaces that are to be coupled

    Parameters
    ==========

    args: CoupledSpinState or SpinState
        The state that is to be coupled. If a subclass of SpinState is used,
        the state must be followed by the j values of the spaces that are to
        be coupled.

    Examples
    ========

    Uncouple a numerical state using a CoupledSpinState state:

        >>> from sympy.physics.quantum.spin import JzKetCoupled, uncouple
        >>> from sympy import S
        >>> uncouple(JzKetCoupled(1, 0, S(1)/2, S(1)/2))
        sqrt(2)*|1/2,-1/2>x|1/2,1/2>/2 + sqrt(2)*|1/2,1/2>x|1/2,-1/2>/2

    Perform the same calculation using a SpinState state:

        >>> from sympy.physics.quantum.spin import JzKet
        >>> uncouple(JzKet(1, 0), S(1)/2, S(1)/2)
        sqrt(2)*|1/2,-1/2>x|1/2,1/2>/2 + sqrt(2)*|1/2,1/2>x|1/2,-1/2>/2

    Uncouple a symbolic state using a CoupledSpinState state:

        >>> from sympy import symbols
        >>> j,m,j1,j2 = symbols('j m j1 j2')
        >>> uncouple(JzKetCoupled(j, m, j1, j2))
        Sum(CG(j1, m1, j2, m2, j, m)*|j1,m1>x|j2,m2>, (m1, -j1, j1), (m2, -j2, j2))

    Perform the same calculation using a SpinState state

        >>> uncouple(JzKet(j, m), j1, j2)
        Sum(CG(j1, m1, j2, m2, j, m)*|j1,m1>x|j2,m2>, (m1, -j1, j1), (m2, -j2, j2))

    """
    if len(args) == 3:
        state, j1, j2 = args
        evect = state.__class__
    elif len(args) == 1:
        state = args[0]
        evect = state.uncoupled_class()
        j1, j2 = state.jvals
        state = evect(state.j, state.m)
    else:
        raise TypeError
    j = state.j
    m = state.m
    if state.j.is_number and state.m.is_number:
        result = []
        for i_m1 in range(2 * j1 + 1):
            m1 = j1 - i_m1
            for i_m2 in range(2 * j2 + 1):
                m2 = j2 - i_m2
                result.append(
                    CG(j1, m1, j2, m2, j, m).doit() *
                    TensorProduct(evect(j1, m1), evect(j2, m2)))
        return Add(*result)
    else:
        m1, m2, mi = symbols('m1 m2 mi')
        # Hack to get rotation angles
        angles = (evect(0, mi)._represent())[0].args[3:6]
        out_state = TensorProduct(evect(j1, m1), evect(j2, m2))
        if angles == (0, 0, 0):
            lt = CG(j1, m1, j2, m2, state.j, state.m)
            return Sum(lt * out_state, (m1, -j1, j1), (m2, -j2, j2))
        else:
            lt = CG(j1, m1, j2, m2, state.j, mi) * Rotation.D(
                state.j, mi, state.m, *angles)
            return Sum(lt * out_state, (mi, -state.j, state.j), (m1, -j1, j1),
                       (m2, -j2, j2))
Esempio n. 24
0
def get_zT_prefactor(Ji,Ti,Tiz,dT,dTz,Tf,Tfz):
    cg = CG(Ti,Tiz,dT,dTz,Tf,Tfz)
    return ((math.sqrt(2*dT+1))/(math.sqrt(2*Ji+1)*math.sqrt(2*Tf+1)))*float(cg.doit())
Esempio n. 25
0
def test_cg_simp_add():
    j, m1, m1p, m2, m2p = symbols('j m1 m1p m2 m2p')
    # Test Varshalovich 8.7.1 Eq 1
    a = CG(S(1) / 2, S(1) / 2, 0, 0, S(1) / 2, S(1) / 2)
    b = CG(S(1) / 2, -S(1) / 2, 0, 0, S(1) / 2, -S(1) / 2)
    c = CG(1, 1, 0, 0, 1, 1)
    d = CG(1, 0, 0, 0, 1, 0)
    e = CG(1, -1, 0, 0, 1, -1)
    assert cg_simp(a + b) == 2
    assert cg_simp(c + d + e) == 3
    assert cg_simp(a + b + c + d + e) == 5
    assert cg_simp(a + b + c) == 2 + c
    assert cg_simp(2 * a + b) == 2 + a
    assert cg_simp(2 * c + d + e) == 3 + c
    assert cg_simp(5 * a + 5 * b) == 10
    assert cg_simp(5 * c + 5 * d + 5 * e) == 15
    assert cg_simp(-a - b) == -2
    assert cg_simp(-c - d - e) == -3
    assert cg_simp(-6 * a - 6 * b) == -12
    assert cg_simp(-4 * c - 4 * d - 4 * e) == -12
    a = CG(S(1) / 2, S(1) / 2, j, 0, S(1) / 2, S(1) / 2)
    b = CG(S(1) / 2, -S(1) / 2, j, 0, S(1) / 2, -S(1) / 2)
    c = CG(1, 1, j, 0, 1, 1)
    d = CG(1, 0, j, 0, 1, 0)
    e = CG(1, -1, j, 0, 1, -1)
    assert cg_simp(a + b) == 2 * KroneckerDelta(j, 0)
    assert cg_simp(c + d + e) == 3 * KroneckerDelta(j, 0)
    assert cg_simp(a + b + c + d + e) == 5 * KroneckerDelta(j, 0)
    assert cg_simp(a + b + c) == 2 * KroneckerDelta(j, 0) + c
    assert cg_simp(2 * a + b) == 2 * KroneckerDelta(j, 0) + a
    assert cg_simp(2 * c + d + e) == 3 * KroneckerDelta(j, 0) + c
    assert cg_simp(5 * a + 5 * b) == 10 * KroneckerDelta(j, 0)
    assert cg_simp(5 * c + 5 * d + 5 * e) == 15 * KroneckerDelta(j, 0)
    assert cg_simp(-a - b) == -2 * KroneckerDelta(j, 0)
    assert cg_simp(-c - d - e) == -3 * KroneckerDelta(j, 0)
    assert cg_simp(-6 * a - 6 * b) == -12 * KroneckerDelta(j, 0)
    assert cg_simp(-4 * c - 4 * d - 4 * e) == -12 * KroneckerDelta(j, 0)
    # Test Varshalovich 8.7.1 Eq 2
    a = CG(S(1) / 2, S(1) / 2, S(1) / 2, -S(1) / 2, 0, 0)
    b = CG(S(1) / 2, -S(1) / 2, S(1) / 2, S(1) / 2, 0, 0)
    c = CG(1, 1, 1, -1, 0, 0)
    d = CG(1, 0, 1, 0, 0, 0)
    e = CG(1, -1, 1, 1, 0, 0)
    assert cg_simp(a - b) == sqrt(2)
    assert cg_simp(c - d + e) == sqrt(3)
    assert cg_simp(a - b + c - d + e) == sqrt(2) + sqrt(3)
    assert cg_simp(a - b + c) == sqrt(2) + c
    assert cg_simp(2 * a - b) == sqrt(2) + a
    assert cg_simp(2 * c - d + e) == sqrt(3) + c
    assert cg_simp(5 * a - 5 * b) == 5 * sqrt(2)
    assert cg_simp(5 * c - 5 * d + 5 * e) == 5 * sqrt(3)
    assert cg_simp(-a + b) == -sqrt(2)
    assert cg_simp(-c + d - e) == -sqrt(3)
    assert cg_simp(-6 * a + 6 * b) == -6 * sqrt(2)
    assert cg_simp(-4 * c + 4 * d - 4 * e) == -4 * sqrt(3)
    a = CG(S(1) / 2, S(1) / 2, S(1) / 2, -S(1) / 2, j, 0)
    b = CG(S(1) / 2, -S(1) / 2, S(1) / 2, S(1) / 2, j, 0)
    c = CG(1, 1, 1, -1, j, 0)
    d = CG(1, 0, 1, 0, j, 0)
    e = CG(1, -1, 1, 1, j, 0)
    assert cg_simp(a - b) == sqrt(2) * KroneckerDelta(j, 0)
    assert cg_simp(c - d + e) == sqrt(3) * KroneckerDelta(j, 0)
    assert cg_simp(
        a - b + c - d +
        e) == sqrt(2) * KroneckerDelta(j, 0) + sqrt(3) * KroneckerDelta(j, 0)
    assert cg_simp(a - b + c) == sqrt(2) * KroneckerDelta(j, 0) + c
    assert cg_simp(2 * a - b) == sqrt(2) * KroneckerDelta(j, 0) + a
    assert cg_simp(2 * c - d + e) == sqrt(3) * KroneckerDelta(j, 0) + c
    assert cg_simp(5 * a - 5 * b) == 5 * sqrt(2) * KroneckerDelta(j, 0)
    assert cg_simp(5 * c - 5 * d + 5 * e) == 5 * sqrt(3) * KroneckerDelta(j, 0)
    assert cg_simp(-a + b) == -sqrt(2) * KroneckerDelta(j, 0)
    assert cg_simp(-c + d - e) == -sqrt(3) * KroneckerDelta(j, 0)
    assert cg_simp(-6 * a + 6 * b) == -6 * sqrt(2) * KroneckerDelta(j, 0)
    assert cg_simp(-4 * c + 4 * d -
                   4 * e) == -4 * sqrt(3) * KroneckerDelta(j, 0)
    # Test Varshalovich 8.7.2 Eq 9
    # alpha=alphap,beta=betap case
    # numerical
    a = CG(S(1) / 2, S(1) / 2, S(1) / 2, -S(1) / 2, 1, 0)**2
    b = CG(S(1) / 2, S(1) / 2, S(1) / 2, -S(1) / 2, 0, 0)**2
    c = CG(1, 0, 1, 1, 1, 1)**2
    d = CG(1, 0, 1, 1, 2, 1)**2
    assert cg_simp(a + b) == 1
    assert cg_simp(c + d) == 1
    assert cg_simp(a + b + c + d) == 2
    assert cg_simp(4 * a + 4 * b) == 4
    assert cg_simp(4 * c + 4 * d) == 4
    assert cg_simp(5 * a + 3 * b) == 3 + 2 * a
    assert cg_simp(5 * c + 3 * d) == 3 + 2 * c
    assert cg_simp(-a - b) == -1
    assert cg_simp(-c - d) == -1
    # symbolic
    a = CG(S(1) / 2, m1, S(1) / 2, m2, 1, 1)**2
    b = CG(S(1) / 2, m1, S(1) / 2, m2, 1, 0)**2
    c = CG(S(1) / 2, m1, S(1) / 2, m2, 1, -1)**2
    d = CG(S(1) / 2, m1, S(1) / 2, m2, 0, 0)**2
    assert cg_simp(a + b + c + d) == 1
    assert cg_simp(4 * a + 4 * b + 4 * c + 4 * d) == 4
    assert cg_simp(3 * a + 5 * b + 3 * c + 4 * d) == 3 + 2 * b + d
    assert cg_simp(-a - b - c - d) == -1
    a = CG(1, m1, 1, m2, 2, 2)**2
    b = CG(1, m1, 1, m2, 2, 1)**2
    c = CG(1, m1, 1, m2, 2, 0)**2
    d = CG(1, m1, 1, m2, 2, -1)**2
    e = CG(1, m1, 1, m2, 2, -2)**2
    f = CG(1, m1, 1, m2, 1, 1)**2
    g = CG(1, m1, 1, m2, 1, 0)**2
    h = CG(1, m1, 1, m2, 1, -1)**2
    i = CG(1, m1, 1, m2, 0, 0)**2
    assert cg_simp(a + b + c + d + e + f + g + h + i) == 1
    assert cg_simp(4 * (a + b + c + d + e + f + g + h + i)) == 4
    assert cg_simp(a + b + 2 * c + d + 4 * e + f + g + h + i) == 1 + c + 3 * e
    assert cg_simp(-a - b - c - d - e - f - g - h - i) == -1
    # alpha!=alphap or beta!=betap case
    # numerical
    a = CG(S(1) / 2,
           S(1) / 2,
           S(1) / 2, -S(1) / 2, 1, 0) * CG(
               S(1) / 2, -S(1) / 2,
               S(1) / 2,
               S(1) / 2, 1, 0)
    b = CG(S(1) / 2,
           S(1) / 2,
           S(1) / 2, -S(1) / 2, 0, 0) * CG(
               S(1) / 2, -S(1) / 2,
               S(1) / 2,
               S(1) / 2, 0, 0)
    c = CG(1, 1, 1, 0, 2, 1) * CG(1, 0, 1, 1, 2, 1)
    d = CG(1, 1, 1, 0, 1, 1) * CG(1, 0, 1, 1, 1, 1)
    assert cg_simp(a + b) == 0
    assert cg_simp(c + d) == 0
    # symbolic
    a = CG(S(1) / 2, m1,
           S(1) / 2, m2, 1, 1) * CG(S(1) / 2, m1p,
                                    S(1) / 2, m2p, 1, 1)
    b = CG(S(1) / 2, m1,
           S(1) / 2, m2, 1, 0) * CG(S(1) / 2, m1p,
                                    S(1) / 2, m2p, 1, 0)
    c = CG(S(1) / 2, m1,
           S(1) / 2, m2, 1, -1) * CG(S(1) / 2, m1p,
                                     S(1) / 2, m2p, 1, -1)
    d = CG(S(1) / 2, m1,
           S(1) / 2, m2, 0, 0) * CG(S(1) / 2, m1p,
                                    S(1) / 2, m2p, 0, 0)
    assert cg_simp(a + b + c +
                   d) == KroneckerDelta(m1, m1p) * KroneckerDelta(m2, m2p)
    a = CG(1, m1, 1, m2, 2, 2) * CG(1, m1p, 1, m2p, 2, 2)
    b = CG(1, m1, 1, m2, 2, 1) * CG(1, m1p, 1, m2p, 2, 1)
    c = CG(1, m1, 1, m2, 2, 0) * CG(1, m1p, 1, m2p, 2, 0)
    d = CG(1, m1, 1, m2, 2, -1) * CG(1, m1p, 1, m2p, 2, -1)
    e = CG(1, m1, 1, m2, 2, -2) * CG(1, m1p, 1, m2p, 2, -2)
    f = CG(1, m1, 1, m2, 1, 1) * CG(1, m1p, 1, m2p, 1, 1)
    g = CG(1, m1, 1, m2, 1, 0) * CG(1, m1p, 1, m2p, 1, 0)
    h = CG(1, m1, 1, m2, 1, -1) * CG(1, m1p, 1, m2p, 1, -1)
    i = CG(1, m1, 1, m2, 0, 0) * CG(1, m1p, 1, m2p, 0, 0)
    assert cg_simp(a + b + c + d + e + f + g + h +
                   i) == KroneckerDelta(m1, m1p) * KroneckerDelta(m2, m2p)
Esempio n. 26
0
def test_cg_simp_sum():
    x, a, b, c, cp, alpha, beta, gamma, gammap = symbols(
        'x a b c cp alpha beta gamma gammap')
    # Varshalovich 8.7.1 Eq 1
    assert cg_simp(
        x * Sum(CG(a, alpha, b, 0, a, alpha),
                (alpha, -a, a))) == x * (2 * a + 1) * KroneckerDelta(b, 0)
    assert cg_simp(x * Sum(CG(a, alpha, b, 0, a, alpha), (alpha, -a, a)) +
                   CG(1, 0, 1, 0, 1, 0)) == x * (2 * a + 1) * KroneckerDelta(
                       b, 0) + CG(1, 0, 1, 0, 1, 0)
    assert cg_simp(2 * Sum(CG(1, alpha, 0, 0, 1, alpha), (alpha, -1, 1))) == 6
    # Varshalovich 8.7.1 Eq 2
    assert cg_simp(x * Sum(
        (-1)**(a - alpha) * CG(a, alpha, a, -alpha, c, 0),
        (alpha, -a, a))) == x * sqrt(2 * a + 1) * KroneckerDelta(c, 0)
    assert cg_simp(3 * Sum((-1)**(2 - alpha) * CG(2, alpha, 2, -alpha, 0, 0),
                           (alpha, -2, 2))) == 3 * sqrt(5)
    # Varshalovich 8.7.2 Eq 4
    assert cg_simp(
        Sum(
            CG(a, alpha, b, beta, c, gamma) *
            CG(a, alpha, b, beta, cp, gammap), (alpha, -a, a),
            (beta, -b,
             b))) == KroneckerDelta(c, cp) * KroneckerDelta(gamma, gammap)
    assert cg_simp(
        Sum(
            CG(a, alpha, b, beta, c, gamma) * CG(a, alpha, b, beta, c, gammap),
            (alpha, -a, a), (beta, -b, b))) == KroneckerDelta(gamma, gammap)
    assert cg_simp(
        Sum(
            CG(a, alpha, b, beta, c, gamma) * CG(a, alpha, b, beta, cp, gamma),
            (alpha, -a, a), (beta, -b, b))) == KroneckerDelta(c, cp)
    assert cg_simp(
        Sum(CG(a, alpha, b, beta, c, gamma)**2, (alpha, -a, a),
            (beta, -b, b))) == 1
    assert cg_simp(
        Sum(
            CG(2, alpha, 1, beta, 2, gamma) * CG(2, alpha, 1, beta, 2, gammap),
            (alpha, -2, 2), (beta, -1, 1))) == KroneckerDelta(gamma, gammap)
Esempio n. 27
0
def kappa(nu, l, lp):
    return Piecewise(((-sqrt(factorial(nu - 2)/factorial(nu + 2)) *
                       CG(l, 1, lp, 1, nu, 2) /
                       CG(l, 1, lp, -1, nu, 0)),
                      ((nu > 1) & (nu < l + lp + 1))), (0, True))
Esempio n. 28
0
def test_cg():
    cg = CG(1, 2, 3, 4, 5, 6)
    wigner3j = Wigner3j(1, 2, 3, 4, 5, 6)
    wigner6j = Wigner6j(1, 2, 3, 4, 5, 6)
    wigner9j = Wigner9j(1, 2, 3, 4, 5, 6, 7, 8, 9)
    assert str(cg) == 'CG(1, 2, 3, 4, 5, 6)'
    ascii_str = \
"""\
 5,6    \n\
C       \n\
 1,2,3,4\
"""
    ucode_str = \
u"""\
 5,6    \n\
C       \n\
 1,2,3,4\
"""
    assert pretty(cg) == ascii_str
    assert upretty(cg) == ucode_str
    assert latex(cg) == r'C^{5,6}_{1,2,3,4}'
    sT(
        cg,
        "CG(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6))"
    )
    assert str(wigner3j) == 'Wigner3j(1, 2, 3, 4, 5, 6)'
    ascii_str = \
"""\
/1  3  5\\\n\
|       |\n\
\\2  4  6/\
"""
    ucode_str = \
u"""\
⎛1  3  5⎞\n\
⎜       ⎟\n\
⎝2  4  6⎠\
"""
    assert pretty(wigner3j) == ascii_str
    assert upretty(wigner3j) == ucode_str
    assert latex(wigner3j) == \
        r'\left(\begin{array}{ccc} 1 & 3 & 5 \\ 2 & 4 & 6 \end{array}\right)'
    sT(
        wigner3j,
        "Wigner3j(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6))"
    )
    assert str(wigner6j) == 'Wigner6j(1, 2, 3, 4, 5, 6)'
    ascii_str = \
"""\
/1  2  3\\\n\
<       >\n\
\\4  5  6/\
"""
    ucode_str = \
u"""\
⎧1  2  3⎫\n\
⎨       ⎬\n\
⎩4  5  6⎭\
"""
    assert pretty(wigner6j) == ascii_str
    assert upretty(wigner6j) == ucode_str
    assert latex(wigner6j) == \
        r'\left\{\begin{array}{ccc} 1 & 2 & 3 \\ 4 & 5 & 6 \end{array}\right\}'
    sT(
        wigner6j,
        "Wigner6j(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6))"
    )
    assert str(wigner9j) == 'Wigner9j(1, 2, 3, 4, 5, 6, 7, 8, 9)'
    ascii_str = \
"""\
/1  2  3\\\n\
|       |\n\
<4  5  6>\n\
|       |\n\
\\7  8  9/\
"""
    ucode_str = \
u"""\
⎧1  2  3⎫\n\
⎪       ⎪\n\
⎨4  5  6⎬\n\
⎪       ⎪\n\
⎩7  8  9⎭\
"""
    assert pretty(wigner9j) == ascii_str
    assert upretty(wigner9j) == ucode_str
    assert latex(wigner9j) == \
        r'\left\{\begin{array}{ccc} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{array}\right\}'
    sT(
        wigner9j,
        "Wigner9j(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6), Integer(7), Integer(8), Integer(9))"
    )
Esempio n. 29
0
def test_sympy__physics__quantum__cg__CG():
    from sympy.physics.quantum.cg import CG
    from sympy import S
    assert _test_args(CG(S(3) / 2, S(3) / 2, S(1) / 2, -S(1) / 2, 1, 1))
Esempio n. 30
0
def cg(l0, l, m):
    return CG(l0, 0, l, m, l, m).doit()
Esempio n. 31
0
def test_doit():
    assert Wigner3j(1 / 2, -1 / 2, 1 / 2, 1 / 2, 0, 0).doit() == -sqrt(2) / 2
    assert CG(1 / 2, 1 / 2, 1 / 2, -1 / 2, 1, 0).doit() == sqrt(2) / 2