Defining anonymous function using an "if" statement
이전 댓글 표시
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?
채택된 답변
추가 답변 (2개)
Roger Stafford
2015년 1월 5일
Try this:
f = @(x) (x.^2>=x).*x.^2+(x.^2<x).*x
댓글 수: 5
John
2015년 1월 6일
Star Strider
2015년 1월 6일
That approach can easily be applied to multivariate functions. See: How do i plot CDF (probability) in Matlab? for an illustration.
This is a classic technique and Star Strider is right. More generally, you would do
h = @(x) L(x).*f(x) + (~L(x)).*g(x)
where L(x) is a possibly multivariate indicator function of x (i.e. =1 when f is active and =0 if g is active).
The only thing I'd point out is that it requires L(x) to be computed twice. It also requires that both f and g be computed even though you really only want to compute the one that is active. With a dedicated mfile you can often avoid that.
So, for large calculations, it has its drawbacks in CPU efficiency, but advantages in syntax efficiency.
John
2015년 1월 6일
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
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
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.
카테고리
도움말 센터 및 File Exchange에서 Interactive Control and Callbacks에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!