Use Parfoor Loop for Parameter Sweep Optimization

4 views (last 30 days)
Hello, I have a general optimization problem that the solution looks something like this (sweeping across parameter p):
maxval = 0;
for a = 1:length(p);
val = somefunction(p(a));
if val > maxval
pmax = p(a);
maxval = val;
end
end
Where I would like to convert into a Parfor loop to find the optimal p that maximizes val. I am struggling to avoid converting into a parfor loop by using only reduction variables. The best I could do looks something like this:
parfor a = 1:length(p);
listval = [val;somefunction(p(a))];
listp = [listp,p(a)];
end
imax = find(val == max(val));
pmax = listp(imax);
So as you can see I am storing the value of every iteration when I am only interested in finding the max value. Also, I am not preallocating memory and my lists (listval & listp) are increasing in size in every iteration. I have the intuition there must be a better solution, as this seems very inefficient, but I have not been able to find anything on the documentation. I have also tried:
maxval = max(maxval,val) instead of the if statement
but of course this only yields the value for the best solution but not the parameter that achieves it. I would appreciate any pointers.

Accepted Answer

Edric Ellis
Edric Ellis on 10 Nov 2022
You can do this using a custom reduction function in parfor. Like this:
p = 1:10;
someFcn = @sin;
% Use a 2-element vector to store maximum
% value of someFcn(x), as well as the input x.
maxVal = [-Inf, NaN];
parfor a = 1:length(p)
val = someFcn(p(a));
% Next, use our "custom reduction" to
% update maxVal if the value piece is larger
% than previous values.
maxVal = iMax(maxVal, [val, p(a)]);
end
Starting parallel pool (parpool) using the 'Processes' profile ... Connected to the parallel pool (number of workers: 2). Analyzing and transferring files to the workers ...done.
disp(maxVal)
0.9894 8.0000
function v = iMax(v, in)
if in(1) > v(1)
v = in;
end
end
(Only after writing out this solution did I notice that the doc example for for custom reduction is precisely this case!)
  1 Comment
Andres Morales
Andres Morales on 10 Nov 2022
Thank you. This is exactly what I was looking for, since I have no interest in saving anything else besides the optimal solution.

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 9 Nov 2022
List concatenation is one of the permitted reduction strategies, so you can assume that it will handle memory allocation appropriately.
But you could also use an array, something like
N = 1000000;
pvals = zeros(2,N);
parfor a = 1 : N
thisp = p(a);
val = somefunction(thisp);
pvals(:,a) = [val;thisp];
end
[maxval, idx] = max(pvals(1,:));
pmax = pvals(2,idx);
Question: your current code would find all the places that have the same (identical) max. Is that deliberate? (There can be good reason to want to know them all, but it does mean there can be instabilities that are due to floating point round off. Though I guess the instabilities exist if you just want one out of all the locations that are maximal.)
  3 Comments
Andres Morales
Andres Morales on 10 Nov 2022
Yeah, that's very clear. Thank you for providing great answers.

Sign in to comment.

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by