Reputation: 79
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
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
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
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
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