123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- """
- This module implements a method to find
- Euler-Lagrange Equations for given Lagrangian.
- """
- from itertools import combinations_with_replacement
- from sympy.core.function import (Derivative, Function, diff)
- from sympy.core.relational import Eq
- from sympy.core.singleton import S
- from sympy.core.symbol import Symbol
- from sympy.core.sympify import sympify
- from sympy.utilities.iterables import iterable
- def euler_equations(L, funcs=(), vars=()):
- r"""
- Find the Euler-Lagrange equations [1]_ for a given Lagrangian.
- Parameters
- ==========
- L : Expr
- The Lagrangian that should be a function of the functions listed
- in the second argument and their derivatives.
- For example, in the case of two functions $f(x,y)$, $g(x,y)$ and
- two independent variables $x$, $y$ the Lagrangian has the form:
- .. math:: L\left(f(x,y),g(x,y),\frac{\partial f(x,y)}{\partial x},
- \frac{\partial f(x,y)}{\partial y},
- \frac{\partial g(x,y)}{\partial x},
- \frac{\partial g(x,y)}{\partial y},x,y\right)
- In many cases it is not necessary to provide anything, except the
- Lagrangian, it will be auto-detected (and an error raised if this
- cannot be done).
- funcs : Function or an iterable of Functions
- The functions that the Lagrangian depends on. The Euler equations
- are differential equations for each of these functions.
- vars : Symbol or an iterable of Symbols
- The Symbols that are the independent variables of the functions.
- Returns
- =======
- eqns : list of Eq
- The list of differential equations, one for each function.
- Examples
- ========
- >>> from sympy import euler_equations, Symbol, Function
- >>> x = Function('x')
- >>> t = Symbol('t')
- >>> L = (x(t).diff(t))**2/2 - x(t)**2/2
- >>> euler_equations(L, x(t), t)
- [Eq(-x(t) - Derivative(x(t), (t, 2)), 0)]
- >>> u = Function('u')
- >>> x = Symbol('x')
- >>> L = (u(t, x).diff(t))**2/2 - (u(t, x).diff(x))**2/2
- >>> euler_equations(L, u(t, x), [t, x])
- [Eq(-Derivative(u(t, x), (t, 2)) + Derivative(u(t, x), (x, 2)), 0)]
- References
- ==========
- .. [1] https://en.wikipedia.org/wiki/Euler%E2%80%93Lagrange_equation
- """
- funcs = tuple(funcs) if iterable(funcs) else (funcs,)
- if not funcs:
- funcs = tuple(L.atoms(Function))
- else:
- for f in funcs:
- if not isinstance(f, Function):
- raise TypeError('Function expected, got: %s' % f)
- vars = tuple(vars) if iterable(vars) else (vars,)
- if not vars:
- vars = funcs[0].args
- else:
- vars = tuple(sympify(var) for var in vars)
- if not all(isinstance(v, Symbol) for v in vars):
- raise TypeError('Variables are not symbols, got %s' % vars)
- for f in funcs:
- if not vars == f.args:
- raise ValueError("Variables %s do not match args: %s" % (vars, f))
- order = max([len(d.variables) for d in L.atoms(Derivative)
- if d.expr in funcs] + [0])
- eqns = []
- for f in funcs:
- eq = diff(L, f)
- for i in range(1, order + 1):
- for p in combinations_with_replacement(vars, i):
- eq = eq + S.NegativeOne**i*diff(L, diff(f, *p), *p)
- new_eq = Eq(eq, 0)
- if isinstance(new_eq, Eq):
- eqns.append(new_eq)
- return eqns
|