передача numpy ndarray в качестве входных данных функции fsolve - PullRequest
0 голосов
/ 27 июня 2019

Я хочу, чтобы численно решить систему нелинейных уравнений и передать в качестве входных данных Numpy ndarrays. Рассмотрим произвольный код ниже:

import numpy as np
from scipy.optimize import fsolve

def eqs(A, B, C, D):
    eq1 = (A - B * np.sin(C)).tolist()
    eq2 = [5 * B + D * np.sum(A * np.cos(C))]
    return eq1 + eq2

n = 3

A = np.zeros((n))
A0 = np.random.rand(n)
B = 0.0
B0 = np.random.rand(1)[0]

C = np.random.rand(n)
D =  np.random.rand(1)[0]

sol = fsolve(func = eqs, x0 = [A0, B0], args = [C, D])

, что приводит к

отсутствуют обязательные позиционные аргументы

ошибка и изменение функции на:

def eqs(A, B, C, D):
    eq1 = A - B * np.sin(C)
    eq2 = C[0] * B + D * np.sum(A * np.cos(C))
    return [eq1, eq2]

также не помогает. Однако я очень сомневаюсь, что ошибка связана с передачей ndarrays. Одним из подходов может быть изменение всех ndarrays на списки python взад и вперед. Но тогда я не смог бы использовать векторизованные функции numpy, такие как np.sin() ...

Буду признателен, если вы поможете мне узнать, как это сделать.

P.S. Приведенные выше уравнения являются просто произвольными и могут вообще не иметь решений.

Ответы [ 2 ]

1 голос
/ 27 июня 2019

Для этих scipy.optimize функций требуется функция с подписью, подобной

f(x, *args)

x - это массив (часто 1d), который будет меняться решателем; args - это кортеж аргументов, которые просто передаются извне.

Измените eqs, чтобы соответствовать этому шаблону

In [11]: def eqs(X, C, D): 
    ...:     A, B  = X[:-1], X[-1] 
    ...:     eq1 = (A - B * np.sin(C)).tolist() 
    ...:     eq2 = [5 * B + D * np.sum(A * np.cos(C))] 
    ...:     return eq1 + eq2 

    ...: n = 3 
    ...: A0 = np.random.rand(n) 
    ...: B0 = np.random.rand(1) 
    ...:  
    ...: C = np.random.rand(n) 
    ...: D =  np.random.rand(1)  

Сделайте пробный вызов eqs:

In [12]: eqs(np.concatenate((A0,B0)),C,D)                                                            
Out[12]: 
[-0.28460532658572657,
 -0.03649115738682615,
 0.7625781482352719,
 array([5.46430853])]

Теперь попробуйте это в fsolve:

In [13]: fsolve(eqs, np.concatenate((A0,B0)), args=(C,D))                                            
Out[13]: array([0., 0., 0., 0.])
1 голос
/ 27 июня 2019

Проверьте, решает ли это ваше уравнение:

import numpy as np
from scipy.optimize import fsolve

def eqs(X, Y):
    A, B = X[:3], X[3]
    C, D = Y[:3], Y[3]
    eq1 = A - B * np.sin(C)
    eq2 = C[0] * B + D * np.sum(A * np.cos(C))
    return np.append(eq1, eq2)

n = 3

A = np.zeros((n))
A0 = np.random.rand(n)
B = 0.0
B0 = np.random.rand(1)[0]

C = np.random.rand(n)
D =  np.random.rand(1)[0]

sol = fsolve(func = eqs, x0 = np.append(A0, B0), args = np.append(C, D))
sol

Выход:

array([ 0.e+000, -1.e-323,  5.e-324, -1.e-323])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...