Spaces:
Sleeping
Sleeping
File size: 7,502 Bytes
b66f126 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | =========
Solvers
=========
.. note::
For a beginner-friendly guide focused on solving common types of equations,
refer to :ref:`solving-guide`.
>>> from sympy import *
>>> x, y, z = symbols('x y z')
>>> init_printing(use_unicode=True)
A Note about Equations
======================
Recall from the :ref:`gotchas <tutorial_gotchas_equals>` section of this
tutorial that symbolic equations in SymPy are not represented by ``=`` or
``==``, but by ``Eq``.
>>> Eq(x, y)
x = y
However, there is an even easier way. In SymPy, any expression not in an
``Eq`` is automatically assumed to equal 0 by the solving functions. Since `a
= b` if and only if `a - b = 0`, this means that instead of using ``x == y``,
you can just use ``x - y``. For example
>>> solveset(Eq(x**2, 1), x)
{-1, 1}
>>> solveset(Eq(x**2 - 1, 0), x)
{-1, 1}
>>> solveset(x**2 - 1, x)
{-1, 1}
This is particularly useful if the equation you wish to solve is already equal
to 0. Instead of typing ``solveset(Eq(expr, 0), x)``, you can just use
``solveset(expr, x)``.
Solving Equations Algebraically
===============================
The main function for solving algebraic equations is ``solveset``.
The syntax for ``solveset`` is ``solveset(equation, variable=None, domain=S.Complexes)``
Where ``equations`` may be in the form of ``Eq`` instances or expressions
that are assumed to be equal to zero.
Please note that there is another function called ``solve`` which
can also be used to solve equations. The syntax is ``solve(equations, variables)``
However, it is recommended to use ``solveset`` instead.
When solving a single equation, the output of ``solveset`` is a ``FiniteSet`` or
an ``Interval`` or ``ImageSet`` of the solutions.
>>> solveset(x**2 - x, x)
{0, 1}
>>> solveset(x - x, x, domain=S.Reals)
โ
>>> solveset(sin(x) - 1, x, domain=S.Reals)
โง ฯ โ โซ
โจ2โ
nโ
ฯ + โ โ n โ โคโฌ
โฉ 2 โ โญ
If there are no solutions, an ``EmptySet`` is returned and if it
is not able to find solutions then a ``ConditionSet`` is returned.
>>> solveset(exp(x), x) # No solution exists
โ
>>> solveset(cos(x) - x, x) # Not able to find solution
{x โ x โ โ โง (-x + cos(x) = 0)}
In the ``solveset`` module, the linear system of equations is solved using ``linsolve``.
In future we would be able to use linsolve directly from ``solveset``. Following
is an example of the syntax of ``linsolve``.
* List of Equations Form:
>>> linsolve([x + y + z - 1, x + y + 2*z - 3 ], (x, y, z))
{(-y - 1, y, 2)}
* Augmented Matrix Form:
>>> linsolve(Matrix(([1, 1, 1, 1], [1, 1, 2, 3])), (x, y, z))
{(-y - 1, y, 2)}
* A*x = b Form
>>> M = Matrix(((1, 1, 1, 1), (1, 1, 2, 3)))
>>> system = A, b = M[:, :-1], M[:, -1]
>>> linsolve(system, x, y, z)
{(-y - 1, y, 2)}
.. note::
The order of solution corresponds the order of given symbols.
In the ``solveset`` module, the non linear system of equations is solved using
``nonlinsolve``. Following are examples of ``nonlinsolve``.
1. When only real solution is present:
>>> a, b, c, d = symbols('a, b, c, d', real=True)
>>> nonlinsolve([a**2 + a, a - b], [a, b])
{(-1, -1), (0, 0)}
>>> nonlinsolve([x*y - 1, x - 2], x, y)
{(2, 1/2)}
2. When only complex solution is present:
>>> nonlinsolve([x**2 + 1, y**2 + 1], [x, y])
{(-โ
, -โ
), (-โ
, โ
), (โ
, -โ
), (โ
, โ
)}
3. When both real and complex solution are present:
>>> from sympy import sqrt
>>> system = [x**2 - 2*y**2 -2, x*y - 2]
>>> vars = [x, y]
>>> nonlinsolve(system, vars)
{(-2, -1), (2, 1), (-โ2โ
โ
, โ2โ
โ
), (โ2โ
โ
, -โ2โ
โ
)}
>>> system = [exp(x) - sin(y), 1/y - 3]
>>> nonlinsolve(system, vars)
{({2โ
nโ
โ
โ
ฯ + log(sin(1/3)) โ n โ โค}, 1/3)}
4. When the system is positive-dimensional system (has infinitely many solutions):
>>> nonlinsolve([x*y, x*y - x], [x, y])
{(0, y)}
>>> system = [a**2 + a*c, a - b]
>>> nonlinsolve(system, [a, b])
{(0, 0), (-c, -c)}
.. note::
1. The order of solution corresponds the order of given symbols.
2. Currently ``nonlinsolve`` doesn't return solution in form of ``LambertW`` (if there
is solution present in the form of ``LambertW``).
``solve`` can be used for such cases:
>>> solve([x**2 - y**2/exp(x)], [x, y], dict=True)
โกโง ____โซ โง ____โซโค
โขโจ โฑ x โฌ โจ โฑ x โฌโฅ
โฃโฉy: -xโ
โฒโฑ โฏ โญ, โฉy: xโ
โฒโฑ โฏ โญโฆ
>>> solve(x**2 - y**2/exp(x), x, dict=True)
โกโง โ-y โโซ โง โyโโซโค
โขโจx: 2โ
Wโโโโโโฌ, โจx: 2โ
Wโโโโฌโฅ
โฃโฉ โ 2 โ โญ โฉ โ2โ โญโฆ
3. Currently ``nonlinsolve`` is not properly capable of solving the system of equations
having trigonometric functions.
``solve`` can be used for such cases (but does not give all solution):
>>> solve([sin(x + y), cos(x - y)], [x, y])
โกโ-3โ
ฯ 3โ
ฯโ โ-ฯ ฯโ โฯ 3โ
ฯโ โ3โ
ฯ ฯโโค
โขโโโโโโ, โโโโ, โโโโ, โโ, โโ, โโโโ, โโโโ, โโโฅ
โฃโ 4 4 โ โ 4 4โ โ4 4 โ โ 4 4โ โฆ
.. _tutorial-roots:
``solveset`` reports each solution only once. To get the solutions of a
polynomial including multiplicity use ``roots``.
>>> solveset(x**3 - 6*x**2 + 9*x, x)
{0, 3}
>>> roots(x**3 - 6*x**2 + 9*x, x)
{0: 1, 3: 2}
The output ``{0: 1, 3: 2}`` of ``roots`` means that ``0`` is a root of
multiplicity 1 and ``3`` is a root of multiplicity 2.
.. note::
Currently ``solveset`` is not capable of solving the following types of equations:
* Equations solvable by LambertW (Transcendental equation solver).
``solve`` can be used for such cases:
>>> solve(x*exp(x) - 1, x )
[W(1)]
.. _tutorial-dsolve:
Solving Differential Equations
==============================
To solve differential equations, use ``dsolve``. First, create an undefined
function by passing ``cls=Function`` to the ``symbols`` function.
>>> f, g = symbols('f g', cls=Function)
``f`` and ``g`` are now undefined functions. We can call ``f(x)``, and it
will represent an unknown function.
>>> f(x)
f(x)
Derivatives of ``f(x)`` are unevaluated.
>>> f(x).diff(x)
d
โโ(f(x))
dx
(see the :ref:`Derivatives <tutorial-derivatives>` section for more on
derivatives).
To represent the differential equation `f''(x) - 2f'(x) + f(x) = \sin(x)`, we
would thus use
>>> diffeq = Eq(f(x).diff(x, x) - 2*f(x).diff(x) + f(x), sin(x))
>>> diffeq
2
d d
f(x) - 2โ
โโ(f(x)) + โโโ(f(x)) = sin(x)
dx 2
dx
To solve the ODE, pass it and the function to solve for to ``dsolve``.
>>> dsolve(diffeq, f(x))
x cos(x)
f(x) = (Cโ + Cโโ
x)โ
โฏ + โโโโโโ
2
``dsolve`` returns an instance of ``Eq``. This is because, in general,
solutions to differential equations cannot be solved explicitly for the
function.
>>> dsolve(f(x).diff(x)*(1 - sin(f(x))) - 1, f(x))
-x + f(x) + cos(f(x)) = Cโ
The arbitrary constants in the solutions from dsolve are symbols of the form
``C1``, ``C2``, ``C3``, and so on.
|