def make_symbols_non_commutative(self, expr): """ replaces commutative symbols x with non commutative symbols z """ symbs = st.atoms(expr, sp.Symbol) nc_symbols = [s for s in symbs if s.is_commutative] new_symbols = [sp.Symbol(s.name.replace("x","z"), commutative=False) for s in nc_symbols] tup_list = zip(nc_symbols, new_symbols) return expr.subs(zip(nc_symbols, new_symbols))
def right_shift_all_in_matrix(self, matrix): # does nct-package provide this already? m,n = matrix.shape matrix_shifted = sp.Matrix([]) t_dep_symbols = [symb for symb in st.atoms(matrix, sp.Symbol) if not symb == s] for i in xrange(n): col = matrix.col(i) col_shifted = sp.Matrix([nct.right_shift_all(expr,s,t, t_dep_symbols) for expr in col]) matrix_shifted = st.concat_cols(matrix_shifted, col_shifted) return matrix_shifted
def make_symbols_non_commutative(self, expr): """ replaces commutative symbols x with non commutative symbols z """ symbs = st.atoms(expr, sp.Symbol) nc_symbols = [s for s in symbs if s.is_commutative] new_symbols = [ sp.Symbol(s.name.replace("x", "z"), commutative=False) for s in nc_symbols ] tup_list = list(zip(nc_symbols, new_symbols)) return expr.subs(list(zip(nc_symbols, new_symbols)))
def right_shift_all_in_matrix(self, matrix): # does nct-package provide this already? m, n = matrix.shape matrix_shifted = sp.Matrix([]) t_dep_symbols = [ symb for symb in st.atoms(matrix, sp.Symbol) if not symb == s ] for i in range(n): col = matrix.col(i) col_shifted = sp.Matrix([ nct.right_shift_all(expr, s, t, t_dep_symbols) for expr in col ]) matrix_shifted = st.concat_cols(matrix_shifted, col_shifted) return matrix_shifted
def make_symbols_commutative(self, expr): """ :param expr: :return: expr (with all symbols commutative) and a subs_tuple_list [(s1_c, s1_nc), ... ] """ symbs = st.atoms(expr, sp.Symbol) nc_symbols = [s for s in symbs if not s.is_commutative] new_symbols = [sp.Symbol(s.name.replace("z","x"), commutative=True) for s in nc_symbols] tup_list = zip(new_symbols, nc_symbols) return expr.subs(zip(nc_symbols, new_symbols))
def make_symbols_commutative(self, expr): """ :param expr: :return: expr (with all symbols commutative) and a subs_tuple_list [(s1_c, s1_nc), ... ] """ symbs = st.atoms(expr, sp.Symbol) nc_symbols = [s for s in symbs if not s.is_commutative] new_symbols = [ sp.Symbol(s.name.replace("z", "x"), commutative=True) for s in nc_symbols ] tup_list = list(zip(new_symbols, nc_symbols)) return expr.subs(list(zip(nc_symbols, new_symbols)))
def make_all_symbols_noncommutative(expr, appendix='_n'): """ :param expr: :return: expr (with all symbols noncommutative) and a subs_tuple_list [(s1_n, s1_c), ... ] """ if isinstance(expr, (list, tuple, set)): expr = sp.Matrix(list(expr)) symbs = st.atoms(expr, sp.Symbol) c_symbols = [s for s in symbs if s.is_commutative] new_symbols = [sp.Symbol(s.name+appendix, commutative=False) for s in c_symbols] # preserve difforder attributes st.copy_custom_attributes(c_symbols, new_symbols) tup_list = lzip(new_symbols, c_symbols) return expr.subs(lzip(c_symbols, new_symbols)), tup_list
def make_all_symbols_noncommutative(expr, appendix='_n'): """ :param expr: :return: expr (with all symbols noncommutative) and a subs_tuple_list [(s1_n, s1_c), ... ] """ if isinstance(expr, (list, tuple, set)): expr = sp.Matrix(list(expr)) symbs = st.atoms(expr, sp.Symbol) c_symbols = [s for s in symbs if s.is_commutative] new_symbols = [ sp.Symbol(s.name + appendix, commutative=False) for s in c_symbols ] # preserve difforder attributes st.copy_custom_attributes(c_symbols, new_symbols) tup_list = lzip(new_symbols, c_symbols) return expr.subs(lzip(c_symbols, new_symbols)), tup_list
def solve_bezout_eq(p1, p2, var): """ solving the bezout equation c1*p1 + c2*p2 = 1 for monovariate polynomials p1, p2 by ansatz-polynomials and equating coefficients """ g1 = st.poly_degree(p1, var) g2 = st.poly_degree(p2, var) if (not sp.gcd(p1, p2) == 1) and (not p1*p2==0): # pass errmsg = "p1, p2 need to be coprime "\ "(condition for Bezout identity to be solveble).\n"\ "p1 = {p1}\n"\ "p2 = {p2}" raise ValueError(errmsg.format(p1=p1, p2=p2)) if p1 == p2 == 0: raise ValueError("invalid: p1==p2==0") if p1 == 0 and g2 > 0: raise ValueError("invalid: p1==0 and not p2==const ") if p2 == 0 and g1 > 0: raise ValueError("invalid: p2==0 and not p1==const ") # Note: degree(0) = -sp.oo = -inf k1 = g2 - 1 k2 = g1 - 1 if k1<0 and k2 <0: if p1 == 0: k2 = 0 else: k1 = 0 if k1 == -sp.oo: k1 = -1 if k2 == -sp.oo: k2 = -1 cc1 = sp.symbols("c1_0:%i" % (k1 + 1)) cc2 = sp.symbols("c2_0:%i" % (k2 + 1)) c1 = coeff_list_to_poly(cc1, var) c2 = coeff_list_to_poly(cc2, var) # Bezout equation: eq = c1*p1 + c2*p2 - 1 # solve it w.r.t. the unknown coeffs sol = sp.solve(eq, cc1+cc2, dict=True) if len(sol) == 0: errmsg = "No solution found.\n"\ "p1 = {p1}\n"\ "p2 = {p2}" raise ValueError(errmsg.format(p1=p1, p2=p2)) sol = sol[0] sol_symbols = st.atoms(sp.Matrix(sol.values()), sp.Symbol) # there might be some superflous coeffs free_c_symbols = set(cc1+cc2).intersection(sol_symbols) if free_c_symbols: # set them to zero fcs0 = st.zip0(free_c_symbols) keys, values = zip(*sol.items()) new_values = [v.subs(fcs0) for v in values] sol = dict(zip(keys, new_values)+fcs0) return c1.subs(sol), c2.subs(sol)