Arrayfun with a function that takes multiple inputs
83 次查看(过去 30 天)
显示 更早的评论
say I have an array that I want to run a function over each of its elements, I could easily do this with arrayfun(@f,v) where f is my function name and v is my vector.
But now say f is defined to take two input arguments, that is f(e,k) where e is an element of the same type as in the vector and k is something unrelated to the vector (for example an integer). how can I run arrayfun?
I would want to do this: arrayfun(@f,v,k), however, this runs arrayfun over two vectors v and k.
%%
Example:
Say mv = movingAvg(v,w) takes a vector v and does a moving average filter over it with width w, and returns the filtered vector to mv. Now say A = {v1,v2,...,vn} is an array of vectors. how could I use arrayfun to give me an array mA = {mv1,mv2,...,mvn} such that mvi = movingAvg(vi,10)?
I would assume that maybe mA = arrayfun(@movingAvg,A,10) or mA = arrayfun(@movingAvg,[A 10]) or something of that sort, but this is not true.
0 个评论
采纳的回答
Steven Lord
2015-7-1
This isn't the most efficient way to write "y = x+17" but it's good for demonstration.
k = 17;
x = 1:10;
y = arrayfun(@(z) plus(z, k), x)
3 个评论
John D'Errico
2015-7-1
Well, I'd argue not really. A simple interpretation is that
@(z) plus(z,k)
is an anonymous function, that is passed the argument k from your workspace, as a constant. This function is a function though of only ONE argument: z. Arrayfun thus sees a function of one argument only, so it is happy. That ancillary argument, k, is a constant as far as arrayfun is concerned. arrayfun does not care where a constant comes from, only that it is predefined.
Steven Lord
2015-7-1
@(z) plus(z, k) is a function [an anonymous function, if you want to be technical] that accepts one input, z, and calls the PLUS function with two inputs, z and k. Since k was defined when this anonymous function was created, and k does not appear in the list of input arguments, the anonymous function "remembers" the existing value.
ARRAYFUN requires the function you pass into it as the first input to accept one input per array over which it should iterate. I passed in one array, x, and so ARRAYFUN will call the function with one input. So the anonymous function satisfies ARRAYFUN's requirements. The PLUS function required you to specify two input arguments, and the anonymous function satisfied that requirement as well. So ARRAYFUN is happy, PLUS is happy, MATLAB is happy, and you're happy because your code runs :)
更多回答(3 个)
Céldor
2016-9-15
编辑:Céldor
2016-9-16
I might be a little too late with an answer. However, I had recently a similar problem. I needed to test if vectors contain NaNs or zeros. I thought I would make an anonymous function with arrayfun and used an extra parameters as another function to apply, e.g. isnan(x) or my custom function iszero(x,tol) etc. The problem was a custom function because it needed tolerance to apply. I made something simple below:
iszero = @(x,tol) x < abs(tol) & x > -abs(tol);
I sorted it out everything using varargin:
TEST = @(sw, fun, varargin) arrayfun(@(x) fun(x,varargin{:}), sw, 'UniformOutput',true);
The great thing about varargin is that it is a cell. Even if it's used inside another function as a parameter, when it's empty MATLAB function simply ignores it. I can now use isnan(x) as well as iszero(x,tol) as follows:
a = [0.1 0.01 0.001 0.0001 0.000001];
TEST(a,@isnan)
ans =
0 0 0 0 0
TEST(a,iszero,0.1)
ans =
0 1 1 1 1
TEST(a,iszero,0.001)
ans =
0 0 0 1 1
Hope it helps :)
0 个评论
Adam
2015-7-1
编辑:Adam
2015-7-1
f = @(x,y) x.^2 + y.^2
g = @(x) f(x,3);
a = [1 2 3 4 5];
res = arrayfun( g, a );
is a general example that should give you the syntax you need. You bind a constant to your function handle rather than passing it as an argument to arrayfun so effectively your function, f, of 2 variables is replaced by a function, g, of one variable.
Edit: Note the @(x) part was missing from the definition of g when this was first posted.
2 个评论
Steven Lord
2015-7-1
You missed a piece of the definition of g. As written, if x is defined before g is defined then g will no longer be an anonymous function handle by the time you get to the ARRAYFUN call and so ARRAYFUN will error. If x is not defined when you define g, you will receive an undefined function or variable error. The definition of g should be:
g = @(x) f(x, 3);
If you're more familiar with C++, think of this technique as similar in some ways to std::bind1st or std::bind2nd.
saadani seifeddine
2017-3-13
[B1,...,Bm] = arrayfun(@(x) func(x,var1,...,vark),A1,...,An)
...
function[Y]=func(X,Var1,...,Vark)
...
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Structures 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!