Как переставить сложное уравнение на Python - PullRequest
1 голос
/ 13 апреля 2020

Я хочу изменить приведенное ниже уравнение для переменной r, используя Python.

P = C * ((1-(1+r)**(-n)))/r + fv*(1+r)**(-n)
to
r = blabla...

Я понял, что sympy связан с такой задачей перестановки. Итак, я написал следующие коды.

# Solve the equation for r
import sympy
from sympy import symbols

P, C, r, n, fv = sympy.symbols('P C r n fv')
eq = sympy.Eq(P, C * ((1-1/(1+r)**n))/r + fv/(1+r)**n)
sympy.solve(eq, r)

Тем не менее, я получил такую ​​ошибку. Вы знаете, как выполнить такую ​​сложную перестановку для уравнения? Я использую Python == 3.7, sympy == 1.4.

Ответы [ 2 ]

1 голос
/ 13 апреля 2020

Это не тривиальное уравнение для решения. Это не имеет ничего общего с расчетом мощности, просто уравнение слишком сложное, чтобы его можно было решить для r.

Однако, если для других переменных есть определенные c значения, и вам нужно найти для r (то есть найти ноль для нетривиального уравнения), вы можете использовать числовой решатель: nsolve

# Solve the equation for r
from sympy import var, Eq, solve

var('C, r, n, fv, P', positive = True)

# this throws an error: no algorithms are implemented to solve equation
equation = Eq(P, C * ((1-1/(1+r)**n))/r + fv/(1+r)**n)

# a simple calculation for power works fine
equation = Eq(P, (1+r)**n)
solve(equation, r)
0 голосов
/ 14 апреля 2020

Уравнение, которое вы пытаетесь решить:

In [23]: eq                                                                                                                       
Out[23]: 
      ⎛           -n⎞               
    C⋅⎝1 - (r + 1)  ⎠             -n
P = ───────────────── + fv⋅(r + 1)  
            r 

Мы можем переставить это в многочлен, например:

In [24]: eq2 = Eq(eq.lhs * (1+r)**n * r, eq.rhs * (1+r)**n * r).expand()                                                          

In [25]: eq2                                                                                                                      
Out[25]: 
           n            n           
P⋅r⋅(r + 1)  = C⋅(r + 1)  - C + fv⋅r

Теперь мы видим, что это многочлен, за исключением того, что показатель n является символом c. В общем случае уравнение такого типа не будет иметь решения, выражаемого в замкнутой форме, поэтому у sympy нет алгоритмов для этого конкретного случая (это не ограничение самого sympy).

Это можно решить Уравнение численно, но численное решение работает, только если у нас есть числовые значения для каждого из параметров. Если мы подставим числа для параметров, то nsolve сможет найти решение численно:

In [26]: eq3 = eq.subs({P:1, C:2, fv:1, n:100})                                                                                   

In [27]: eq3                                                                                                                      
Out[27]: 
                   ⎛        1     ⎞
                 2⋅⎜1 - ──────────⎟
                   ⎜           100⎟
        1          ⎝    (r + 1)   ⎠
1 = ────────── + ──────────────────
           100           r         
    (r + 1)                        

In [28]: nsolve(eq3, r, 1)                                                                                                        
Out[28]: 2.00000000000000

Но обратите внимание, что решения этого уравнения не являются уникальными, например, -2 также является решением здесь:

In [52]: nsolve(eq3, r, -1.9)                                                                                                     
Out[52]: -2.00000000000000

Это конкретное уравнение имеет что-то вроде 100 корней, хотя не обязательно все реальные.

...