简体   繁体   中英

recursive function handle in MATLAB

Assume the following:

u=[1 2 3];
W_in=[4 5 6]';
W=[1 2 3;4 5 6;7 8 9];
x=zeros(3,4); %initialization
x(:,1)=[1 2 3]';

How can I create a function handle such that:

x(:,i)=@(gamma) (1-gamma)*x(:,i-1)+gamma*(W*x(:,i-1)+W_in*u(i-1)) 

where gamma is a scalar between 0 and 1.

Since I CANNOT use double array to store function handle, I tried to use cell array to store function handles generated in the loop:

x=cell(1,4);
x{1}=[1 2 3]';
for i=2:4,
    x{i}=@(gamma) (1-gamma)*x{i-1}+gamma*(W*x{i-1}+W_in*u(i-1)) 
end

If I set gamma to 0.4 and try to access x{2}(0.4), I get [7.8 16 24.2]', which is what I want. However, when I try to access x{3}(0.4), I get an error which says 'Undefined operator '*' for input arguments of type 'function_handle'.'

OK, then I modify the function handle like follows,

x{i}=@(gamma) (1-gamma)*x{i-1}(gamma)+gamma*(W*x{i-1}(gamma)+W_in*u(i-1)) 

This time when I try to access x{2}(0.4), I get another error saying 'Subscript indices must either be real positive integers or logicals.', which means that 0.4 should not be used as an index. Here what confuses me is that previously I can do X{2}(0.4), but this time MATLAB seems to interpret x{i}(j) differently, j has to be an integer this time and cannot be decimals. So I don't know where to assign my value of gamma in this case and how to get rid of the error.

Generally the reason why I need a function handle in the end is that I will put the final error function handle, which involves gamma only, into genetic algorithm ga() or other optimization built-in function in MATLAB and find optimal value for gamma.

So in the end, when I eventually have cell arrays of function handles x. I could do

errorFunction=@(gamma) sum(arrayfun(@(x_q,y_q) y_q-x_q{1}(gamma),x,y));
[gamma global_minimum]=ga(errorfunction,1);

to get my optimal gamma.

You should also pass the argument to the previous functions, then everything seems to work as you intended:

u=[1 2 3];
W_in=[4 5 6]';
W=[1 2 3;4 5 6;7 8 9];
x=cell(1,4);
x{1}=@(gamma)[1 2 3]';
for i=2:4,
    x{i}=@(gamma) (1-gamma)*x{i-1}(gamma)+gamma*(W*x{i-1}(gamma)+W_in*u(i-1)) 
end

If you omit the (gamma) in x{i-1}(gamma) then you're trying to multiply a scalar with a function handle, which will obviously not work. And if you omit the @(gamma) in the definition of x{1} then you're trying to call x{1} as a function (in x{2} ), but actually Matlab notices it is not a function but just a constant matrix, so it tries using (..) as an index, but as it is a floating point number (you said eg 0.5 ) it will produce the said error about indexing.

Just as a final note: Using function handles like that works, but not well: It is quite slow, especially if you have a great number of nested calls. Otherwise you could build a polynomial as this is just constructing a polynomial expression in gamma , instructions can be found here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM