Я пишу некоторый код, который использует sympy для создания сложного математического выражения, а затем использует функцию autowrap
для его компиляции и многократной оценки.
К сожалению, мои выражения в некоторых случаях становятся экспоненциально большими,Чтобы предотвратить это, я хочу создать выражения, содержащие операторы присваивания.То есть я хочу получить что-то вроде (псевдокод)
x1 = f(a,a);
x2 = f(x1,x1);
x3 = f(x2,x2);
x4 = f(x3,x3);
вместо
f(f(f(a,a),f(a,a)),f(f(a,a),f(a,a))),f(f(a,a),f(a,a)),f(f(a,a),f(a,a))))
, в котором каждое подвыражение заменяется дважды.
Кажется, есть механизм для этого в виде sympy.codegen.ast.CodeBlock
.Однако я не могу понять, как заставить это работать с autowrap
, если это действительно так.
Если я попытаюсь сделать
>>> f = autowrap(ast.CodeBlock(ast.Assignment(y,sym.sin(x))),backend='cython')
, тогда я получутрассировка длинного стека, заканчивающаяся
wrapped_code_12.c:5:22: error: use of undeclared identifier 'y'
autofunc_result = y = sin(x);
^
1 error generated.
error: command '/usr/bin/clang' failed with exit status 1
, что говорит мне о том, что использование CodeBlock непосредственно внутри autowrap
не является правильным способом сделать это.(Я получаю похожую ошибку, используя бэкэнд Фортрана.)
Вопрос в том, есть ли правильный способ сделать это?Могу ли я использовать CodeBlock
в autowrap
или есть какой-то другой способ, которым я могу генерировать промежуточные переменные с autowrap
, вместо того, чтобы всегда полностью раскрывать мои выражения sympy?