views:

4523

answers:

4

I'm a little surprised that MATLAB doesn't have a Map function, so I hacked one together myself since it's something I can't live without. Is there a better version out there? Is there a somewhat-standard functional programming library for MATLAB out there that I'm missing?

function results = map(f,list)
% why doesn't MATLAB have a Map function?
results = zeros(1,length(list));
for k = 1:length(list)
    results(1,k) = f(list(k));
end

end

usage would be e.g.

map( @(x)x^2,1:10)
+1  A: 

If matlab does not have a built in map function, it could be because of efficiency considerations. In your implementation you are using a loop to iterate over the elements of the list, which is generally frowned upon in the matlab world. Most built-in matlab functions are "vectorized", i. e. it is more efficient to call a function on an entire array, than to iterate over it yourself and call the function for each element.

In other words, this


a = 1:10;
a.^2

is much faster than this


a = 1:10;
map(@(x)x^2, a)

assuming your definition of map.

Dima
+15  A: 

The short answer: the built-in function ARRAYFUN does exactly what your map function does for numeric arrays:

>> y = arrayfun(@(x) x^2,1:10)
y =

     1     4     9    16    25    36    49    64    81   100

There are two other built-in functions that behave similarly: CELLFUN (which operates on elements of cell arrays) and STRUCTFUN (which operates on each field of a structure).

However, these functions are often not necessary if you take advantage of vectorization, specifically using element-wise arithmetic operators. For the example you gave, a vectorized solution would be:

>> x = 1:10;
>> y = x.^2
y =

     1     4     9    16    25    36    49    64    81   100

Some operations will automatically operate across elements (like adding a scalar value to a vector) while others operators have a special syntax for element-wise operation (denoted by a "." before the operator). Many functions in MATLAB are designed to operate on vector and matrix arguments using element-wise operations, and thus don't require map functions.

To summarize, here are some different ways to square each element in an array:

x = 1:10;
f = @(x) x.^2;
% Option #1:
y = x.^2;  % Use the element-wise power operator
% Option #2:
y = f(x);  % Pass a vector to f
% Option #3:
y = arrayfun(f,x);  % Pass each element to f separately

Of course, for such a simple operation, option #1 is the most sensible choice.

gnovice
+3  A: 

You don't need map since a scalar-function that is applied to a list of values is applied to each of the values and hence works similar to map. Just try

l = 1:10
f = @(x) x + 1

f(l)

In your particular case, you could even write

l.^2
Dario
-1: That's actually not true. Matlab does not have a type system strong enough to specify scalar functions. f is called with the vector and a single vector addition is performed in your example. To verify this, profile your code sample ("profile on" before running the code, then "profile off report" after it). You'll see there's a single call to f.
Mr Fooz
+3  A: 

In addition to vector and element-wise operations, there's also cellfun for mapping functions over cell arrays. For example:

cellfun(@upper, {'a', 'b', 'c'}, 'UniformOutput',false)
ans = 
    'A'    'B'    'C'

If 'UniformOutput' is true (or not provided), it will attempt to concatenate the results according to the dimensions of the cell array, so

cellfun(@upper, {'a', 'b', 'c'})
ans =
ABC
kwatford