Direct access to the elements of a vector of anonymous functions

10 次查看(过去 30 天)
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.

回答(2 个)

Steven Lord
Steven Lord 2021-5-21
f = @(x) x.^2;
getElementOf = @(vec, n) vec(n);
y = getElementOf(f(1:10), 5) % 25
y = 25
  3 个评论
Steven Lord
Steven Lord 2021-5-21
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 2021-5-22
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].

请先登录,再进行评论。


Walter Roberson
Walter Roberson 2021-6-3
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 个评论
Roman Morawski
Roman Morawski 2021-6-3
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.

请先登录,再进行评论。

类别

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

产品


版本

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by