def test_basic_drs_indexed(): """Test basic properties of drudge script indexed object.""" base_name = 'a' orig_base = IndexedBase(base_name) for drudge in [None, []]: matching_indices = [(Symbol('x'), DrsSymbol(drudge, 'x')), ((Symbol('x'), Symbol('y')), (DrsSymbol(drudge, 'x'), DrsSymbol(drudge, 'y')))] drs_base = DrsSymbol(drudge, base_name) for orig_indices, drs_indices in matching_indices: ref = orig_base[orig_indices] for i in [ orig_base[drs_indices], drs_base[orig_indices], drs_base[drs_indices] ]: assert ref == i assert hash(ref) == hash(i) assert sympy_key(ref) == sympy_key(i)
def test_basic_drs_symb(): """Test the symbol class for basic operations. """ name = 'a' ref = Symbol(name) dict_ = {ref: 1} symbs = [DrsSymbol(None, name), DrsSymbol([], name)] for i in symbs: assert isinstance(i, DrsSymbol) assert ref == i assert i == ref assert hash(ref) == hash(i) assert dict_[i] == 1 assert sympy_key(ref) == sympy_key(i) assert not hasattr(i, '__dict__') ref = Symbol(name + 'x') for i in symbs: assert ref != i assert i != ref assert hash(ref) != hash(i) assert sympy_key(ref) != sympy_key(i)
def _parse_vec_uga(vec, spec: _UGSpec): """Get the character, lattice indices, and the indices of keys of vector. """ base = vec.base if base == spec.uga: char = _UG_GEN else: raise ValueError('Unexpected generator of the Unitary Group',vec) indices = vec.indices if len(indices)!=2: raise ValueError('Unexpected length of indices for the generators of Unitary Group',vec) keys = tuple(sympy_key(i) for i in indices) return char, indices, keys
def _parse_vec_agp(vec, spec: _AGPSpec): """Get the character, lattice indices, and the indices of keys of vector. """ base = vec.base if base == spec.cartan: char = _CARTAN elif base == spec.raise_: char = _RAISE elif base == spec.lower: char = _LOWER else: raise ValueError('Unexpected vector for the AGP algebra', vec) indices = vec.indices keys = tuple(sympy_key(i) for i in indices) return char, indices, keys
def test_ancr_character_has_basic_properties(): """Test the annihilation and creation character singleton values. This test case also serves as the test for the general concrete symbol utility class and meta-class. """ # Its objects will be serialized and deserialized. n_cr, n_an = [pickle.loads(pickle.dumps(i)) for i in [CR, AN]] # We test both the original value and the deserialized values. for cr, an in [(CR, AN), (n_cr, n_an)]: # Printing, all kinds of printing. assert str(cr) == 'CR' assert str(an) == 'AN' assert repr(cr) == 'CranChar.CR' assert repr(an) == 'CranChar.AN' assert latex(cr) == r'\dagger' assert latex(an) == '' # Ordering, in its original form and as SymPy key. assert cr == cr assert an == an assert cr < an assert not cr > an assert sympy_key(cr) == sympy_key(cr) assert sympy_key(an) == sympy_key(an) assert sympy_key(cr) < sympy_key(an) assert not sympy_key(cr) > sympy_key(an) # Subtraction, purpose is the handling in deltas. assert cr - cr == 0 assert an - an == 0 assert cr - an != 0 assert an - cr != 0 assert KroneckerDelta(cr, cr) == 1 assert KroneckerDelta(an, an) == 1 assert KroneckerDelta(cr, an) == 0 assert KroneckerDelta(an, cr) == 0
def _parse_vec(vec, spec: _SU4Spec): """Get the character, lattice indices, and indices keys of the vector. """ base = vec.base if base == spec.cartan1: char = _CARTAN1 elif base == spec.raise1: char = _RAISE1 elif base == spec.lower1: char = _LOWER1 elif base == spec.cartan2: char = _CARTAN2 elif base == spec.raise2: char = _RAISE2 elif base == spec.lower2: char = _LOWER2 elif base == spec.ypp: char = _YPP elif base == spec.ymm: char = _YMM elif base == spec.yzz: char = _YZZ elif base == spec.ypm: char = _YPM elif base == spec.ymp: char = _YMP elif base == spec.ypz: char = _YPZ elif base == spec.yzp: char = _YZP elif base == spec.ymz: char = _YMZ elif base == spec.yzm: char = _YZM else: raise ValueError('Unexpected vector for SU2 algebra', vec) indices = vec.indices keys = tuple(sympy_key(i) for i in indices) return char, indices, keys
def _parse_vec(vec, spec: _AGPFSpec): """Get the character, lattice indices, and indices keys of the vector. """ base = vec.base indices = vec.indices if base == spec.c_.base: if vec.indices[0] == CranChar.AN: char = _C_ indices = vec.indices[1:] elif vec.indices[0] == CranChar.CR: char = _C_DAG indices = vec.indices[1:] else: pass elif base == spec.Nup: char = _N_UP_ elif base == spec.Ndn: char = _N_DN_ elif base == spec.N: char = _N_ elif base == spec.Pdag: char = _P_DAG elif base == spec.P: char = _P_ elif base == spec.S_p: char = _S_P elif base == spec.S_z: char = _S_Z elif base == spec.S_m: char = _S_M else: raise ValueError('Unexpected vector for AGPFermi algebra', vec) keys = tuple(sympy_key(i) for i in indices[0:1]) return char, indices, keys
def _try_simpl_unresolved_deltas(amp: Expr): """Try some simplification on unresolved deltas. This function aims to normalize the usage of free indices in the amplitude when a delta factor is present to require their equality. TODO: Unify the treatment here and the treatment for summation dummies. """ substs = {} if not (isinstance(amp, Mul) or isinstance(amp, KroneckerDelta)): return amp, substs deltas = _UNITY others = _UNITY if isinstance(amp, KroneckerDelta): arg1, arg2 = amp.args # Here, only the simplest case is treated, a * x = b * y, with a, b # being numbers and x, y being atomic symbols. One of the symbols # can be missing. But not both, since SymPy will automatically # resolve a delta between two numbers. factor1, symb1 = _parse_factor_symb(arg1) factor2, symb2 = _parse_factor_symb(arg2) if factor1 is not None and factor2 is not None: if symb1 is None: assert symb2 is not None arg1 = symb2 arg2 = factor1 / factor2 elif symb2 is None: assert symb1 is not None arg1 = symb1 arg2 = factor2 / factor1 elif sympy_key(symb1) < sympy_key(symb2): arg1 = symb2 arg2 = factor1 * symb1 / factor2 else: arg1 = symb1 arg2 = factor2 * symb2 / factor1 substs[arg1] = arg2 deltas *= KroneckerDelta(arg1, arg2) else: for i in amp.args: if isinstance(i, KroneckerDelta): arg1, arg2 = i.args # Here, only the simplest case is treated, a * x = b * y, # with a, b being numbers and x, y being atomic symbols. # One of the symbols can be missing. But not both, # since SymPy will automatically resolve a delta between # two numbers. factor1, symb1 = _parse_factor_symb(arg1) factor2, symb2 = _parse_factor_symb(arg2) if factor1 is not None and factor2 is not None: if symb1 is None: assert symb2 is not None arg1 = symb2 arg2 = factor1 / factor2 elif symb2 is None: assert symb1 is not None arg1 = symb1 arg2 = factor2 / factor1 elif sympy_key(symb1) < sympy_key(symb2): arg1 = symb2 arg2 = factor1 * symb1 / factor2 else: arg1 = symb1 arg2 = factor2 * symb2 / factor1 # Now update the substs dictionary if arg1 not in list(substs.keys()): substs[arg1] = arg2 else: # if the arg1 exists in the key, # multiply with the new delta deltas *= KroneckerDelta(arg2, substs[arg1]) deltas *= KroneckerDelta(arg1, arg2) else: others *= i others = others.xreplace(substs) return deltas * others, substs