Direct access to the elements of a vector of anonymous functions

10 Ansichten (letzte 30 Tage)
Roman Morawski
Roman Morawski am 21 Mai 2021
Kommentiert: Roman Morawski am 3 Jun. 2021
Dear Colleagues, I would like to find an elegant method for programming a linear transformation of a vector of functions, f(x)=[f1(x), …, fN(x)], into another vector of functions, g(x)=[g1(x), …, gM(x)], i.e. the operation g(x)=A*f(x), where A is a real-valued MxN matrix. There is, however, an important requirement (IReq): I would like to have the selective access to each element of the vector g(x). Lets' consider a simple example:
A=[1 2; 3 4];f=@(x)[x;x^2];g=@(x)A*f(x);
This solution is compact and elegant, but not satisfying IReq. Of course, I can solve this problem using a cell array:
ff={@(x)x,@(x)x^2};
gg={@(x)A(1,:)*[ff{1}(x);ff{2}(x)],@(x)A(2,:)*[ff{1}(x);ff{2}(x)]};
In this case, the access to each element of gg(x) is guaranteed, but the script is cumbersome and getting unacceptably long for the large values of N and M. The direct access to the elements of vectors of anonymous functions would be a logical solution. I will appreciate the advice on how to make it possible.

Antworten (2)

Steven Lord
Steven Lord am 21 Mai 2021
f = @(x) x.^2;
getElementOf = @(vec, n) vec(n);
y = getElementOf(f(1:10), 5) % 25
y = 25
  3 Kommentare
Steven Lord
Steven Lord am 21 Mai 2021
MATLAB does not allow the creation of a (non-scalar) vector of function handles, not anymore.
f = [@(x) x.^2; @(x) x.^3] % error
Error using vertcat
Nonscalar arrays of function handles are not allowed; use cell arrays instead.
Since you can't create a non-scalar array of function handles, you can't index into one.
As you noted you could make a cell array. I can't run this in this Answer because the first line already threw an error:
f = {@(x) x.^2; @(x) x.^3};
f{2}(1:3) % [1, 8, 27]
Or you could try cellfun to iterate through the elements of f.
A = magic(3);
y = cellfun(@(fun) fun(1:3)*A, f, 'UniformOutput', false)
Roman Morawski
Roman Morawski am 22 Mai 2021
The latter operation yields a numerical result. What I need is a method for extracting M anonymous functions g1, ..., gM from the anonymous function g, for example: g1 =@(x) and g2 =@(x) from g =@(x)A*f(x), where A=[1 2; 3 4] and f=@(x)[x;x^2].

Melden Sie sich an, um zu kommentieren.


Walter Roberson
Walter Roberson am 3 Jun. 2021
There is no documented way of doing this.
Function handles have a completely opaque representation; a sealed class that is implemented completely internally. They cannot have their struct() taken, their property list is empty.
You can probe a printable representation using functions(), but as far as I can tell, that printed representation is constructed by inserting any implied commas between pieces, then removing any extra whitespace
foo = @(x) [ sin(x), 1 -1]
foo = function_handle with value:
@(x)[sin(x),1,-1]
functions(foo)
ans = struct with fields:
function: '@(x)[sin(x),1,-1]' type: 'anonymous' file: '/tmp/Editor_evpgg/LiveEditorEvaluationHelperEeditorId.m' workspace: {[1×1 struct]} within_file_path: ''
The workspace field you see there will contain an empty struct unless the anonymous function refers to variables (that are not parameters), in which case the struct will contain a copy of the variables. This does allow you to peak at the values of the variables, but gives you no way to examine the anonymous function itself.
As far as I have been able to determine, once the anonymous function is parsed, the printable version is constructed as a static string, and the meta information is constructed as shown above... and then the rest of it is all binary internals, whatever internal structure is used by the Execution Engine. Which is not something that MATLAB has ever allowed users to examine.
I do not know that it is strictly impossible to peak inside a function handle. Just maybe you could get something using some mex code. But I am absolutely certain that there is no "elegant method" of programming what you want.
In some cases you could pass a symbolic expression of the proper size to an anonymous function, have it execute on that, running the functions on symbolic inputs, and sometimes that returns a symbolic array of expressions... that could then be indexed into. And later turned into an anonmous function using matlabFunction() .
  1 Kommentar
Roman Morawski
Roman Morawski am 3 Jun. 2021
Thank you for your input. I have come to similar conclusions, and therefore I have solved my problem in a way which is at least compact. Here is a low-dimensional example:
x=@(t)[t;sin(t);cos(t)];% system input
A=magic(3);y=@(t)A*x(t);% system output
S=eye(3); % selection matrix
y1=@(t)S(1,:)*y(t)
y2=@(t)S(2,:)*y(t)
y3=@(t)S(3,:)*y(t)
The components of the function y(t) are extracted here by means of selection vectors being the rows of the identity matrix. The price for the script simplicity is a considerable number of unnecessary multiplications by 0.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Scripts finden Sie in Help Center und File Exchange

Produkte


Version

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by