How to pass multiple arguments to a function handle?
17 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
I try to define a function named myfun(f, varargin) to evaluate a general multivariate function , the first parameter f is a function handle (avoid using 'sym' objects and subs() for their low performance) while the parameters varargin are supposed to be values of .
Here comes the problem: I want this myfun() to evaluate the function f for arbitary integer n, i.e. it should work on functions with different independent variable number n, but I fail to pack all the input values of and pass them together to a function handle .
It seems that there're no elegent ways to pack and pass multiple arguments to a function handle, unlike Python I may just write code like
myfun(f, *x_tuple)
where x_tuple is a n-length tuple of values coresponding to each . In python the function myfun() will automatically read all values in x_tuple and pass them to corresponding parameters of myfun(). Can we do similar things in MATLAB?
I also figure out a way to solve this problem using eval() : (I rewrite the function as myfun(f, x_values))
(i) Get the length of x_values (it's supposed to be a vector), that is, the number of independent variables n;
(ii) Loop over indices and concatenate the strings like
mystr = 'f(';
for i = 1:n
if i < n
mystr = [mystr, num2str(x_values(i)), ','];
else
mystr = [mystr, num2str(x_values(i))];
end
end
mystr = [mystr, ')'];
(iii) Evaluate mystr via eval() I get the value I want.
But using eval() is usually not a good idea because of its inefficiency and insecurity. Are there any better methods for the above problem?
0 comentarios
Respuestas (2)
Star Strider
el 21 de Oct. de 2024
An example of what you want to do could help.
Perhaps something like this —
for k = 1:10
k
arg = randn(1,k)
out = myfun(arg)
end
function out = myfun(varargin)
xvecc(1:numel(varargin)) = varargin;
xvec = cell2mat(xvecc);
out = [min(xvec) max(xvec) mean(xvec) median(xvec) std(xvec)];
end
I am not certain what problem you may be having.
This is the approach I usually use witth varargin arguments.
.
3 comentarios
Star Strider
el 21 de Oct. de 2024
My pleasure!
‘But what if I want to evaluate fn = x_1 .^ x_2 .^ x_3 .^ ... .^ x_n with x_i = i/10 ?’
That can be vectorised using MATLAB’s vectorisation syntax and calls to log and exp.
Example —.
x_i = [0.1 rand(1,99)];
disp(x_i)
tic
x_e(1) = x_i(1);
for k = 1:numel(x_i)-1
x_e(k+1) = x_e(k)^x_i(k+1);
end
toc
disp(x_e)
tic
x_ee = [x_e(1) exp(log(x_i(1))*cumprod(x_i(2:end)))];
toc
disp(x_ee)
The vectorisation approach even appears to be a bit faster
I am not certain that I understand what you want to do. I doubt that there is a general approach that could apply to any arbitrary function of a vector argument that has a large (and possibly memory-saturating) number of elements.
With respect to using varargin howeveer, my approach should work.
.
Steven Lord
el 21 de Oct. de 2024
But what if I want to evaluate fn = x_1 .^ x_2 .^ x_3 .^ ... .^ x_n with x_i = i/10 ?
When n is large (namely, 10^4 or even larger),
There is a limit on the maximum number of input arguments you can specify for a function in MATLAB. I don't remember what the value is offhand, but if you're trying to pass ten thousand separate inputs to your function you may reach that limit.
Even if you don't reach that limit, if your number of input arguments gets into double digits your function is probably too unwieldy to use especially if some have a specific meaning depending on where in the argument list they appear. [fmincon from Optimization Toolbox is one example of a function that is harder to use than it should be because it has ten positional input arguments and it's way too easy to miss one. We've seen plenty of complaints on Answers about error messages caused by missing one.]
Don't pass the inputs in as separate values. Pass in one input argument that is an array. For the specific example you specified:
y = powertower((1:5)/10)
function y = powertower(x)
if ~isempty(x)
y = x(1); % Assuming you want (x(1)^x(2))^x(3) not x(1)^(x(2)^x(3))
for k = 2:numel(x)
y = y.^x(k);
end
else
y = NaN; % Placeholder
end
end
Saurabh
el 21 de Oct. de 2024
Editada: Saurabh
el 21 de Oct. de 2024
I understand that you want to define a function to evaluate a general multivariable function.
So let assume that the function 'f' calculates the sum of the squares of input arguments.
function result = f(varargin)
% f calculates the sum of the squares of input arguments.
% varargin allows a variable number of inputs.
% Initialize the result
result = 0;
% Loop through each input argument
for k = 1:length(varargin)
% Ensure the input is numeric
if isnumeric(varargin{k})
% Add the square of the current argument to the result
result = result + varargin{k}^2;
else
error('All inputs must be numeric.');
end
end
end
'myfun' Function: This function takes the function handle and the variable inputs, unpacks them, and evaluates the function.
function result = myfun(f, varargin)
% f is a function handle
% varargin is a cell array containing the input values
% Call the function handle with the unpacked arguments
result = f(varargin{:});
end
Function Handle: When calling 'myfun', we use @f to pass the function handle of f.
% Example usage with different numbers of arguments
result1 = myfun(@f, 1, 2, 3); % Evaluates f(1, 2, 3)
disp(['Result 1: ', num2str(result1)]);
result2 = myfun(@f, 4, 5); % Evaluates f(4, 5)
disp(['Result 2: ', num2str(result2)]);
result3 = myfun(@f, 6); % Evaluates f(6)
disp(['Result 3: ', num2str(result3)]);
Refer to the following link to know more about the 'varargin' function:
I hope this was helpful.
Ver también
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!