Sympy lambdify массив с формой (n,) - PullRequest
0 голосов
/ 03 июля 2018

У меня есть следующая проблема с sympy на данный момент:

У меня есть символическое выражение типа M = matrix([pi*a, sin(1)*b]), которое я хочу lambdify и передать числовому оптимизатору. Проблема заключается в том, что оптимизатору нужна функция для ввода / вывода массивов с фигурами (n,) и, в частности, НЕ (n,1).

Теперь я смог добиться этого с помощью следующего кода (MWE):

import numpy as np
import sympy as sp
a, b = sp.symbols('a, b')
M = sp.Matrix([2*a, b])
f_tmp = sp.lambdify([[a,b]], M, 'numpy')
fun   = lambda x: np.reshape( f_tmp(x), (2,))

Теперь, это, конечно, крайне уродливо, поскольку изменение необходимо применять каждый раз, когда fun оценивается (что может быть МНОГО раз). Есть ли способ избежать этой проблемы? Класс Matrix по определению всегда 2-мерный. Я пытался использовать класс sympy MutableDenseNDimArray, но они не работают в сочетании с lambdify. (символические переменные не распознаются)

1 Ответ

0 голосов
/ 03 июля 2018

Один из способов - преобразовать матрицу во вложенный список и взять первую строку:

fun = sp.lambdify([[a, b]], M.T.tolist()[0], 'numpy')

Теперь fun([2, 3]) равно [4, 3]. Это список Python, а не массив NumPy, но оптимизаторы (по крайней мере, в SciPy) должны с этим согласиться.

Можно также сделать

fun = sp.lambdify([[a, b]], np.squeeze(M), 'numpy')

, который также возвращает список.

В моем тесте вышеописанное было одинаково быстрым и более быстрым, чем версия с функцией обертывания (будь то np.squeeze или np.reshape): около 6 мкс против 9 мкс. Кажется, выгода заключается в устранении одного вызова функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...