def __call__(self, v, obj=False): if isinstance(v, mv.Mv) and self.Ga.name != v.Ga.name: raise ValueError( 'In Lt call Lt and argument refer to different vector spaces') if self.spinor: if not isinstance(v, mv.Mv): v = mv.Mv(v, ga=self.Ga) if self.rho_sq == None: R_v_Rrev = self.R * v * self.Rrev else: R_v_Rrev = self.rho_sq * self.R * v * self.Rrev if obj: return R_v_Rrev.obj else: return R_v_Rrev if isinstance(v, mv.Mv): if v.is_vector(): lt_v = v.obj.xreplace(self.lt_dict) if obj: return lt_v else: return mv.Mv(lt_v, ga=self.Ga) else: mv_obj = v.obj else: mv_obj = mv.Mv(v, ga=self.Ga).obj if self.mv_dict is None: # Build dict for linear transformation of multivector self.mv_dict = copy(self.lt_dict) for key in self.Ga.blades[2:]: for blade in key: index = self.Ga.blades_to_indexes_dict[blade] lt_blade = self(self.Ga.basis[index[0]], obj=True) for i in index[1:]: lt_blade = self.Ga.wedge( lt_blade, self(self.Ga.basis[i], obj=True)) self.mv_dict[blade] = lt_blade lt_v = mv_obj.xreplace(self.mv_dict) if obj: return lt_v else: return mv.Mv(lt_v, ga=self.Ga)
def tr(self): # tr(L) defined by tr(L) = grad|L(x) connect_flg = self.Ga.connect_flg self.Ga.connect_flg = False F_x = mv.Mv(self(self.Ga.lt_x, obj=True), ga=self.Ga) tr_F = (self.Ga.grad | F_x).scalar() self.Ga.connect_flg = connect_flg return (tr_F)
def Lt_latex_str(self): if self.spinor: s = '\\left \\{ \\begin{array}{ll} ' for base in self.Ga.basis: s += 'L \\left ( ' + str(base) + '\\right ) =& ' + str( self.R * mv.Mv(base, ga=self.Ga) * self.Rrev) + ' \\\\ ' s = s[:-3] + ' \\end{array} \\right \\} \n' return s else: s = '\\left \\{ \\begin{array}{ll} ' for base in self.Ga.basis: if base in self.lt_dict: s += 'L \\left ( ' + str(base) + '\\right ) =& ' + str( mv.Mv(self.lt_dict[base], ga=self.Ga)) + ' \\\\ ' else: s += 'L \\left ( ' + str(base) + '\\right ) =& 0 \\\\ ' s = s[:-3] + ' \\end{array} \\right \\} \n' return s
def Lt_str(self): if self.spinor: return 'R = ' + str(self.R) else: pre = 'Lt(' s = '' for base in self.Ga.basis: if base in self.lt_dict: s += pre + str(base) + ') = ' + str( mv.Mv(self.lt_dict[base], ga=self.Ga)) + '\n' else: s += pre + str(base) + ') = 0\n' return s[:-1]
def __init__(self, *kargs, **kwargs): """ Except for the spinor representation the linear transformation is stored as a dictionary with basis vector keys and vector values self.lt_dict so that a is a vector a = a^{i}e_{i} then self(a) = a^{i} * self.lt_dict[e_{i}]. For the spinor representation the linear transformation is stored as the even multivector self.R so that if a is a vector self(a) = self.R * a * self.R.rev(). For the general representation of a linear transformation the linear transformation is represented as a dictionary self.lt_dict where the keys are the basis symbols, {e_i}, and the dictionary entries are the object vector images (linear combination of sympy non-commutative basis symbols) of the keys so that if L is the linear transformation then L(e_i) = self.Ga.mv(L.lt_dict[e_i]) """ kwargs = metric.test_init_slots(Lt.init_slots, **kwargs) mat_rep = kargs[0] ga = kwargs['ga'] self.fct_flg = kwargs['f'] self.mode = kwargs['mode'] # General g, s, or a transformation self.Ga = ga self.coords = ga.lt_coords self.X = ga.lt_x self.spinor = False self.rho_sq = None self.lt_dict = {} self.mv_dict = None self.mat = None self.Ga.inverse_metric( ) # g^{-1} needed for standard matrix representation if isinstance(mat_rep, tuple): # tuple input for key in mat_rep: self.lt_dict[key] = mat_rep[key] elif isinstance(mat_rep, dict): # Dictionary input for key in mat_rep: self.lt_dict[key] = mat_rep[key] elif isinstance(mat_rep, list): # List of lists input if not isinstance(mat_rep[0], list): for (lt_i, base) in zip(mat_rep, self.Ga.basis): self.lt_dict[base] = lt_i else: #mat_rep = map(list, zip(*mat_rep)) # Transpose list of lists for (row, base1) in zip(mat_rep, self.Ga.basis): tmp = 0 for (col, base2) in zip(row, self.Ga.basis): tmp += col * base2 self.lt_dict[base1] = tmp elif isinstance(mat_rep, Matrix): # Matrix input self.mat = mat_rep mat_rep = self.mat * self.Ga.g_inv self.lt_dict = Matrix_to_dictionary(mat_rep, self.Ga.basis) elif isinstance(mat_rep, mv.Mv): # Spinor input self.spinor = True self.R = mat_rep self.Rrev = mat_rep.rev() self.rho_sq = self.R * self.Rrev if self.rho_sq.is_scalar(): self.rho_sq = self.rho_sq.scalar() if self.rho_sq == S(1): self.rho_sq = None else: raise ValueError( 'In Spinor input for Lt, S*S.rev() not a scalar!\n') elif isinstance(mat_rep, str): # String input Amat = Symbolic_Matrix(mat_rep, coords=self.Ga.coords, mode=self.mode, f=self.fct_flg) self.__init__(Amat, ga=self.Ga) else: # Linear multivector function input # F is a multivector function to be tested for linearity F = mat_rep a = mv.Mv('a', 'vector', ga=self.Ga) b = mv.Mv('b', 'vector', ga=self.Ga) if F(a + b) == F(a) + F(b): self.lt_dict = {} for base in self.Ga.basis: self.lt_dict[base] = (F(mv.Mv(base, ga=self.Ga))).obj if not self.lt_dict[base].is_vector(): raise ValueError( str(mat_rep) + ' is not supported for Lt definition\n') else: raise ValueError( str(mat_rep) + ' is not supported for Lt definition\n')