问题描述
使用SymPy找到一个衍生物(见这个问题:http://math.stackexchange.com/questions/726104/apply-chain-rule-to-vector-function-with-chained-dot-and-cross-product ),我想出了这个code:
Using SymPy to find a derivative (see this question: http://math.stackexchange.com/questions/726104/apply-chain-rule-to-vector-function-with-chained-dot-and-cross-product ), I came up with this code:
from sympy import *
from sympy.physics.mechanics import *
from sympy.printing import print_ccode
from sympy.utilities.codegen import codegen
x1, x2, x3 = symbols('x1 x2 x3')
y1, y2, y3 = symbols('y1 y2 y3')
z1, z2, z3 = symbols('z1 z2 z3')
u = ReferenceFrame('u')
u1=(u.x*x1 + u.y*y1 + u.z*z1)
u2=(u.x*x2 + u.y*y2 + u.z*z2)
u3=(u.x*x3 + u.y*y3 + u.z*z3)
s1=(u1-u2).normalize()
s2=(u2-u3).normalize()
v=cross(s1, s2)
f=dot(v,v)
df_dy2=diff(f, y2)
print_ccode(df_dy2, assign_to='df_dy2')
[(c_name, c_code), (h_name, c_header)] = codegen( ("df_dy2", df_dy2), "C", "test", header=False, empty=False)
print c_code
这会产生这种美:
Which yields this beauty:
#include "test.h"
#include <math.h>
double df_dy2(double x1, double x2, double x3, double y1, double y2, double y3, double z1, double z2, double z3) {
return ((x1 - x2)*(y2 - y3)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2))) - (x2 - x3)*(y1 - y2)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2))))*(2*(x1 - x2)*(y1 - y2)*(y2 - y3)/(pow(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2), 3.0L/2.0L)*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2))) + 2*(x1 - x2)*(-y2 + y3)*(y2 - y3)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*pow(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2), 3.0L/2.0L)) + 2*(x1 - x2)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2))) - 2*(x2 - x3)*pow(y1 - y2, 2)/(pow(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2), 3.0L/2.0L)*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2))) - 2*(x2 - x3)*(y1 - y2)*(-y2 + y3)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*pow(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2), 3.0L/2.0L)) + 2*(x2 - x3)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2)))) + (-(x1 - x2)*(z2 - z3)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2))) + (x2 - x3)*(z1 - z2)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2))))*(-2*(x1 - x2)*(y1 - y2)*(z2 - z3)/(pow(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2), 3.0L/2.0L)*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2))) - 2*(x1 - x2)*(-y2 + y3)*(z2 - z3)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*pow(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2), 3.0L/2.0L)) + 2*(x2 - x3)*(y1 - y2)*(z1 - z2)/(pow(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2), 3.0L/2.0L)*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2))) + 2*(x2 - x3)*(-y2 + y3)*(z1 - z2)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*pow(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2), 3.0L/2.0L))) + ((y1 - y2)*(z2 - z3)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2))) - (y2 - y3)*(z1 - z2)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2))))*(2*pow(y1 - y2, 2)*(z2 - z3)/(pow(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2), 3.0L/2.0L)*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2))) + 2*(y1 - y2)*(-y2 + y3)*(z2 - z3)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*pow(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2), 3.0L/2.0L)) - 2*(y1 - y2)*(y2 - y3)*(z1 - z2)/(pow(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2), 3.0L/2.0L)*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2))) - 2*(-y2 + y3)*(y2 - y3)*(z1 - z2)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*pow(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2), 3.0L/2.0L)) - 2*(z1 - z2)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2))) - 2*(z2 - z3)/(sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2))*sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2) + pow(z2 - z3, 2))));
}
有相同编号的sqrts和战俘,这可能是计算一次以提高可读性和执行时间的几个多次出现。但我不知道该怎么...
there are several multiple occurrences of the sqrts and pows of the same numbers, which could be computed once to improve readability and time of execution. But I do not know how...
Q1:你知道的方法,使sympy自动执行此操作。
Q1: Do you know of a way to make sympy do this automatically?
Q2:你知道的一种方式进行后处理这个code与其他工具
Q2: Do you know of a way to postprocess this code with an other tool?
Q3:在编译时GCC优化呢?为什么呢?
Q3: Can gcc optimize this at compile time? Why?
推荐答案
GCC可能会优化,但如果你想自己做,看一看 CSE
。的
gcc will probably optimize this, but if you want to do it yourself, take a look at cse
. http://docs.sympy.org/latest/modules/simplify/simplify.html#module-sympy.simplify.cse_main
这篇关于通过优化产生sympy code的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!