Jessica
Jessica

Reputation: 79

How to use conditions within an anonymous function

A function can be defined as @(x) x^.2 (for e.g)

But in case, we have a function that takes different representation on different intervals for e.g : if abs(x)<3 fun = x^.2 else 0

How can we use the same way (i mean use @(x) ) to define such a function.

Upvotes: 7

Views: 13311

Answers (4)

Arthur Ward
Arthur Ward

Reputation: 627

To expand on the link hiding in @RodyOldenhuis's answer, have a look at Functional Programming Constructs. That package provides a pretty comprehensive set of functional constructs. The author also did a series of guest posts on the Art of MATLAB blog showing a lot of the details behind this library. If you don't want pull the whole package in to your project, the blog posts also include anonymous one-liners of some of the functions in the package.

Upvotes: 0

Juho &#214;stman
Juho &#214;stman

Reputation: 1594

This is what I came up with. I have cases.m function with the following definition:

function [ val ] = cases( table )
  [rows,~] = size(table);
  for i = drange(1:rows)
    condition = table{i,1};
    if (ischar(condition) && strcmpi(condition,'else')) || feval(condition)
      val = feval(table{rows,2});
      return
    end
  end
  val={};
end

The function cases takes a cell array with two columns. Each element is a function with zero arguments. For each row it takes the first element and if it is the string 'else' or a function that returns a true value, the second element is called and its value returned. If no row qualifies, an empty cell is returned. The elements are nullary functions instead of values, so that unneeded cases are not evaluated.

Then I can write case expressions like this:

w=arrayfun(@(j) cases({ ...
   @() (j==0 || j==n) @() (-1)^j/2; ...
   'else' @() (-1)^j }), 0:n);

This produces an array for values from 0 to n with the first and the last value halved.

Upvotes: 0

Paul P M
Paul P M

Reputation: 159

As @Gunther mentioned in the comments above, a generic function to handle simple conditions to mimic the tertiary operator ?: can be created to circumnavigate the limitation that Matlab doesn't allow conditionals inside anon functions (if you don't count that messy-ugly-inefficient-but-fun inline version :).

The solution was presented via this link (and perhaps a few other places but SO came back on top of my google search so thought it'd be good to add here). http://www.mathworks.co.jp/matlabcentral/newsreader/view_thread/158054

define a function say iff or ifelse and add it to the Matlab path.

function result = ifelse(condition,trueResult,falseResult)
    error(nargchk(3,3,nargin));  % check correct number of input args
    if condition
        result = trueResult;
    else
        result = falseResult;
    end

then use like this

predict = arrayfun(@(x) ifelse(x>=0.5,1,0), inputData);

In the OP's case, something like this could be used

arrayfun(@(x) ifelse(abs(x)<3,x^.2,0), data)

Upvotes: 0

Rody Oldenhuis
Rody Oldenhuis

Reputation: 38042

There's a few ways to do this.

Multiply by false:

g = @(x) (abs(x)<3) .* x.^2

or define a proper function (the BEST way really):

function y = g(x)

    y = zeros(size(x), class(x));

    inds = abs(x)<3;
    y(inds) = x(inds).^2;

end 

or do the messy-ugly-inefficient-but-fun thing and use an inline-if:

iif = @(varargin) varargin{2 * find([varargin{1:2:end}], 1, 'first')}();
g = @(x) iff( ...
    abs(x)<3,  x.^2, ...
        true,  0);

Upvotes: 19

Related Questions