Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
"""Utility functions for classifying and solving ordinary and partial differential equations.
Contains ======== _preprocess ode_order _desolve
"""
"""Prepare expr for solving by making sure that differentiation is done so that only func remains in unevaluated derivatives and (if hint doesn't end with _Integral) that doit is applied to all other derivatives. If hint is None, don't do any differentiation. (Currently this may cause some simple differential equations to fail.)
In case func is None, an attempt will be made to autodetect the function to be solved for.
>>> from sympy.solvers.deutils import _preprocess >>> from sympy import Derivative, Function, Integral, sin >>> from sympy.abc import x, y, z >>> f, g = map(Function, 'fg')
Apply doit to derivatives that contain more than the function of interest:
>>> _preprocess(Derivative(f(x) + x, x)) (Derivative(f(x), x) + 1, f(x))
Do others if the differentiation variable(s) intersect with those of the function of interest or contain the function of interest:
>>> _preprocess(Derivative(g(x), y, z), f(y)) (0, f(y)) >>> _preprocess(Derivative(f(y), z), f(y)) (0, f(y))
Do others if the hint doesn't end in '_Integral' (the default assumes that it does):
>>> _preprocess(Derivative(g(x), y), f(x)) (Derivative(g(x), y), f(x)) >>> _preprocess(Derivative(f(x), y), f(x), hint='') (0, f(x))
Don't do any derivatives if hint is None:
>>> eq = Derivative(f(x) + 1, x) + Derivative(f(x), y) >>> _preprocess(eq, f(x), hint=None) (Derivative(f(x) + 1, x) + Derivative(f(x), y), f(x))
If it's not clear what the function of interest is, it must be given:
>>> eq = Derivative(f(x) + g(x), x) >>> _preprocess(eq, g(x)) (Derivative(f(x), x) + Derivative(g(x), x), g(x)) >>> try: _preprocess(eq) ... except ValueError: print("A ValueError was raised.") A ValueError was raised.
"""
raise ValueError('The function cannot be ' 'automatically detected for %s.' % expr) return expr, func d.has(func) or set(d.variables) & fvars]
""" Returns the order of a given differential equation with respect to func.
This function is implemented recursively.
Examples ========
>>> from sympy import Function >>> from sympy.solvers.deutils import ode_order >>> from sympy.abc import x >>> f, g = map(Function, ['f', 'g']) >>> ode_order(f(x).diff(x, 2) + f(x).diff(x)**2 + ... f(x).diff(x), f(x)) 2 >>> ode_order(f(x).diff(x, 2) + g(x).diff(x, 3), f(x)) 2 >>> ode_order(f(x).diff(x, 2) + g(x).diff(x, 3), g(x)) 3
"""
else: else:
"""This is a helper function to dsolve and pdsolve in the ode and pde modules.
If the hint provided to the function is "default", then a dict with the following keys are returned
'func' - It provides the function for which the differential equation has to be solved. This is useful when the expression has more than one function in it.
'default' - The default key as returned by classifier functions in ode and pde.py
'hint' - The hint given by the user for which the differential equation is to be solved. If the hint given by the user is 'default', then the value of 'hint' and 'default' is the same.
'order' - The order of the function as returned by ode_order
'match' - It returns the match as given by the classifier functions, for the default hint.
If the hint provided to the function is not "default" and is not in ('all', 'all_Integral', 'best'), then a dict with the above mentioned keys is returned along with the keys which are returned when dict in classify_ode or classify_pde is set True
If the hint given is in ('all', 'all_Integral', 'best'), then this function returns a nested dict, with the keys, being the set of classified hints returned by classifier functions, and the values being the dict of form as mentioned above.
Key 'eq' is a common key to all the above mentioned hints which returns an expression if eq given by user is an Equality.
See Also ======== classify_ode(ode.py) classify_pde(pde.py) """
# preprocess the equation and find func if not given
# type is an argument passed by the solve functions in ode and pde.py # that identifies whether the function caller is an ordinary # or partial differential equation. Accordingly corresponding # changes are made in the function.
# Magic that should only be used internally. Prevents classify_ode from # being called more than it needs to be by passing its results through # recursive calls. n=terms, x0=x0, prep=prep)
else: # Here is what all this means: # # hint: The hint method given to _desolve() by the user. # hints: The dictionary of hints that match the DE, along with other # information (including the internal pass-through magic). # default: The default hint to return, the first hint from allhints # that matches the hint; obtained from classify_ode(). # match: Dictionary containing the match dictionary for each hint # (the parts of the DE for solving). When going through the # hints in "all", this holds the match string for the current # hint. # order: The order of the DE, as determined by ode_order(). {'default': hint, hint: kwargs['match'], 'order': kwargs['order']}) str(eq) + " is not a differential equation in " + str(func))
# classify_ode will set hints['default'] to None if no hints match. if hint not in allhints and hint != 'default': raise ValueError("Hint not recognized: " + hint) elif hint not in hints['ordered_hints'] and hint != 'default': raise ValueError(string + str(eq) + " does not match hint " + hint) else: raise NotImplementedError(dummy + "solve" + ": Cannot solve " + str(eq)) prep=prep, x0=x0, classify=False, order=hints['order'], match=hints[hints['default']], xi=xi, eta=eta, n=terms, type=type) for i in hints: if i.endswith('_Integral'): gethints.remove(i[:-len('_Integral')]) # special cases for k in ["1st_homogeneous_coeff_best", "1st_power_series", "lie_group", "2nd_power_series_ordinary", "2nd_power_series_regular"]: if k in gethints: gethints.remove(k) classify=False, n=terms, order=hints['order'], match=hints[i], type=type) else: # Key added to identify the hint needed to solve the equation |