Почему Sympy не решает уравнение и не возвращает пустой список? - PullRequest
1 голос
/ 16 марта 2020

Это мой код, и после одной итерации возврат из sym.solve представляет собой пустой список, даже если существует реальное решение. Почему это случилось? Что я не так сделал?

from scipy import *
import matplotlib.pyplot as plt
import numpy as np
import sympy as sym


rosenbrock = lambda x,y: (1 + x)**2 + 100*(y - x**2)**2
df_rosenbrock = lambda x,y: np.array([-400*x*y + 400*x**3 + 2*x -2, 200*y -200*x**2])
gradient = lambda x,y,alpha: np.array((x,y)) - (alpha * df_rosenbrock(x, y))

x,y = (-2,-2)
for i in range(10):
  a = sym.symbols('alpha', real = True)
  d_0 = - df_rosenbrock(x, y)
  x_0 = np.array((x,y))
  f = rosenbrock(*(x_0 + a*d_0))
  f_df = sym.diff(f,a)
  results = sym.solve(f_df, a)
  results = [result.evalf() for result in results]
  new_results = [sym.re(result) for result in results if (sym.re(result) > 0)]

  if new_results == []:
    alpha = 0.0002
  else:
    alpha = max(new_results)

  x,y = gradient(x,y,alpha)

Ответы [ 2 ]

2 голосов
/ 16 марта 2020

Когда вы работаете с Floats, лучше избегать использования solve. nsolve хороший вариант; real_roots - лучший вариант для вашего выражения полинома. Модифицированный код для l oop приведен ниже:

x,y = (-2,-2)
a = sym.symbols('alpha', real = True)
g = 0
for i in range(10):
  d_0 = - df_rosenbrock(x, y)
  x_0 = np.array((x,y))
  f = rosenbrock(*(x_0 + a*d_0))
  f_df = sym.diff(f,a)
  results = real_roots(f_df)
  results = [result.evalf() for result in results]
  print(results)
  if results == []:
    alpha = 0.0002
  else:
    alpha = max(results)
  x,y = gradient(x,y,alpha)

Это дает в качестве вывода:

[0.000441337793142084]
[0.00515203928757550, 0.0319174312939091, 0.0586149494008985]
[-3.10788521492778, -1.55403909321385, 0.000190101167850467]
[9.55804650314387e-6, 0.888327666156469, 1.77644094084023]
[-2.10061893789262, -1.05020390268404, 4.22416276906710e-6]
[-2.21819554773374, -1.10898951281205, 2.77707471229222e-7]
[-2.22597281529973, -1.11287797130474, 1.83791879133972e-8]
[-2.22648773727225, -1.11313542069817, 1.21690353113779e-9]
[-2.22652183165770, -1.11315246712336, 8.05747904731784e-11]
[-2.22652408915671, -1.11315359582205, 5.33504194318928e-12]

Хорошая особенность real_roots в том, что корни реальны, поэтому вам не нужно беспокоиться об обработке воображаемых деталей.

0 голосов
/ 16 марта 2020

Недавно я обнаружил, что это происходит потому, что я объявлял альфа как реальную, и, несмотря на то, что выражение имело реальные решения, решатель возвращает ответ с мнимой частью, близкой к нулю (1e-50). Эти решения рассматривались как комплексные числа, и по этой причине решатель возвратил пустой список.

...