How to use fzero with arrayfun or cell fun?

2 Ansichten (letzte 30 Tage)
Ruben
Ruben am 6 Okt. 2024
Beantwortet: Umar am 8 Okt. 2024
Hi there,
I have the piece of code that you see at the bottom. In short,
  1. I have a function whose form I don't know but I know it is smooth and I can interpolated it.
  2. I create a function function that accepts a cell as an input and has 2 variables.
  3. I create a new function to three variables, the previous 2 + 1, so that I can minimise it useing fzero
  4. I would like to use arrayfun or cellfun (or any other trick) to evaluate fzero over several pairs of inputs all at once to avoid looping.
I would appreciate if someone could put me on the right track.
miny = setting.Y.miny;
maxy = y(end);
xrep = reshape(repmat(x', [y_sz 1]),[x_sz*y_sz 1]);
yrep = repmat(y, [x_sz 1]);
xy = mat2cell(num2cell([xrep yrep]), ones([x_sz*y_sz 1]), 2);
Fmin_bar = MW_mw.Fmin_bar;
Smin = griddedInterpolant({x,y},MW_mw.S_xy_min,"linear","spline");
dSdy =@(c) (Smin({c{1},c{2}+1e-9})-Smin(c))./1e-9.*MS_tilde_f(c{:});
t_thres =@(t,c) dSdy(c) - c{1}./(r+delta+s.*lamb_min.*Fmin_bar(t));d
tr = fzero(@(t) t_thres(t,c),[miny maxy*10]);
tr = zeros(4000,1);
tic
for i = 1:4000
z = xy{i,:};
try
tr(i) = fzero(@(t) t_thres(t,z),[miny maxy*10]);
catch
tr(i) = NaN;
end
end
Best,
Ruben
  3 Kommentare
Ruben
Ruben am 8 Okt. 2024
This worked perfectly, thanks!!
Umar
Umar am 8 Okt. 2024
Hi @Ruben,
Glad to know that your problem is resolved. Please don’t forget to click “Accept Answer” and vote for @Walter Roberson for contributing his efforts to help out.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Umar
Umar am 8 Okt. 2024

Hi @Ruben,

To efficiently apply fzero across multiple input pairs in MATLAB, you can leverage cellfun. This function allows you to apply a specified function to each cell in a cell array, which is ideal for your use case. Here’s how you can modify your code:

miny = setting.Y.miny;
maxy = y(end);
xrep = reshape(repmat(x', [y_sz 1]), [x_sz*y_sz 1]);
yrep = repmat(y, [x_sz 1]);
xy = mat2cell(num2cell([xrep yrep]), ones([x_sz*y_sz 1]), 2);
Fmin_bar = MW_mw.Fmin_bar;
Smin = griddedInterpolant({x,y}, MW_mw.S_xy_min, "linear", "spline");
dSdy = @(c) (Smin({c{1}, c{2}+1e-9}) - Smin(c)) ./ 1e-9 .*   MS_tilde_f(c{:});
t_thres = @(t, c) dSdy(c) - c{1} ./ (r + delta + s .* lamb_min .*     Fmin_bar(t));
% Using cellfun to apply fzero across all pairs
tr = cellfun(@(z) tryCatchFzero(@(t) t_thres(t, z), [miny maxy*10]),   xy);
% Function to handle try-catch for fzero
function result = tryCatchFzero(func, interval)
  try
      result = fzero(func, interval);
  catch
      result = NaN; % Return NaN if fzero fails
  end
end

In this code, cellfun applies the tryCatchFzero function to each element of xy, which contains your input pairs. This approach eliminates the need for explicit loops, enhancing code readability and performance.

Hope this helps. Please let me know if you have any further questions.

Weitere Antworten (1)

Walter Roberson
Walter Roberson am 6 Okt. 2024
Verschoben: Walter Roberson am 6 Okt. 2024
tr = fzero(@(t) t_thres(t,c),[miny maxy*10]);
The @(t) t_thres(t,c) part creates an anonymous function that copies its (first) input, and "captures" the current value of c and passes in that current value of c.
However, c is not defined at that point. For that to work, c has to have been assigned a specific value.
t_thres =@(t,c) dSdy(c) - c{1}./(r+delta+s.*lamb_min.*Fmin_bar(t));d
Caution: this code assigns an anonymous function to t_thres. And then it displays the value of d. Which is a problem, as d is not defined.
tr = zeros(4000,1);
You are overwriting the fzero() result that you obtained a moment earlier.
z = xy{i,:};
That looks like it is going to extract a numeric array.
tr(i) = fzero(@(t) t_thres(t,z),[miny maxy*10]);
The second parameter of t_thresh must be a cell array, not a numeric array.

Kategorien

Mehr zu Loops and Conditional Statements finden Sie in Help Center und File Exchange

Produkte


Version

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by