Methods to Speed-up fsolve

조회 수: 69 (최근 30일)
Carlos Acasuso
Carlos Acasuso 2020년 12월 2일
편집: Matt J 2020년 12월 2일
Hello,
I am attempting to speed-up a solution to a system of equations.
I have already made huge progress by rewriting my problem to use fsolve, instead of solving symbolically using vpasolve, where I have gone down from around 0.3s to now solving in 0.0045s.
I am solving this system in a for loop for 1,000 data points, so it is running in around 4.5s.
My idea is to make it as efficient as possible, as the data files I am planning to execute could range to >100,000 data points.
For this, I have done background reading on using Parallel Computing such as parfor, parfeval or spmd to try use more of my available computer power and bring the execution time down by a few folds, if possible.
tic
for i = 1:1000
LDamperFL_st = string(LDamperFL(i));
LDamperFR_st = string(LDamperFR(i));
SteerRackTravel_st = string(SteerRackTravel(i));
f = replace(f,["LDamperFL","LDamperFR","xSteerRack"], [LDamperFL_st, LDamperFR_st, SteerRackTravel_st]);
Sfun_R = str2func(f);
Solution(:,i) = fsolve(Sfun_R, rand(14,1), opts);
end
toc
The solution output (Solution) consists of a 14x1000 double array.
I have attempted to use parfor, but the solution takes significantly longer (15.2s for a loop of 1000 data points, 0.0152s per solution)
I have attempted to use parforeval:
tic
[Solution] = parfeval(ResolveKin, 1, LDamperFL, LDamperFR, SteerRackTravel, f, opts);
toc
where my function is:
function [KinSol] = ResolveKin(LDamperFL, LDamperFR, SteerRackTravel, f, opts)
for i = 1:1000
LDamperFL_st = string(LDamperFL(i));
LDamperFR_st = string(LDamperFR(i));
SteerRackTravel_st = string(SteerRackTravel(i));
f = replace(f,["LDamperFL","LDamperFR","xSteerRack"], [LDamperFL_st, LDamperFR_st, SteerRackTravel_st]);
Sfun_R = str2func(f);
KinSol(:,i) = fsolve(Sfun_R, rand(14,1), opts);
end
end
But I get the following error:
Not enough input arguments.
I have also attempted to us spmd by I get an error:
Warning: Saving Composites is not supported.
For spmd, I believe I am just not coding it correctly, but I struggle to figure out how to do this.
Finally, I have also attempted to set my fsolve "opts" as shown below, in an attempt to run fsolve in parallel and test if this helps to run the loop quicker.
opts = optimoptions('fsolve', 'Display', 'none', 'UseParallel',true);
But if I do so it takes much longer to execute my 1000 data points loop, taking 318s (0.318s per soltuion)
Thank you very much for your help, very much appreciated.
I could share my full script privately if it helped.
Regards,
Carlos

채택된 답변

Matt J
Matt J 2020년 12월 2일
편집: Matt J 2020년 12월 2일
If the solutions are expected to evolve continuously, it can save time to use the last result as the initial guess for the next one. Also, pre-allocating KinSol should also speed things up.
function [KinSol] = ResolveKin(LDamperFL, LDamperFR, SteerRackTravel, f, opts)
x0=rand(14,1);%<---
KinSol=nan(14,1000); %<---
for i = 1:size(KinSol,2) %<---
LDamperFL_st = string(LDamperFL(i));
LDamperFR_st = string(LDamperFR(i));
SteerRackTravel_st = string(SteerRackTravel(i));
f = replace(f,["LDamperFL","LDamperFR","xSteerRack"], [LDamperFL_st, LDamperFR_st, SteerRackTravel_st]);
Sfun_R = str2func(f);
x0 = fsolve(Sfun_R, x0, opts);%<---
KinSol(:,i) = x0;%<---
end
end
Aside from that, I do not understand why you are updating f in every iteration of the loop. After the first iteration, it doesn't look like f will change at all. If you are doing this just to substitute new sets of numeric data into the formula for f, there are indeed more efficient ways to accomplish this.
  댓글 수: 1
Carlos Acasuso
Carlos Acasuso 2020년 12월 2일
편집: Carlos Acasuso 2020년 12월 2일
Thank you very much Matt J, just looking into your tips I'll let you know soon how I get on.
Just to answer your last question, it is indeed to subsititute the values of LDamperFL, LDamperFR, SteerRackTravel into my function, as the function (i.e. the system of 14 equations) needs to be solved for every instance when these three variables change, and these are just pre-stored in single-vector arrays.
It is then that I need to solve this problem in a loop for the length of my LDamperFL, LDamperFR, SteerRackTravel arrays (these three are all same length).
Hope that is clearer. I will also investigate more efficient ways of doing this as you've linked.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Parallel for-Loops (parfor)에 대해 자세히 알아보기

제품


릴리스

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by