Defining anonymous function using an "if" statement

214 vues (au cours des 30 derniers jours)
John
John le 5 Jan 2015
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?

Réponse acceptée

Matt J
Matt J le 5 Jan 2015
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 commentaires
yang
yang le 24 Août 2018
you can do like this h=@(x)max(f(x),g(x))
Matt J
Matt J le 24 Août 2018
Modifié(e) : Matt J le 24 Août 2018
In this particular example, that is true. More complicated h() might require an mfile to express, however.

Connectez-vous pour commenter.

Plus de réponses (2)

Roger Stafford
Roger Stafford le 5 Jan 2015
Try this:
f = @(x) (x.^2>=x).*x.^2+(x.^2<x).*x
  5 commentaires
John
John le 6 Jan 2015
I see. I checked the references you provided and now I understand.
Alec Jacobson
Alec Jacobson le 16 Déc 2016
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...

Connectez-vous pour commenter.


Cristobal Montecino
Cristobal Montecino le 26 Juin 2019
Modifié(e) : Cristobal Montecino le 26 Juin 2019
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 commentaire
Oscar Raya i Casanova
Oscar Raya i Casanova le 29 Jan 2020
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.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Testing Frameworks dans Help Center et File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by