Вы делаете несколько странных вещей, но я не могу сказать, насколько это связано с упрощенным MCVE.
Во-первых, немного более элегантное определение вашей функции:
import sympy as sym
x = sym.Symbol('x')
a = sym.Matrix([1, 1, 1])
dot = sym.Function('dot')
f = dot(x, a)
ff = sym.lambdify(x, f, modules='numpy')
Причина этого и ваш оригинальный ляп работает, потому что все, что вы должны добиться того, чтобы иметь что-то , который говорит «dot
». После этого lambdify
заменит np.dot
той части вашего символа.
Теперь, просто для полноты картины, вот как я бы сделал это вместо:
import numpy as np
a = np.array([[1],[1],[1]])
ff = lambda x,a=a: np.dot(x,a)
Я знаю, что это не может быть вариантом в вашей конкретной проблеме, но мой опыт показывает, что если что-то может быть сделано без символической математике, тогда это стоит делать так.
Теперь для вашей ошибки. Ошибка довольно ясна, и математика тоже. Вы определили функцию, которая для любого входа x
вычисляет x*a
с вектором 3d-столбца a
. Как показывает ошибка, это имеет смысл в очень ограниченном числе случаев. Было бы разумно, если бы оба операнда были 3-элементными 1d-массивами, в этом случае скалярное произведение было бы возвращено. Однако, поскольку один из ваших операндов фиксирован до формы (3,1)
, np.dot
выполняет только умножение матрицы (и для векторного ввода возвращает 1-элементный 1-й массив вместо скаляра). Благодаря вашему определению он работает только с матрицами, которые могут быть умножены справа на a
, то есть матрицы формы (N,3)
. Ясно, что это не так для вашего ввода.
Что вы должны сделать, транспонировать x
на числовой стороне:
x = np.random.rand(3,10)
print(ff(x.T))
Это ввести массив формы (10,3)
в функцию, которая затем умножает его одним из формы (3,1)
, в результате чего 2d-массив формы (10,1)
: вектор-столбец, каждая строка содержит скалярное произведение, если данный входной вектор равен a
.
Другой вариант поменять определение вашей функции:
f = dot(a.T,x)
ff = sym.lambdify(x, f, modules='numpy')
# or
a = np.array(1,1,1) # transpose of previous a
ff = lambda x,a=a: np.dot(a,x)
Оба создать функцию, которая умножать массив формы (1,3)
с правой стороны с входом. Тогда ваш ввод x
формы (3,10)
непосредственно совместим; выход будет 1d массивом из 10 скалярных продуктов. В этой формулировке
О, эй, я не понимал, что вы автор matlab2tikz. Удивительная работа! :) –
Спасибо! Проверьте https://github.com/nschloe/matplotlib2tikz, если вы хотите активировать свою сюжетную игру. –