def apply_transformation(M, T, k=0, systype=None): r""" Applies a basis transformation to a first order system given by x^k*D(Y)=M*Y, where D is the differential or the shift operator. Input: - T ... a matrix defining a basis transformation. - M ... a matrix defining a first order system. - k ... (optional) a non-negative integer. Default is 0. - systype ... (optional) a string specifying whether the system is a system of differential or difference equations. Can be either 'shift' or 'diff'. The defualt value is set in the global variable 'global_systype'. Output: - The defining matrix of the transformed system. EXAMPLES: sage: L.<x>=PolynomialRing(QQ) sage: MS=MatrixSpace(L,2) sage: M=MS([[2*x,x+1],[3,0]]) sage: T=shearing_transformation(MS,2) sage: apply_transformation(M,T,'d') [(2*x^2 - 1)/x x + 1] [ 3 -1/x] sage: apply_transformation(M,T,'s') [2*x^2/(x + 1) x] [ 3*x/(x + 1) 0] sage: apply_transformation(M,MS.one(),'d')==M True sage: apply_transformation(M,MS.one(),'s')==M True Algorithm: - naive """ if systype == None: systype = systype_fallback() var = M.parent().base_ring().gens()[0] if systype in systype_s: if k == 0: return T.inverse().subs({var: var + 1}) * M * T return T.inverse().subs({var: var + 1 }) * (M * T - T.subs({var: var + 1}) + T) elif systype in systype_as: return T.inverse().substitute({var: var - 1}) * M * T elif systype in systype_d: return T.inverse() * (M * T - var**k * T.parent()(diff(T))) elif systype in systype_ad: return T.inverse() * (M * T + var**k * T.parent()(diff(T))) else: raise ValueError(systype_error_string)
def operator(M, k=0, systype=None): if systype == None: systype = systype_fallback() var = M.parent().base_ring().gens()[0] if systype in systype_s: return lambda x: (M * x - x.subs({var: var + 1})).subs({var: var - 1}) elif systype in systype_as: return lambda x: (M * x - x.subs({var: var - 1})).subs({var: var + 1}) elif systype in systype_d: return lambda x: M * x - var**k * diff(x, var) elif systype in systype_ad: return lambda x: M * x + var**k * diff(x, var) else: raise ValueError(systype_error_string)
def indicial_matrix(M, p, systype=None): if systype == None: systype = systype_fallback() (M, MS, F, R, _, var) = __parent_info(M) if systype in systype_d: D = matrix([[ var**(-min(1 + matrix_valuation(M.rows()[i], p), 0)) if i == j else 0 for i in range(M.nrows()) ] for j in range(M.nrows())]) A = (p / diff(p, var) * D * M) elif systype in systype_s: #TODO: THis is just tested at infinity, so for indicial_matrix(M(-1/x),x) if p != var: raise NotImplementedError A = 1 / var * (M - MS.one()) D = matrix([[ var**(-min(matrix_valuation(A.rows()[i], p), 0)) if i == j else 0 for i in range(A.nrows()) ] for j in range(A.nrows())]) A = D * A else: raise ValueError(systype_error_string) A0 = padic_expansion(A, p, 1) D0 = padic_expansion(D, p, 1) A0 = __lift(A0[1][0]) if A0[0] == 0 else A.parent().zero() D0 = __lift(D0[1][0]) if D0[0] == 0 else D.parent().zero() R2 = PolynomialRing(R, [repr(var) + '0']) var2 = R2.gens()[0] MS = A0.parent().change_ring(R2) A0 = MS(A0) D0 = MS(D0) var2 = R2.gens()[0] return A0 - var2 * D0
def prolongationODE(equations, dependent, independent): """ Baumann, ex 1, pp.136 >>> x = var("x") >>> u = function('u') >>> F = function("F") >>> ode3 = diff(u(x), x) - F(u(x),x) >>> prolongationODE(ode3,u,x) [xi(u(x), x)*D[0](F)(u(x), x)*diff(u(x), x) - diff(u(x), x)^2*D[0](xi)(u(x), x) - (D[0](F)(u(x), x)*diff(u(x), x) + D[1](F)(u(x), x) - diff(u(x), x, x))*xi(u(x), x) - phi(u(x), x)*D[0](F)(u(x), x) + D[0](phi)(u(x), x)*diff(u(x), x) - xi(u(x), x)*diff(u(x), x, x) - diff(u(x), x)*D[1](xi)(u(x), x) + D[1](phi)(u(x), x)] """ vars = [dependent(independent), independent] xi = function("xi") phi = function("phi") eta = phi(*vars) - xi(*vars) * diff(dependent(independent), independent) test = function("t") prolong = FrechetD([equations], [dependent], [independent], testfunction=[test]) prol = [] for p in prolong: _p = [l.substitute_function(test, eta).expand() for l in p] prol.append(sum(_ for _ in _p)) prolong = prol[:] prol = [] for j in range(len(prolong)): prol.append(prolong[j] + xi(*vars) * equations.diff(independent)) return prol
def EulerD(density, depend, independ): r''' >>> t = var("t") >>> u= function('u') >>> v= function('v') >>> L=u(t)*v(t) + diff(u(t), t)**2 + diff(v(t), t)**2 - u(t)**2 - v(t)**2 >>> EulerD(L, (u,v), t) [-2*u(t) + v(t) - 2*diff(u(t), t, t), u(t) - 2*v(t) - 2*diff(v(t), t, t)] >>> L=u(t)*v(t) + diff(u(t), t)**2 + diff(v(t), t)**2 + 2*diff(u(t), t) * diff(v(t), t) >>> EulerD(L, (u,v), t) [v(t) - 2*diff(u(t), t, t) - 2*diff(v(t), t, t), u(t) - 2*diff(u(t), t, t) - 2*diff(v(t), t, t)] ''' wtable = [function("w_%s" % i) for i in range(len(depend))] y = function('y') w = function('w') e = var('e') result = [] for j in range(len(depend)): loc_result = 0 def f0(*args): return y(independ) + e * w(independ) def dep(*args): return depend[j](independ) fh = density.substitute_function(depend[j], f0) fh = fh.substitute_function(y, dep) fh = fh.substitute_function(w, wtable[j]) fh = fh.diff(e) fh = fh.subs({e: 0}).expand() if fh.operator().__name__ == 'mul_vararg': operands = [fh] else: operands = fh.operands() for operand in operands: d = None coeff = [] for _ops in operand.operands(): if is_op_du(_ops, wtable[j](independ)): d = _ops.operands().count(independ) elif is_function(_ops) and _ops.operator() == wtable[j]: pass else: coeff.append(_ops) coeff = functools.reduce(mul, coeff, 1) if d is not None: coeff = ((-1)**d) * diff(coeff, independ, d) loc_result += coeff result.append(loc_result) return result
def annihilating_system(r, systype=None): r""" Computes an annihilating first order system for a rational function. Input: - r ... A rational function in one variable. - systype ... (optional) a string specifying whether the system is a system of differential or difference equations. Can be either 'shift' or 'diff'. The defualt value is set in the global variable 'global_systype'. Output: - A matrix of differential or difference type whose associtated pseudo linear operator annihilates r. EXAMPLES: sage: L.<x>=PolynomialRing(QQ) sage: d=randint(1,100) sage: n=randint(1,100) sage: p=L.random_element(d,n) sage: Md=annihilating_system(p,systype='d') sage: Ms=annihilating_system(p,systype='s') sage: operator(Md,systype='d')(p)==0 True sage: operator(Ms,systype='s')(p)==0 True sage: p=L.zero() sage: Md=annihilating_system(p,systype='d') sage: Ms=annihilating_system(p,systype='s') sage: operator(Md,systype='d')(p)==0 True sage: operator(Ms,systype='s')(p)==0 True Algorithm: - naive """ if systype == None: systype = systype_fallback() var = r.parent().gens()[0] if r == 0: return matrix([[r.parent().one()]]) if systype in systype_s: return matrix([[r.subs({var: var + 1}) / r]]) elif systype in systype_d: return matrix([[diff(r, var) / r]]) else: raise ValueError(systype_error_string)
def tangent_vector(f): # https://doc.sagemath.org/html/en/reference/manifolds/sage/manifolds/differentiable/tangent_vector.html?highlight=partial%20differential # XXX: There is TangentVector in Sage but a little bit more complicated. Does it pay to use that one ? r""" Do a tangent vector DEFINITION: missing INPUT: - ``f`` - symbolic expression of type 'function' OUTPUT: the tangent vector .. NOTE:: none so far .. EXAMPLES: compute the tangent vector of :: sage: from delierium.helpers import tangent_vector sage: x,y,z = var ("x y z") sage: tangent_vector (x**2 - 3*y**4 - z*x*y + z - x) [-y*z + 2*x - 1, -12*y^3 - x*z, -x*y + 1] sage: tangent_vector (x**2 + 2*y**3 - 3*z**4) [2*x, 6*y^2, -12*z^3] sage: tangent_vector (x**2) [2*x] """ t = var("t") newvars = [var("x%s" % i) for i in f.variables()] for o, n in zip(f.variables(), newvars): f = f.subs({o: o+t*n}) d = diff(f, t).limit(t=0) return [d.coefficient(_) for _ in newvars]
def FrechetD(support, dependVar, independVar, testfunction): frechet = [] var("eps") for j in range(len(support)): deriv = [] for i in range(len(support)): def r0(*args): return dependVar[i]( *independVar) + testfunction[i](*independVar) * eps #def _r0(*args): # # this version has issues as it always uses w2 ?!? investigate further # # when time and motivation. Online version on asksage works perfectly # return dependVar[i](*independVar)+ testfunction[i](*independVar) * eps #r0 = function('r0', eval_func=_r0) s = support[j].substitute_function(dependVar[i], r0) deriv.append(diff(s, eps).subs({eps: 0})) frechet.append(deriv) return frechet
def _reduce_inner(e, ld): e2_order = _order(ld) for t in e._p: d = t._d if func(ld) != func(d): continue c = t._coeff e1_order = _order(d) dif = [a - b for a, b in zip(e1_order, e2_order)] if all(map(lambda h: h == 0, dif)): return _Differential_Polynomial( e1.expression() - e2.expression() * c, context) if all(map(lambda h: h >= 0, dif)): variables_to_diff = [] for i in range(len(context._independent)): if dif[i] != 0: variables_to_diff.extend([context._independent[i]] * abs(dif[i])) return _Differential_Polynomial( e1.expression() - c * diff(e2.expression(), *variables_to_diff), context) return e
def FrechetD(support, dependVar, independVar, testfunction): """ >>> t, x = var ("t x") >>> v = function ("v") >>> u = function ("u") >>> w1 = function ("w1") >>> w2 = function ("w2") >>> eqsys = [diff(v(x,t), x) - u(x,t), diff(v(x,t), t) - diff(u(x,t), x)/(u(x,t)**2)] >>> m = Matrix(FrechetD (eqsys, [u,v], [x,t], [w1,w2])) >>> m[0][0] -w1(x, t) >>> m[0][1] diff(w2(x, t), x) >>> m[1][0] 2*w1(x, t)*diff(u(x, t), x)/u(x, t)^3 - diff(w1(x, t), x)/u(x, t)^2 >>> m[1][1] diff(w2(x, t), t) """ frechet = [] var("eps") for j in range(len(support)): deriv = [] for i in range(len(support)): def r0(*args): return dependVar[i]( *independVar) + testfunction[i](*independVar) * eps #def _r0(*args): # # this version has issues as it always uses w2 ?!? investigate further # # when time and motivation. Online version on asksage works perfectly # return dependVar[i](*independVar)+ testfunction[i](*independVar) * eps #r0 = function('r0', eval_func=_r0) s = support[j].substitute_function(dependVar[i], r0) deriv.append(diff(s, eps).subs({eps: 0})) frechet.append(deriv) return frechet
def infinitesimalsODE (ode, dependent, independent): def order(ode, dep, indep): return 3 prolongation = prolongationODE(ode, dependent, independent)[0] from pprint import pprint print ("PROLONGATION") prolongation.show() l = [] def collect(prol, d): res = 0 s = prol.operands() for _s in s: locs = _s.operands() if d in locs: res += _s/d return res for o in range (order(ode, y, x),0,-1): d = diff(dependent(independent), independent)**o c = collect(prolongation, d) l.append(c.expand()) prolongation = prolongation - c*d l.append (prolongation.expand()) janet = Janet_Basis(l, [xi, phi], [x, y]) return janet
def diff(self, *args): return type(self)(diff(self.expression(), *args), self._context)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Tue Dec 14 14:10:23 2021 @author: tapir """ import sage.all from sage.calculus.var import var, function from sage.calculus.functional import diff from delierium.MatrixOrder import Context, Mgrlex, Mgrevlex, Mlex vars = var("x y") z = function("z")(*vars) w = function("w")(*vars) # ctx: items are in descending order ctx = Context((w, z), vars, Mgrevlex) f1 = diff(w, y) + x * diff(z, y) / (2 * y * (x**2 + y)) - w / y f2 = diff(z, x, y) + y * diff(w, y) / x + 2 * y * diff(z, x) / x f3 = diff(w, x, y) - 2 * x * diff(z, x, 2) / y - x * diff(w, x) / y**2 f4 = diff(w, x, y) + diff(z, x, y) + diff(w, y) / (2 * y) - diff( w, x) / y + x * diff(z, y) / y - w / (2 * y**2) f5 = diff(w, y, y) + diff(z, x, y) - diff(w, y) / y + w / (y**2) system_2_24 = [f1, f2, f3, f4, f5]
# # when time and motivation. Online version on asksage works perfectly # return dependVar[i](*independVar)+ testfunction[i](*independVar) * eps #r0 = function('r0', eval_func=_r0) s = support[j].substitute_function(dependVar[i], r0) deriv.append(diff(s, eps).subs({eps: 0})) frechet.append(deriv) return frechet var("t x") v = function("v") u = function("u") w1 = function("w1") w2 = function("w2") eqsys = [ diff(v(x, t), x) - u(x, t), diff(v(x, t), t) - diff(u(x, t), x) / (u(x, t)**2) ] eqsys FrechetD(eqsys, [u, v], [x, t], [w1, w2]) var("t x y") v = function("v") u = function("u") z = function("z") w1 = function("w1") w2 = function("w2") w3 = function("w3") eqsys1 = [
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Tue Dec 14 14:10:23 2021 @author: tapir """ import sage.all from sage.calculus.var import var, function from sage.calculus.functional import diff from delierium.MatrixOrder import Context, Mgrlex, Mgrevlex, Mlex vars = var("x y") z = function("z")(*vars) w = function("w")(*vars) # ctx: items are in descending order ctx = Context((w, z), vars, Mgrevlex) g1 = diff(z, y, y) + diff(z, y) / (2 * y) g2 = diff(w, x, x) + 4 * diff(w, y) * y**2 - 8 * (y**2) * diff(z, x) - 8 * w * y g3 = diff( w, x, y) - diff(z, x, x) / 2 - diff(w, x) / (2 * y) - 6 * (y**2) * diff(z, y) g4 = diff(w, y, y) - 2 * diff(z, x, y) - diff(w, y) / (2 * y) + w / (2 * y**2) system_2_25 = [g2, g3, g4, g1]
def f(n): return diff(expr,var,n).substitute({var:at})/factorial(n)
def f(n): return diff(g[n],_t)(_t=0)
from IPython.core.debugger import set_trace function('xi phi') def infinitesimalsODE (ode, dependent, independent): def order(ode, dep, indep): return 3 prolongation = prolongationODE(ode, dependent, independent)[0] from pprint import pprint print ("PROLONGATION") prolongation.show() l = [] def collect(prol, d): res = 0 s = prol.operands() for _s in s: locs = _s.operands() if d in locs: res += _s/d return res for o in range (order(ode, y, x),0,-1): d = diff(dependent(independent), independent)**o c = collect(prolongation, d) l.append(c.expand()) prolongation = prolongation - c*d l.append (prolongation.expand()) janet = Janet_Basis(l, [xi, phi], [x, y]) return janet ode = 4*diff(y(x),x,x)*y(x) - 3* diff(y(x),x)**2-12*y(x)**3 inf = infinitesimalsODE(ode, y ,x) inf.show()