2012-04-26 4 views
0

파이썬 파라미터 곡선을 따라 소정 아크 거리의 위치를 ​​찾기 : (X, Y) = F (t)I 매개 변수화 된 2D 커브를

함수 f는 임의이지만 미분 가능이고, 따라서 I 수 표준 공식을 사용하여 어느 지점에서든지 커브를 따라 미분 아크 길이 ds를 계산하십시오. 차등 호 길이 공식을 수치 적으로 적분하여 곡선의 처음부터 끝까지 총 호 길이 S (t)를 구할 수도 있습니다. 계산의 정확성을 제어 할 수 있습니다.

곡선의 시작 부분에서 총 호 길이 S = D 인 점 (x, y)을 찾고자합니다. 구현이 파이썬에 있다면 더 좋습니다. 저는 이것을 여러 번 할 것이며, 정확성과 컨버전스에 대한 확신에 대한 엄격한 통제가 필요한 계산 응용 프로그램의 일부입니다.

루트 찾기가 가장 좋은 방법인지는 모르지만 제 질문은 g (t) = S (t) - D에 대한 근원 찾기 문제와 같습니다. 여기서 g (t)는 계산되지 않습니다. 정확히 S (t)가 그렇지 않기 때문이다. 부정확 한 함수 평가는 정확도뿐만 아니라 g (t)의 단조 로움도 엉망으로 만듭니다. 나는 처음부터 단단한 수치 적 통합을 시도했지만 영원히 걸립니다. 루트 알고리즘이 수렴 할 때 뿌리 발견 알고리즘이 진행되는 동안 통합 정확도를 느리게 제어해야하고, 처음에는 부적절한 평가를 요구하고 정확도를 높이려면 필자가 요구하는 내약성에 맞춰야합니다.

쉽게 이용할 수있는 것이 있습니까? 그것을 할 수있는 영리한 방법이 있습니까?

도움 말 감사

+0

그냥 상황을 이해하려고합니다. t는 맞습니까? 귀하의 알려진 위치 : 시작 시간, 시작 위치, 종료 시간 및 끝 곡선 길이 (t0, x0, y0, tF, S (tF) = D). 그 변위에 대한 최종 위치 (xF, yF)를 찾고 싶습니다. x에 명시 적 함수로 곡선을 작성할 수 있습니까? 예 : y = h (x)? – fraxel

+0

안녕하십니까 : t는 커브를 매개 변수화하는 더미 변수 일뿐입니다. 나는 그것이 시간으로 생각하는 것에 어떤 해를 끼치 지 않는다고 생각한다. 덧붙여 말하자면, HYRY는 정확히 나의 접근 방식을 보여주는 코드를 게시하여 나를 도왔다 고 생각합니다. –

+0

하지만 .. t를 제거하고 x에서 명시적인 함수를 얻을 수 있습니까? 예 : y = h (x)? (아마도 당신은 할 수 있습니다) 그렇다면 나는 이것을 할 수있는 멋진 방법이 있을지 모릅니다. – fraxel

답변

2

몇 가지 코드를 게시하고 문제점을 알려주십시오.

from scipy.integrate import quad 
from scipy.optimize import fsolve 
from math import cos, sin, sqrt, pi 

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 curve_length(t0, S, length): 
    return quad(S, 0, t0)[0] - length 

def solve_t(curve_diff, length):  
    return fsolve(curve_length, 0.0, (curve_diff, length))[0] 

print solve_t(circle_diff, 2*pi) 
print solve_t(sin_diff, 7.640395578) 
0

OK, @HYRY가 여기에 크게 당신을 기반으로 코드입니다 :

다음은 S (t)는 == D를 t를 계산 나의 버전입니다. 성공하려면 "쿼드 러처"대신 "쿼드"를 사용하십시오. 그래서 나는 적어도 당신의 대답에 투표 할 것이지만 나는 이야기에 덧붙이고 싶습니다.

먼저 코드가 빠르게 돌아 갔지만 정확도가 부족한 곳은 약 5 군데였습니다. 쿼드 톨과 옵트톨을 예제에 추가하여 직교 및 루트 찾기 정확도의 상호 작용을 설명하려고했습니다. 나는 또한 속도 차이를 드러내 기 위해 기본 높은 공차를 기반으로 한 루프를 추가했다.

sin 예제는 정확도에서 circle보다 훨씬 더 민감합니다. 나는 또한 fareve가이 예제에서 실패하고 어떤 brentq조차도이 작업에서 같거나 더 좋기 때문에 고지 함수 (angegeometric function)에 의해 아크 길이가 주어지고 "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)