Defining anonymous function using an "if" statement

183 ビュー (過去 30 日間)
John
John 2015 年 1 月 5 日
I'm trying to define an anonymous function using an "if" statement. Here is a minimum "not working" example (my code is more convoluted, but this illustrates the issue):
clc;
clear all;
f=@(x)x^2;
g=@(x) x;
if f(x)>=g(x)
h=@(x) f(x)
else h=@(x) g(x)
end
The point is that I don't want to create an m file and have to recompute both f and g in it (my actual problem would require recomputing many more). So the question is:
1-) Is it possible to create an anonymous function using "if" statements (fixing the code above)?
2-) Is it possible to define function h on a separate m file, without having to recompute f and g inside of it?

採用された回答

Matt J
Matt J 2015 年 1 月 5 日
You can also do things like the following
f=@(x)x^2;
g=@(x) x;
h=@(x) fg_mfile(x,f,g);
function out=fg_mfile(x,f,g) %put this in mfile
fval=f(x);
gval=g(x);
if fval>=gval
out=fval;
else
out= gval;
end
end
  2 件のコメント
yang
yang 2018 年 8 月 24 日
you can do like this h=@(x)max(f(x),g(x))
Matt J
Matt J 2018 年 8 月 24 日
編集済み: Matt J 2018 年 8 月 24 日
In this particular example, that is true. More complicated h() might require an mfile to express, however.

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

その他の回答 (2 件)

Roger Stafford
Roger Stafford 2015 年 1 月 5 日
Try this:
f = @(x) (x.^2>=x).*x.^2+(x.^2<x).*x
  5 件のコメント
John
John 2015 年 1 月 6 日
I see. I checked the references you provided and now I understand.
Alec Jacobson
Alec Jacobson 2016 年 12 月 16 日
This style/hack has two (more) "gotchas".
1) Suppose L(x) is true, but g(x) produces nan/inf. Then h(x) = nan rather than f(x).
2) Suppose L(x) is true and g(x) is very expressive to compute or has side-effects (admittedly rare for matlab code), g(x) will still be called. This is very different behavior from:
if L(x)
return f(x)
else
return g(x)
I really wish matlab had full-citizen anonymous functions...

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


Cristobal Montecino
Cristobal Montecino 2019 年 6 月 26 日
編集済み: Cristobal Montecino 2019 年 6 月 26 日
I use:
call = @(fun) fun();
cellget = @(cell, index) cell{index};
iff = @(test, truefn, falsefn) call(cellget({falsefn, truefn}, test + 1));
And:
arrayget = @(arr, index) arr(index);
ifv = @(test, trueval, falseval) arrayget([falseval, trueval], test + 1);
%or
cellget = @(cell, index) cell{index};
ifv = @(test, trueval, falseval) cellget({falseval, trueval}, test + 1);
Examples:
iff(true, @() 2, @() this_throw_an_error)
% out: 2
iff(false, @() 2, @() this_throw_an_error)
% out: Undefined function or variable 'this_throw_an_error'.
ifv(true, 2, 3)
% out: 2
ifv(true, 2, this_throw_an_error)
% out: Undefined function or variable 'this_throw_an_error'.
  1 件のコメント
Oscar Raya i Casanova
Oscar Raya i Casanova 2020 年 1 月 29 日
Nice tip. As improvement for the first option:
call = @(fun,par) fun(par{:});
cellget = @(cell, index) cell{index};
iff = @(test, truefn, falsefn, truePar, falsePar) call( ...
cellget({falsefn, truefn}, test + 1), ... % functions
cellget({falsePar, truePar}, test + 1) ... % params
);
Examples:
f1 = @(a,b) a + b;
f2 = @(a,b,c) a*b + c;
f3 = @() 7;
iff(true,f1,f2,{1,2},{1,2,3});
% out: 3
iff(false,f1,f2,{1,2},{1,2,3});
% out: 5
iff(false,f1,f3,{1,2},{});
% out: 7
This way you can use functions with different number of parameters.

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

カテゴリ

Help Center および File ExchangeInstall Products についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by