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

87 views (last 30 days)
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 ??

Accepted Answer

Steven Lord
Steven Lord on 1 Apr 2022
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 Comments
Luca Amicucci
Luca Amicucci on 2 Apr 2022
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 on 2 Apr 2022
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

Sign in to comment.

More Answers (1)

Voss
Voss on 1 Apr 2022
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 Comments
Luca Amicucci
Luca Amicucci on 1 Apr 2022
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 on 1 Apr 2022
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.

Sign in to comment.

Products


Release

R2017b

Community Treasure Hunt

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

Start Hunting!