Methods to Speed-up fsolve
43 views (last 30 days)
Show older comments
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
0 Comments
Accepted Answer
Matt J
on 2 Dec 2020
Edited: Matt J
on 2 Dec 2020
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.
More Answers (0)
See Also
Categories
Find more on Parallel for-Loops (parfor) in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!