Calling a function option using cellfun
67 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Henry Williams
el 20 de Dic. de 2017
Respondida: Nick Jankowski
el 10 de Nov. de 2021
Hey guys,
I'm trying to use the function datestr on a cellmatrix using the option 'local'.
My code without the 'local' option looks something like this:
C = cellfun(@datestr, C, 'UniformOutput', false);
Where do I place the option in this piece of code?
I'm using Matlab2012a
Thanks
0 comentarios
Respuesta aceptada
Guillaume
el 20 de Dic. de 2017
You need to create a new function that only takes one input argument (the cell array element) and then call datestr with that argument and the 'local' option. This can be done all in one go with an anonymous function:
C = cellfun(@(x) datestr(x, 'local'), C, 'UniformOutput', false);
5 comentarios
Guillaume
el 21 de Dic. de 2017
As Stephen's said, an anonymous function, by definition, has no name. x is the name given to the input argument of the anonymous function and can be anything.
Now to answer your question is it good practice...
Good practice for naming variables is to give them names that clearly describe what's in them. With that in name x and C are extremely poor variable names.
However, for anonymous functions, the variable scope is only the next few characters that follows its declaration. In my answer x only exists as far as the end of datestr(x, 'local'), so it's immediately clear that its sole purpose is to pass the input to datestr with a 'local' option, so I don't worry about the name.
C however lives on more than one line, so you should absolutely use a better name for that variable.
Más respuestas (1)
Nick Jankowski
el 10 de Nov. de 2021
realize it's been a few years, but just came across this and noticed Matlab didn't have a way of passing or implicitly expanding a parameter in cellfun (except for a very few specific functions as mentioned in the help). It looks clunky, but the following also works for parameters, passing constants, etc., as additional cell arrays without calling an anonymous function, which has a bit of a performance penalty (understanding the memory impact this could imply for very large cell arrays). I assume it can also be done for non-constant parameters, but not sure you'd see the same speedup:
abc = {magic(2), magic(3), magic(4)}
abc =
3×1 cell array
{2×2 double}
{3×3 double}
{4×4 double}
def = cellfun (@(x) sum(x,2), abc, "UniformOutput", false) % Guillaume's anonymous function method
def =
3×1 cell array
{2×1 double}
{3×1 double}
{4×1 double}
def{:}
ans =
4
6
ans =
15
15
15
ans =
34
34
34
34
def = cellfun (@sum, abc, num2cell(2*ones(size(abc))), "UniformOutput", false) % cell expansion method
def =
3×1 cell array
{2×1 double}
{3×1 double}
{4×1 double}
def{:}
ans =
4
6
ans =
15
15
15
ans =
34
34
34
34
a quick and very unscientific speed check seems to indicate it's a bit faster, although you'd want to check before scaling to large arrays, or more than one parameter
tic;
for idx = 1:100000
cellfun(@(x) sum(x,2), abc,"UniformOutput",false);
end
toc
Elapsed time is 4.017116 seconds.
tic,
for idx = 1:100000
cellfun(@sum, abc, num2cell(2*ones(size(abc))),"UniformOutput",false);
end
toc
Elapsed time is 1.217712 seconds
I would assume for nontrivial numeric parameters, you could use repmat instead of num2cell, but that seems to carry more overhead:
tic
for idx = 1:100000
cellfun(@sum, abc, repmat({2}, size(abc)),"UniformOutput",false);
end
toc
Elapsed time is 4.367002 seconds.
0 comentarios
Ver también
Categorías
Más información sobre Performance and Memory en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!