How to extract an element from a ''vector'' of function handle

19 次查看(过去 30 天)
Hi guys,
I'm having some troubles managing handle functions.
What I would like to do is to extract an element of an "handle" array like this below.
f = @(x1,x2,x3)[x1*2-x3;x3*x1-x2;x1-x2^2]
And I would like to compute "something" like that.
f(1) = x1*2-x3;
f(2) = x3*x1-x2;
f(3) = x1-x2^2;
So, like a vector.
How can I do that ??

采纳的回答

Steven Lord
Steven Lord 2022-4-1
If you've already created your f function you could do this using one helper function. I vectorized your f function.
f = @(x1,x2,x3)[x1*2-x3;x3.*x1-x2;x1-x2.^2];
getRow = @(data, rowNum) data(rowNum, :); % Helper function
Now if you want a function handle that retrieves the third row in the output of f:
g3 = @(x1, x2, x3) getRow(f(x1, x2, x3), 3);
Check the full output versus the row 3 output:
y123 = f(1:5, 6:10, 11:15)
y123 = 3×5
-9 -8 -7 -6 -5 5 17 31 47 65 -35 -47 -61 -77 -95
y3 = g3(1:5, 6:10, 11:15)
y3 = 1×5
-35 -47 -61 -77 -95
You could theoretically eliminate the getRow function by explicitly calling subsref yourself inside g3, but using a separate getRow function makes the code much clearer IMO.
  5 个评论
Luca Amicucci
Luca Amicucci 2022-4-2
Ok but even so,
h = @(x1, x2, x3) [g1(x1, x2, x3); g2(x1, x2, x3); g3(x1, x2, x3)];
It's not a vector.
I would like to have a vector 3x1 [g1;g2;g3], but maybe it is not possible to convert an handle function to an array of size 3x1.
Or do you have an idea ?
Steven Lord
Steven Lord 2022-4-2
Years ago MATLAB did allow you to have a vector of function handles, but that functionality was removed when we introduced anonymous functions (to avoid ambiguity: would f(3) be a call to the function with the input 3 or a request for the third element of the array?) If you want an array of function handles it must be a cell array.
Q = {@sin, @cos, @tan};
Now Q{2} is unambiguous and so is Q{2}(pi).
f = Q{2}(pi)
f = -1

请先登录,再进行评论。

更多回答(1 个)

Voss
Voss 2022-4-1
It seems like you want a cell array of function handles:
f = {@(x1,x2,x3)x1*2-x3; @(x1,x2,x3)x3*x1-x2; @(x1,x2,x3)x1-x2^2}
f = 3×1 cell array
{ @(x1,x2,x3)x1*2-x3} {@(x1,x2,x3)x3*x1-x2} { @(x1,x2,x3)x1-x2^2}
f{1}
ans = function_handle with value:
@(x1,x2,x3)x1*2-x3
f{2}
ans = function_handle with value:
@(x1,x2,x3)x3*x1-x2
f{3}
ans = function_handle with value:
@(x1,x2,x3)x1-x2^2
Then you can evaluate the functions one at a time:
f{1}(10,13,15)
ans = 5
f{2}(10,13,15)
ans = 137
f{3}(10,13,15)
ans = -159
Or all at once:
cellfun(@(x)x(10,13,15),f)
ans = 3×1
5 137 -159
  3 个评论
Luca Amicucci
Luca Amicucci 2022-4-1
Thank you guys for the answers.
But the function handle comes from some calculus and I cannot arrange as a cell array.
I made some calculus in syms "mode" and then, with the matlabFunction, I converted the result in a handle function.
The problem is that this result in handle function contains 3 functions
results = @(x1,x2,x3) [f1;f2;f3]
and so i wanted to extract f1 f2 f3 apart.
Voss
Voss 2022-4-1
I see. Then maybe something like this would work, depending on what f1, f2 and f3 actually are:
% a function handle you have
results = @(x1,x2,x3) [f1;f2;f3]
results = function_handle with value:
@(x1,x2,x3)[f1;f2;f3]
% make it a char vector:
str = func2str(results)
str = '@(x1,x2,x3)[f1;f2;f3]'
% parse the char vector into argument list and functions f1, f2, f3:
f = regexp(str,'(@\(.+\))\[(.+);(.+);(.+)\]','tokens');
f = [f{:}]
f = 1×4 cell array
{'@(x1,x2,x3)'} {'f1'} {'f2'} {'f3'}
% make a cell array of function handles out of that argument list and each
% function (f1, f2, f3):
f = cellfun(@(x)str2func([f{1} x]),f(2:end),'UniformOutput',false)
f = 1×3 cell array
{@(x1,x2,x3)f1} {@(x1,x2,x3)f2} {@(x1,x2,x3)f3}
Now you have a cell array of function handles to those individual functions.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Logical 的更多信息

产品


版本

R2017b

Community Treasure Hunt

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

Start Hunting!

Translated by