Asked by John
on 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?

Answer by Matt J
on 5 Jan 2015

Accepted Answer

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

Answer by Roger Stafford
on 5 Jan 2015

Try this:

f = @(x) (x.^2>=x).*x.^2+(x.^2<x).*x

Matt J
on 6 Jan 2015

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
on 6 Jan 2015

I see. I checked the references you provided and now I understand.

Alec Jacobson
on 16 Dec 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...

Sign in to comment.

Answer by Cristobal Montecino
on 26 Jun 2019 at 18:32

Edited by Cristobal Montecino
on 26 Jun 2019 at 18:39

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'.

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.