Giving Vector Inputs in Function Handles

조회 수: 103 (최근 30일)
JPS
JPS 2021년 4월 27일
답변: Elena Thomas 2022년 10월 6일
I have a function f that takes in 5 inputs and gives an output.
I wish to evaluate this function at different set of points. I have this points stacked up in a matrix called X.
X = X Matrix
I decided to loop through X taking each row at a time as the input for the function f
% defining function handle
f = @(x1 , x2 , x3 , x4 , x5) x1 + x2 + x3 + x4 + x5;
% finding the no of rows
s = size(X);
rows = s(1);
% preallocation of output y
y = zeros(1 , rows);
% looping through X taking one row at a time
for i = 1 : rows
y(i) = f(X(i , :)); % however this line shows an error stating function needs more argument
end
As mentioned in the comment, MATLAB takes X(i , :) as a single argument.
Now, is there any way to overcome this hurdle?
Of course, I can think of doing,
% looping through X taking one row at a time
for i = 1 : rows
t1 = X(i , 1); t2 = X(i , 2); t3 = X(i , 3); t4 = X(i , 4); t5 = X(i , 5);
y(1) = f(t1 , t2 , t3 , t4 , t5);
end
But what if there are 50 or 100 variables? This looks time-consuming.
I would be grateful if someone could enlighten me with an elegant method for doing the same.
NOTE: The function f defined above is just for illustrating my problem. Of course, the sum function can be used for this case. But, I was looking for a general solution which can be applied for any multivariable function.
  댓글 수: 3
Stephen23
Stephen23 2021년 4월 29일
"But what if there are 50 or 100 variables?"
Then your code has a major design flaw.
"This looks time-consuming."
It would be time consuming to write out, difficult to write without mistakes, and very difficult to maintain.
"I would be grateful if someone could enlighten me with an elegant method for doing the same."
Using numbered variables names is a sign that you are doing something wrong.
The much better solution is to use a vector, just like MATLAB was designed for.
JPS
JPS 2021년 4월 29일
@Stephen Cobeldick Thanks a lot! I replaced the in the function handle definitions with . Now it works great!

댓글을 달려면 로그인하십시오.

채택된 답변

Jan
Jan 2021년 4월 28일
Adam danz hit the point alread.
If you have a function with 50 or 100 inputs, this is the design problem already. Your example requires number names of variables, and this is a secure marker of a design fault.
Replace
f = @(x1 , x2 , x3 , x4 , x5) x1 + x2 + x3 + x4 + x5;
by
f = @(x) x(1) + x(2) + x(3) + x(4) + x(5);
Of couse, if only adding is performed, sum(x) is more efficient. But in the general case the solution is to use arrays instead of a bunch of variables.
Compare your code example with Adam's solution to see the point:
y = sum(X,2);
@Adam Danz: I'm finding another answer of you, where I can drop my votes for your valuable explanation. :-)
  댓글 수: 2
Adam Danz
Adam Danz 2021년 4월 28일
편집: Adam Danz 2021년 4월 28일
Thanks Jan I was thinking about using varargin with arrayfun or using deal() with the anonymous function but it gets ugly quickly.
Steven Lord
Steven Lord 2021년 4월 29일
I agree with the sentiment that many input arguments makes things get ugly very quickly. There's a commonly used function in Optimization Toolbox, fmincon, that has as its longest documented syntax one with ten positional arguments. There have been numerous questions both on Answers and on the CSSM newsgroup before it where people simply forgot to add in one of the inputs and got a somewhat confusing error.
You should probably try to stick closer to the passage from the Book of Armaments detailing the use of the Holy Hand Grenade of Antioch. Five is probably okay rather than being "right out", but many more than that and you probably should switch to a different approach (an options structure, an object, name-value pairs, etc.)

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Elena Thomas
Elena Thomas 2022년 10월 6일
I had a similar thing recently. The thing to do is to set the @(___) to a vector variable such as @(a) and then when making the function, use a(index) where needed.
So for this problem:
f1 = @(a) a(1) + a(2) + a(3) + a(4) + a(5);
% or
f2 = @(a) sum(a)
f2 = function_handle with value:
@(a)sum(a)
example_f1 = f1([-9 3 10 25 -7])
example_f1 = 22
example_f2 = f2([2 6 4 -9 3 9 10 25 -7 -22])
example_f2 = 21
For a problem with a specifc number of values, function one would work well since you'd be able to specify the variables. However, as you said there could be a TON of value that would be a pain to total, so an encompassing function like function 2 would be best.

카테고리

Help CenterFile Exchange에서 Logical에 대해 자세히 알아보기

제품


릴리스

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by