Reputation: 184
I am trying to produce the argument string for an anonymous function based on the number of input arguments without using for loops. For example, if N=3, then I want a string that reads
@(ax(1),ax(2),ax(3),ay(1),ay(2),ay(3))
I tried using repmat('ax',1,N) but I cannot figure out how to interleave the (i) index.
Any ideas?
Aside: Great answers so far, the above problem has been solved. To provide some intuition for those who are wondering why I want to do this: I need to construct a very large matrix anonymous function (a Jacobian) on the order of 3000x3000. I initially used the Matlab operations jacobian and matlabFunction to construct the anonymous function; however, this was quite slow. Instead, since the closed form of the derivative was quite simple, I decided to form the anonymous function directly. This was done by forming the symbolic Jacobian matrix, J, then appending it to the above @() string by using char(J{:})' and using eval to form the final anonymous function. This may not be the most elegant solution but I find it runs much faster than the jacobian/matlabFunction combination, especially for large N (additionally the structure of the new approach allows for the evaluation to be done in parallel).
EDIT: Just for completeness, the correct form of the argument string for the anonymous function should read
@(ax1,ax2,ax3,ay1,ay2,ay3)
to avoid a syntax error associated with indexing.
Upvotes: 2
Views: 264
Reputation: 112659
Try this:
N = 3;
sx = strcat('ax(', arrayfun(@num2str, 1:N, 'uniformoutput', 0), '),');
sy = strcat('ay(', arrayfun(@num2str, 1:N, 'uniformoutput', 0), '),');
str = [sx{:} sy{:}];
str = ['@(' str(1:end-1) ')']
Upvotes: 1
Reputation: 74930
I suggest the following:
N = 3;
argumentString = [repmat('ax(%i),',1,N),repmat('ay(%i),',1,N)];
functionString = sprintf(['@(',argumentString(1:end-1),')'], 1:N, 1:N)
First, you create input masks for sprintf (e.g. 'ax(%i)'
), which you then fill in with the appropriate numbers to create the function string.
Note: the syntax @(ax(1),...)
will not actually work. More likely, you want to use either @()someFunction(ax(1),...)
, or you are trying to pass multiple input arguments to an existing function, in which case storing the inputs in a cell array and calling the function as fun(axCell{:})
would work.
Upvotes: 2
Reputation: 5171
A solution would be to use arrayfun
:
sx = strjoin(arrayfun(@(x) ['ax(' num2str(x) ')'], 1:3, 'UniformOutput', false), ',');
sy = strjoin(arrayfun(@(x) ['ay(' num2str(x) ')'], 1:3, 'UniformOutput', false), ',');
s = ['@(' sx ',' sy ')'];
contains
'@(ax(1),ax(2),ax(3),ay(1),ay(2),ay(3))'
Best,
Upvotes: 1