sympyからccode()を使用して、sageの有効なCコードに大きな式を変換しようとしています。しかし、私の表現には多くの二乗と立方体があります。 pow(x、2)はx * xよりもはるかに遅いので、私は式の中で変換前にそれらの項を拡張しようとしています。 this会話に基づいて、私は次のコードを書いた:2乗とキューブの項を乗算に変換する
from sympy import Symbol, Mul, Pow, pprint, Matrix, symbols
from sympy.core import numbers
def pow_to_mul(expr):
"""
Convert integer powers in an expression to Muls, like a**2 => a*a.
"""
pows = list(expr.atoms(Pow))
pows = [p for p in pows if p.as_base_exp()[1]>=0]
if any(not e.is_Integer for b, e in (i.as_base_exp() for i in pows)):
raise ValueError("A power contains a non-integer exponent")
repl = zip(pows, (Mul(*[b]*e,evaluate=False) for b,e in (i.as_base_exp() for i in pows)))
return expr.subs(repl)
それは部分的に動作しますが、限り電源は乗算の引数であるとして失敗します。
>>>_=var('x')
>>>print pow_to_mul((x^3+2*x^2)._sympy_())
2*x**2 + x*x*x
>>>print pow_to_mul((x^2/(1+x^2)+(1-x^2)/(1+x^2))._sympy_())
x**2/(x*x + 1) - (x*x - 1)/(x*x + 1)
なぜ?そして私はそれをどのように変えることができますか? ありがとう、
正確に失敗しましたか? '+(1-x^2)/(1 + x^2)'は ' - (x * x-1)/(x * x + 1)'と同じです。 –
最初の例では、 'x^3 + 2 * x^2'は' 2 * x ** 2 + x * x * x'と同じです。シーケンスは切り替えられ、演算子のスタイルは変わりませんでしたが、数学的には同じです。あなたが何を求めているのかは不明です。 '**'は時には ''と ''にすることができる '^'と区別するために "力に"使われます。 –
問題は、ccode(x * x)はx * xを返し、ccode(x^2)またはccode(x ** 2)はpow(x、2)を返します。 Cプログラムに入ると、後者は本当に最適ではありません。したがって、私は2 * x * x + x * x * xを期待しています。 – Domino