решение нелинейных уравнений с использованием scipy

#scipy

Вопрос:

Я пытаюсь решить следующее уравнение:

введите описание изображения здесь

Где задан список значений A_e/A* и гамма=1,2, как я должен решить это уравнение таким образом, чтобы возвращался список M_e, соответствующий списку значений A_e/A*? Я думал об использовании scipy.optimize.newton , но, похоже, это неправильный подход

 def expr(x):
       
    result = np.arange(1,1.25,step=0.004)-((1/x)*((2/(1.2 1))*(1 ((1.2-1)/2)*x**2))**((1.2 1)/(2*1.2-1)))
            
    return result.any()


scipy.optimize.newton(expr,1.1)


---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
~AppDataLocalTemp/ipykernel_4660/3619719442.py in <module>
----> 1 scipy.optimize.newton(expr,1.1,x1=1.2)

D:SoftwaresAnacondalibsite-packagesscipyoptimizezeros.py in newton(func, x0, fprime, args, tol, maxiter, fprime2, x1, rtol, full_output, disp)
    338                             " Failed to converge after %d iterations, value is %s."
    339                             % (itr   1, p1))
--> 340                         raise RuntimeError(msg)
    341                     warnings.warn(msg, RuntimeWarning)
    342                 p = (p1   p0) / 2.0

RuntimeError: Tolerance of 0.09999999999999987 reached. Failed to converge after 1 iterations, value is 1.2.
 

Я использовал x для обозначения M_e, и я заменил Ae/A* списком значений- np.arange(1,1.25,step=0.004) Но, я думаю, метод Ньютона может возвращать только 1 скалярное значение, но я определил функцию с широким списком значений Ae/A*. Как мне это исправить?

Ответ №1:

newton работает для скалярных функций, и вы превращаете его в векторную функцию. Поскольку вам нужен ноль для разных Ae значений, включите Ae параметр в определение функции, затем вызовите newton несколько раз (вы можете использовать args ключевое слово).:

 def expr(x, a):
    result = a-((1/x)*((2/(1.2 1))*(1 ((1.2-1)/2)*x**2))**((1.2 1)/(2*1.2-1)))
    return result

[newton(expr, .01, args=(a,)) for a in np.arange(1,1.25,step=0.004)]

>>[0.9999999999999992, 0.9944379739232752,0.9889506795317498, 0.9835363421148852, ...
 

Комментарии:

1. У меня есть следующий вопрос. Как я могу заставить результаты быть >1? Это уравнение теоретически должно возвращать как значение меньше 1, так и значение больше 1

2. при newton этом вам нужно указать x0 ( 0.01 в ответе вы можете его изменить). Единственный способ выбрать решение x>1-это установить x0 так, чтобы решение сходилось там. Вы можете сделать это, выбрав достаточно большой x0 (обычно работает) или выбрав x0 так, чтобы xs < xm

3. В качестве альтернативы вы можете использовать метод деления пополам ( scipy.optimize.brentq работает как деление пополам, но быстрее).

4. на самом деле я думаю, что мне нужно изменять предположение о сходимости x0 для каждой итерации, поэтому я изменил код следующим образом: mach_exit_list=[scipy.optimize.newton(expr, tol=1.48e-6,maxiter=1000,args=(a,x)) for a in np.arange(2,50.5,step=0.5) amp; for x in np.arange(2,6.01,step=0.01)] , однако это не работает. Как я должен включить и x то, и a другое args ?

5. пробовать [scipy.optimize.newton(expr, x0, tol=1.48e-6, maxiter=1000, args=(a,)) for a, x0 in zip(np.arange(2,50.5,step=0.5), np.arange(2,6.01,step=0.01) )]