OK,@HYRY,这里主要是基于你的代码片段。你给了我成功所需的提示:使用“quad”而不是“quadrature”。所以我至少会为你的答案投票,但我想补充一点。
首先,你的代码跑得快,而是五个地方短的精确度我了。我将quadtol和opttol添加到您的示例中,试图说明正交和根查找精度的相互影响。我还添加了一个基于默认高公差的循环来显示速度差异。
罪示例比对精度的圆敏感得多。我还添加了一条曲线,曲线的弧长由超几何函数给出,“brentq”选项注释掉,因为在这个例子中,fsolve失败,甚至在任何brentq中,这个任务都是相等或更好的。
“积分”是缓慢的,但表现出预期的行为:求根速度,精度和成功的改变与正交宽容。
相比之下,“四边形”似乎忽略了要求的容差并始终产生更准确的答案。这个未被证实的准确性会令人讨厌或者引起一些解释,除非它对于例子的运行速度如此之快,以至于我不能确定我的问题是否有趣。谢谢!
from scipy.integrate import quad, quadrature
from scipy.optimize import fsolve, brentq
from math import cos, sin, sqrt, pi, pow
def circle_diff(t):
dx = -sin(t)
dy = cos(t)
return sqrt(dx*dx+dy*dy)
def sin_diff(t):
dx = 1
dy = cos(t)
return sqrt(dx*dx+dy*dy)
def hypergeom_diff(t):
""" y = t^5 x = t^3 """
dx = 3*t*t
dy = 5*pow(t,4)
return sqrt(dx*dx+dy*dy)
def curve_length(t0, S, length,quadtol):
integral = quad(S, 0, t0,epsabs=quadtol,epsrel=quadtol)
#integral = quadrature(S, 0, t0,tol=quadtol,rtol=quadtol, vec_func = False)
return integral[0] - length
def solve_t(curve_diff, length,opttol=1.e-15,quadtol=1e-10):
return fsolve(curve_length, 0.0, (curve_diff, length,quadtol), xtol = opttol)[0]
#return brentq(curve_length, 0.0, 3.2*pi,(curve_diff, length, quadtol), rtol = opttol)
for i in range(1000):
y = solve_t(circle_diff, 2*pi)
print 2*pi
print solve_t(circle_diff, 2*pi)
print solve_t(sin_diff, 7.640395578)
print solve_t(circle_diff, 2*pi,opttol=1e-5,quadtol=1e-3)
print solve_t(sin_diff, 7.640395578,opttol = 1e-12,quadtol=1e-6)
print "hypergeom"
print solve_t(hypergeom_diff, 2.0,opttol = 1e-12,quadtol=1e-12)
print solve_t(hypergeom_diff, 2.0,opttol = 1e-12,quadtol=1e-6)
只是想了解情况:t是时间吧?您的知识是:开始时间,开始位置,结束时间和结束曲线长度(t0,x0,y0,tF,S(tF)= D)。你想找到那个位移的最后位置,(xF,yF)。你能否把曲线写成一个明确的x函数,即:y = h(x)? – fraxel 2012-04-26 09:58:37
喜fraxel:t只是一个虚拟变量参数化曲线。我不认为它随着时间的推移而产生任何伤害。顺便说一下,我认为HYRY通过发布代码来帮助我,这些代码完全说明了我的方法。 – 2012-04-26 16:31:43
但是..你可以消除t并得到一个明确的函数在x中,即:y = h(x)? (可以假设你可以)如果是这样,我可能有一个很酷的方式来做到这一点。 – fraxel 2012-04-27 06:31:10