フィルターのクリア

How to use fzero with arrayfun or cell fun?

22 ビュー (過去 30 日間)
Ruben
Ruben 2024 年 10 月 6 日
回答済み: Umar 2024 年 10 月 8 日 9:48
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 件のコメント
Ruben
Ruben 2024 年 10 月 8 日 7:11
This worked perfectly, thanks!!
Umar
Umar 2024 年 10 月 8 日 8:34
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.

サインインしてコメントする。

採用された回答

Umar
Umar 2024 年 10 月 8 日 9:48

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.

その他の回答 (1 件)

Walter Roberson
Walter Roberson 2024 年 10 月 6 日
移動済み: Walter Roberson 2024 年 10 月 6 日
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.

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

製品


リリース

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by