Arrayfun with a function that takes multiple inputs
84 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Noah Chrein
il 1 Lug 2015
Risposto: saadani seifeddine
il 13 Mar 2017
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 Commenti
Risposta accettata
Steven Lord
il 1 Lug 2015
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 Commenti
John D'Errico
il 1 Lug 2015
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
il 1 Lug 2015
@(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 :)
Più risposte (3)
Céldor
il 15 Set 2016
Modificato: Céldor
il 16 Set 2016
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 Commenti
Adam
il 1 Lug 2015
Modificato: Adam
il 1 Lug 2015
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 Commenti
Steven Lord
il 1 Lug 2015
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
il 13 Mar 2017
[B1,...,Bm] = arrayfun(@(x) func(x,var1,...,vark),A1,...,An)
...
function[Y]=func(X,Var1,...,Vark)
...
0 Commenti
Vedere anche
Categorie
Scopri di più su Structures in Help Center e File Exchange
Prodotti
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!