OK、@HYRY、これは主にあなたのものに基づいたコードスニペットです。あなたは私が成功するために必要なヒントを教えてくれました: "quadrature" の代わりに "quad" を使用してください。だから私は少なくともあなたの答えに投票しますが、ストーリーに追加したいと思います.
まず、コードは高速に実行されましたが、私が求めていた精度よりも約 5 桁足りませんでした。あなたの例に quadtol と opttol を追加して、求積法と求根精度の相互作用を説明しようとしました。また、速度の違いを明らかにするために、デフォルトの高許容値に基づいてループを追加しました。
sin の例は、精度に関して円よりもはるかに敏感です。また、弧の長さが超幾何関数によって与えられるパレマー化された曲線を追加し、「brentq」オプションをコメント アウトしました。
"quadrature" は遅いですが、予想される動作を示します: 求根速度、精度、および成功率は、直交許容値によって変化します。
対照的に、「quad」は要求された許容範囲を無視し、常により正確な回答を生成するようです。この要求されていない正確さは、私の質問がもはや興味深いかどうか確信が持てないほど高速に動作することを除けば、煩わしいか、説明を招くでしょう。ありがとう!
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)