2011-03-27 3 views
1

여기에서 내가 주제가되기를 바랍니다. FAQ 페이지에서 말한 이후로 묻습니다. 소프트웨어 알고리즘에 관한 질문입니다. 그래서 여기에 있습니다 :MATLAB : ode45에서 feval 호출에 대한 대안

저는 ODE 시스템을 풀 필요가 있습니다 ($ \ dot x = A (Calc_EDS_v2 ('Sys_EDS_a', ...)
그러면 루프에서 ode45를 사용하여 내 x를 찾을 수 있습니다 :

function [intervals, testing] = EDS_calc_v2(smA,options,debug) 
[..] 
for t=t_start:t_step:t_end) 
    [Te,Qe]=func_int(@intQ_2_v2,[t,t+t_step],q); 
    q=Qe(end,:); 
    [..] 
end 
[..] 

ode45 및 @ intQ_2_v2 인 func_int는 내 m 파일입니다. q가 시작 벡터로 호출에 제공됩니다. 볼 수 있듯이 나는 intervall [t, t + t_step]에서 ode45를 사용하고 있습니다. 왜냐하면 시스템 매트릭스 A가 ode45에 많은 단계를 사용하도록 강제 할 수 있기 때문에 AbsTol 또는 RelTol 매우 빠릅니다.

이제 내 A는 B (t) * Q (t)와 비슷합니다. 따라서 m 파일 intQ_2_v2.m에서 시간 t에서 B와 Q를 모두 평가해야합니다. 처음과 같이하여 행해진 (함수 이름이 다른되도록 V1 - 파일)보다

function q=intQ_2_v1(t,X) 
[..] 
B(1)=...; ... B(4)=...; 
Q(1)=...; ... 

만이 2 × 2 매트릭스라고 가정 자연스럽게된다. 이 설정으로 10 초에서 15 초 사이의 기본 시스템을 계산했습니다.

위의 파일 대신 B1.m에서 B4.m과 Q1.m에서 B4.m까지의 파일을 사용합니다. (나는 우아한 것은 아니지만 나중에 B에서 quadgk를 사용해야하고 quadgk는 그렇지 않습니다.

function q=intQ_2_v2(t,X) 
[..] 
global funcnameQ, funcnameB, d 
for k=1:d 
Q(k)=feval(str2func([funcnameQ,int2str(k)]),t); 
B(k)=feval(str2func([funcnameB,int2str(k)]),t); 
end 
[..] 

funcname (string)은 B 또는 Q (k가 추가됨)를 나타내며 d는 시스템의 차원입니다.

이제는 첫 번째 버전보다 더 많은 시간이 소요된다는 것을 알았지 만 컴퓨팅 시간이 10 배나 늘어난 것을보고 있습니다. (150-160 초) ode-loop 당 약 4 배의 파일을 열고 평가하는 것은 비용이 많이 든다는 것을 이해합니다 ... ode45는 적응 단계 크기를 사용하기 때문에 B와 Q를 사전 평가할 수 없습니다 ...

마지막 루프를 사용하지 않을 방법이 있습니까?

주로 컴퓨팅 시간을 줄이는 솔루션에 관심이 많습니다. 나는 뭔가를 놓치고 있다는 느낌이 들지만 ... 내 손가락을 실제로 넣을 수는 없다. 10 초가 아닌 3 분 정도 걸리면 이제 각 테스트 런 사이에 커피를 마실 수 있습니다 ... (더 빠른 컴퓨터를 구하라는 말은하지 마세요)

(오랜 질문은 죄송합니다)

답변

1

여기에서하는 일을 완전히 이해하고 있는지 확신 할 수 없지만 몇 가지 팁을 제공 할 수 있습니다.

  1. 프로파일 러를 사용하면 병목 현상이 발생한 위치를 정확하게 파악하는 데 도움이됩니다.

  2. feval은 함수 핸들을 직접 사용하는 것보다 느립니다. 특히 매번 str2func를 사용하여 핸들을 작성할 때 특히 그렇습니다. 또한 전역 변수를 사용하면 속도가 느려지므로 (절대적으로 필요한 경우가 아니라면 이러한 변수를 사용하지 않는 것이 좋습니다). 이들 각각은 반복적으로 사용할 때 실제로 추가됩니다 (여기처럼 보입니다). 저장 함수는 셀 배열의 각 m 파일에 대한 핸들을 처리에 직접 전달하거나 최적화를 위해 중첩 된 함수를 사용하여 최적화 된 함수에서 핸들의 셀 배열을 볼 수있게합니다. 개인적으로, 나는 중첩 된 메소드를 선호하지만, 다른 곳에있는 mfiles를 사용하면 패스하는 것이 더 좋습니다.

이 방법을 사용하면 런타임에서 첫 번째 방법과 거의 비슷하게 돌아갈 것으로 예상됩니다. 이것이 문제인지 아니면 다른 해결책을 찾았는지 알려주십시오.

+0

답장을 보내 주셔서 감사합니다. 나는 당신이 제안한 것처럼 셀 배열에서 함수 핸들을 사용하여 계산 시간을 절반으로 줄였습니다. 또한 Profiler를 사용하여 다른 영역을 최적화했습니다. a) matlab의 ode solver는 사전 정의 된 함수이고 추가 매개 변수 (afaik)를 전달할 수 없으므로 b) 함수 (B 및 Q)가 나중에 언젠가 변경 될 수 있기 때문에 전역 함수를 사용해야합니다. , 그래서 그들은 메인 파일에 중첩되면 안된다. 도움을 주셔서 감사합니다. 훌륭한 출발점이었습니다! 나는 투표 할 것이지만 지금 당장은 할 수 없다 : -/ – PingLu

+0

@PingLu 기꺼이 도와 주었다. 특히 ODE 해결에 ​​대해서는 많이 알지 못합니다. 그러나 Matlab에서 최적화 도구로 꽤 많이 해봤으며 유사한 문제가있었습니다. 그리고 그 답을 받아 들여라. – MatlabSorter

+0

미안하지만 나는 그 차이를 알지 못했습니다. 이제 받아 들였습니다. 나는 내 스크립트에서 1 ~ 2 초 더 긁어 모으려고했다. Profiler는 정말 대단히 유용하다. – PingLu