How do I count the number of Functions in a Function Handle?

4 vues (au cours des 30 derniers jours)
Karamjit Singh Bedi
Karamjit Singh Bedi le 18 Août 2022
Commenté : Walter Roberson le 19 Août 2022
I have defined a Function Handle with multiple functions. I want to find a way to count the number of functions I have defined in the Function Handle, similar to finding the columns of a matrix using size(mat, 1).
As of now, calling the Function Handle in the terminal simply gives me its definition and its type (function_handle). Its dimensions are 1x1 in the Workspace.
fun_hand = @(x)[mod(x, 5), mod(x, 3), x^3, floor(20/x)];
% fun_hand is the Function Handle that has 4 functions
% it takes an input x and passes it into each function, returning a row vector of the outputs
no_of_fun = something(fun_hand);
% no_of_fun should contain the value 4 after execution
% I want to find this "something" and if it doesn't exist,
% then I want to find a way to parse through the Function Handle
  2 commentaires
dpb
dpb le 18 Août 2022
Modifié(e) : dpb le 18 Août 2022
Good luck on that one...it'll take a whole lot of parsing and testing to make that work generically -- although trivial cases could be dealt with by func2str and parsing the result to find the precedent to the argument list parentheses and then applying exist to those. That would find builtin functions (not classes) and m-, mex or p-files, but in your above "^" is not a function but an operator and by including that you've just made it a whole lot harder because now you've got to parse and interpret the expression itself. If you restricted yourself to writing those cases using the optional function name (above would be pow(x,3)), then you've got sorta' a chance...
BTW, one would presume your functions inside the anonymous function are missing the "dot" operators to make then work on elemental basis for vector or array inputs...otherwise they're going to crash or give probably unexpected results.
Karamjit Singh Bedi
Karamjit Singh Bedi le 19 Août 2022
I did consider using in-built functions but for my actual application, I might need a few mathematical functions of the form "1/x". But the answer you have provided worked perfectly, I wanted a way to count the number of functions without actually executing the Function Handle.

Connectez-vous pour commenter.

Réponse acceptée

dpb
dpb le 19 Août 2022
Modifié(e) : dpb le 19 Août 2022
With coding style constraints
fun_hand = @(x)[mod(x,5);mod(x,3);x.^3;floor(20./x)].';
% the (constrained) engine
nFuncs=@(s)numel(strfind(func2str(fun_hand),';'))+1;
nFuncs(fun_hand)
ans = 4
The above limits what could be coded to not including any column vectors explicitly(*) as coefficients or other constants; that might, or might not, be something could live with.
There are probably(?) other artifices that could be dreamed up as well...
(*) That is, couldn't write [a;b;c] as a a coefficient term, but would have to use [a.',b.',c,'],' or an equivalent form instead.
  2 commentaires
dpb
dpb le 19 Août 2022
>> fun_hand = @(x)[mod(x, 5)+zeros(size(x)), mod(x, 3)+zeros(size(x)), x^3+zeros(size(x)), floor(20/x)+zeros(size(x))];
>> numel(strfind(func2str(fun_hand),'+zeros'))
ans =
4
>>
Karamjit Singh Bedi
Karamjit Singh Bedi le 19 Août 2022
This works perfectly, thank you so much!

Connectez-vous pour commenter.

Plus de réponses (2)

Voss
Voss le 19 Août 2022
Modifié(e) : Voss le 19 Août 2022
It sounds like you actually want to count the number of elements in the vector returned by your function handle, in which case you can execute fun_hand with a scalar input and then use numel:
fun_hand = @(x)[mod(x, 5), mod(x, 3), x^3, floor(20/x)];
numel(fun_hand(0))
ans = 4
  4 commentaires
Karamjit Singh Bedi
Karamjit Singh Bedi le 19 Août 2022
Yes, I was referring to "mathematical functions" and not the in-built Matlab functions. I know that I could have simply executed the Function Handle, but I wanted a way to count the functions without having to do so.
Walter Roberson
Walter Roberson le 19 Août 2022
'Yes, I was referring to "mathematical functions" and not the in-built Matlab functions.'
fun_hand = @(x)[mod(x, 5), mod(x, 3), x^3, floor(20/x)];
mod is one function, and it is being used twice here
^ is matrix power. You could argue that it is single function, but you could also argue that it is a lot of scalar multiplication and addition. The exact number of multiplication and additions required for x^2 is not certain... somewhere on the order of n^2.3 where n is the size of the matrix. But that optimized multiplication has a very high overhead and does not become cost effective until something like n=10^30 so nearly everyone uses n^3 in practice. As powers get higher you can reduce the work by binary decomposition of the power. Or you can flip over to decomposition, raise the diagonal to the power, reconstruct. It isn't clear what the appropriate mathematical function count should be.
/ is the matrix right division operator. Should the algorithm be smart enough to realize that the only time matrix power and matrix right division can be combined is for scalar x?
floor is a mathematical function
[] is considered a mathematical function, tuple formation.

Connectez-vous pour commenter.


Walter Roberson
Walter Roberson le 18 Août 2022
Modifié(e) : Walter Roberson le 18 Août 2022
The number is always 1. Each function handle encodes exactly one function, which potentially returns a non-scalar output when executed. The part to be executed is always one expression, where the expression might happen to be the [] operator.
If you want to probe the size of the returned output, without executing the handle, you would have difficulty. For example @(n)repmat(42,1,max(2,min(3,n))) could return [42 42] or [42 42 42]. I speculate that your desired result here would be 1, same as @(n)[repmat(42,1,max(2,min(3,n)))] and I further speculate that you would want 2 returned for @(n)[repmat(42,1,max(1,min(2,n))), repmat(42,1,max(1,min(2,n)))] even though the possible return values are [42 42] or [42 42 42 42].
Your example function can return empty if the input is empty, or 1 x 4 if the input is scalar, but will error in the x^3 if the input is larger unless the input is a square matrix, and will error in 20/x if the input is larger and square.

Catégories

En savoir plus sur Mathematics and Optimization dans Help Center et File Exchange

Produits


Version

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by