def __div__(self, rhs): if isinstance(rhs, int): return self.__mul__(1/rhs) if isinstance(rhs, float) or isinstance(rhs, complex): return self.__mul__(1.0/rhs) else: raise ufo_exception("Tensor division for this type not supported")
def __init__(self, init): if isinstance(init, str): self._expr = parse_expr(init) elif isinstance(init, Basic): self._expr = init else: raise ufo_exception("Expect string or sympy expression in constructor")
def __eq__(self, rhs): if isinstance(rhs, lorentz_key): if not (self._lorentz == rhs._lorentz): raise ufo_exception("Internal error, ambiguous lorentz key comparison") return (self._key == rhs._key) return False
def get_out_current_declaration(self, out_spin, out_key): if (out_spin == 1): return "CScalar<SType>* j{0} = NULL;\n".format(out_key) elif (out_spin == 2): return "CSpinor<SType>* j{0} = NULL;\n".format(out_key) elif (out_spin == 3): return "CVec4<SType>* j{0} = NULL;\n".format(out_key) else: raise ufo_exception("Cannot handle spin {0}".format(out_spin))
def common_key_dict(tens_a, tens_b): comm_keys = common_keys(tens_a,tens_b) new_dict = dict() dict_a = tens_a.key_dim_dict() dict_b = tens_b.key_dim_dict() for key in comm_keys: dim_a = dict_a[key] if (dim_a != dict_b[key]): raise ufo_exception("Cannot create common tensor key dictionary") new_dict.update( {key:dim_a} ) return new_dict
def c_string_from_num(num): # where this is used, we have 'complex' typedef'd if isinstance(num, complex): if num == 0: return "(0.0)" return "(complex({0},{1}))".format(num.real,num.imag) # do not want integers floating around in generated c code if isinstance(num, int): return "({0})".format(float(num)) if isinstance(num, float): return "({0})".format(num) raise ufo_exception("Can't convert {0}".format(num))
def c_string_from_num(num): # where this is used, we have 'complex' typedef'd if isinstance(num, complex): if num == 0: return "(0.0)" return "(complex({0},{1}))".format(num.real, num.imag) # do not want integers floating around in generated c code if isinstance(num, int): return "({0})".format(float(num)) if isinstance(num, float): return "({0})".format(num) raise ufo_exception("Can't convert {0}".format(num))
def __mul__(self, rhs): if isinstance(rhs, int) or isinstance(rhs, float) or isinstance(rhs, complex) or isinstance(rhs,str): return self.__mul__(tensor([rhs], None)) if not isinstance(rhs, tensor): raise ufo_exception("Tensor multiplication for type {0} not supported".format(type(rhs))) # if no indices to be summed over: # return simple product if len(common_keys(self,rhs)) == 0: return multiply(self, rhs) return contract(common_key_dict(self, rhs), self, rhs)
def __mul__(self, other): if isinstance(other, c_variable): # string can potentially be a sum, insert parantheses return c_variable("(" + self._string + ") * (" + other._string + ")", self._prefac * other._prefac) if isinstance(other, complex) or isinstance(other, float): return c_variable(self._string, self._prefac * other) if isinstance(other, int): return c_variable(self._string, self._prefac * float(other)) else: raise ufo_exception("Cannot perform multiplication of c_variable with {0}".format(type(other)))
def __mul__(self, other): if isinstance(other, c_variable): # string can potentially be a sum, insert parantheses return c_variable( "(" + self._string + ") * (" + other._string + ")", self._prefac * other._prefac) if isinstance(other, complex) or isinstance(other, float): return c_variable(self._string, self._prefac * other) if isinstance(other, int): return c_variable(self._string, self._prefac * float(other)) else: raise ufo_exception( "Cannot perform multiplication of c_variable with {0}".format( type(other)))
def contract(key_dim_dict, tens_a, tens_b): if len(key_dim_dict)==0: assert(len(common_keys(tens_a,tens_b))==0) return multiply(tens_a,tens_b) key, dim = key_dim_dict.popitem() if dim==0: raise ufo_exception("Cannot contract empty tensors") # need to make a deepcopy here since # 'contract' keeps popping items from dict ret = [contract(deepcopy(key_dim_dict), tens_a[{key:i}],tens_b[{key:i}]) for i in range(dim)] # built-in support for implicit metric # multiplication when contracting lorentz indices if hasattr(key, '_lorentz'): if key._lorentz: return -sum(ret[1:], -ret[0]) return sum(ret[1:], ret[0])
def get_in_current_tens(self, key, spin): # scalar if spin == 1: return tensor([c_variable("j{0}[0]".format(key))], None) # fermion if (spin == 2): return tensor([ tensor([c_variable("j{0}[{1}]".format(key, 0))], None), tensor([c_variable("j{0}[{1}]".format(key, 1))], None), tensor([c_variable("j{0}[{1}]".format(key, 2))], None), tensor([c_variable("j{0}[{1}]".format(key, 3))], None) ], key + 1) if (spin == 3): needs_gauge = self.needs_vector_gauge() dummy = tensor([ tensor([ c_variable("j{0}[{1}]".format( key, vect_gauge_dict[0] if needs_gauge else 0)) ], None), tensor([ c_variable("j{0}[{1}]".format( key, vect_gauge_dict[1] if needs_gauge else 1)) ], None), tensor([ c_variable("j{0}[{1}]".format( key, vect_gauge_dict[2] if needs_gauge else 2)) ], None), tensor([ c_variable("j{0}[{1}]".format( key, vect_gauge_dict[3] if needs_gauge else 3)) ], None) ], 'dummy_key') # incoming currents are alway contravariant in sherpa, # so we need to multiply by metric return dummy * mink_metric(key + 1, 'dummy_key') raise ufo_exception( "External wavefunction for spin {0} not implemented".format(spin))
def get_in_current_tens(self, key, spin): # scalar if spin == 1: return tensor([c_variable("j{0}[0]".format(key))], None) # fermion if (spin == 2): return tensor([tensor([c_variable("j{0}[{1}]".format(key,0))] , None), tensor([c_variable("j{0}[{1}]".format(key,1))] , None), tensor([c_variable("j{0}[{1}]".format(key,2))] , None), tensor([c_variable("j{0}[{1}]".format(key,3))] , None)], key+1) if (spin == 3): needs_gauge = self.needs_vector_gauge() dummy = tensor([tensor([c_variable("j{0}[{1}]".format(key,vect_gauge_dict[0] if needs_gauge else 0))] , None), tensor([c_variable("j{0}[{1}]".format(key,vect_gauge_dict[1] if needs_gauge else 1))] , None), tensor([c_variable("j{0}[{1}]".format(key,vect_gauge_dict[2] if needs_gauge else 2))] , None), tensor([c_variable("j{0}[{1}]".format(key,vect_gauge_dict[3] if needs_gauge else 3))] , None)], 'dummy_key') # incoming currents are alway contravariant in sherpa, # so we need to multiply by metric return dummy * mink_metric(key+1, 'dummy_key') raise ufo_exception("External wavefunction for spin {0} not implemented".format(spin))
def get_in_current_tens(self, key, spin): # scalar if spin == 1: return tensor([c_variable("j{0}[0]".format(key))], None) # fermion if (spin == 2): # put key+1 as key to account for UFO key conv. return tensor([tensor([c_variable("j{0}[{1}]".format(key,0))] , None), tensor([c_variable("j{0}[{1}]".format(key,1))] , None), tensor([c_variable("j{0}[{1}]".format(key,2))] , None), tensor([c_variable("j{0}[{1}]".format(key,3))] , None)], key+1) if (spin == 3): dummy = tensor([tensor([c_variable("j{0}[{1}]".format(key,vect_gauge_dict[0]))] , None), tensor([c_variable("j{0}[{1}]".format(key,vect_gauge_dict[1]))] , None), tensor([c_variable("j{0}[{1}]".format(key,vect_gauge_dict[2]))] , None), tensor([c_variable("j{0}[{1}]".format(key,vect_gauge_dict[3]))] , None)], 'dummy_key') # Incoming currents are alway contravariant in sherpa, # so we need to multiply by metric. # Put key+1 as key to account for UFO key conv. return dummy * mink_metric(key+1, 'dummy_key') raise ufo_exception("External wavefunction for spin {0} not implemented".format(spin))
def __add__(self, rhs): # so far, support/define # only sum of identical type # i.e. demand equality of key_dim_dict() if (cmp(self.key_dim_dict(), rhs.key_dim_dict())!=0): raise ufo_exception("Inconsistent tensor addition") # get a deepcopy so we don't need # to build a return value from scratch ret = deepcopy(self) # end of recursion: elementary tensor if ret._elementary: if isinstance(ret._array[0], str) or isinstance(rhs._array[0], str): ret._array[0] = str(ret._array[0]) + " + " + str(rhs._array[0]) else: ret._array[0] = ret._array[0] + rhs._array[0] return ret # apply addition recursively to elements in array for i in range(self._toplevel_dim): ret[{self._toplevel_key:i}] = ret[{self._toplevel_key:i}].__add__(rhs[{self._toplevel_key:i}]) return ret
def get_in_current_tens(self, key, spin): # scalar if spin == 1: return tensor([c_variable("j{0}[0]".format(key))], None) # fermion if (spin == 2): # put key+1 as key to account for UFO key conv. return tensor([ tensor([c_variable("j{0}[{1}]".format(key, 0))], None), tensor([c_variable("j{0}[{1}]".format(key, 1))], None), tensor([c_variable("j{0}[{1}]".format(key, 2))], None), tensor([c_variable("j{0}[{1}]".format(key, 3))], None) ], key + 1) if (spin == 3): dummy = tensor([ tensor( [c_variable("j{0}[{1}]".format(key, vect_gauge_dict[0]))], None), tensor( [c_variable("j{0}[{1}]".format(key, vect_gauge_dict[1]))], None), tensor( [c_variable("j{0}[{1}]".format(key, vect_gauge_dict[2]))], None), tensor( [c_variable("j{0}[{1}]".format(key, vect_gauge_dict[3]))], None) ], 'dummy_key') # Incoming currents are alway contravariant in sherpa, # so we need to multiply by metric. # Put key+1 as key to account for UFO key conv. return dummy * mink_metric(key + 1, 'dummy_key') raise ufo_exception( "External wavefunction for spin {0} not implemented".format(spin))