简体   繁体   中英

Trouble iterating a function with one input and two outputs on Matlab

I've created a function (name it MyFunction) which, given a matrix A, outputs two matrices B and C ie [BC] = MyFunction(A).

I'm trying to create another function which, when given a matrix A, will calculate MyFunction(A) and then calculate MyFunction(B) = [DE] and MyFunction(C) = [FG], and then calculate MyFunction(D), MyFunction(E), MyFunction(F) and MyFunction(G), and so on, until the matrices it outputs start to repeat. I know this process necessarily terminates.

I'm really having difficulty constructing this code. Any advice would be really appreciated.

I think what you're trying to do is binary tree recursion. It's hard to give a good solution without knowing more about the problem, especially without knowing what you want as the output of this process.

I whipped this up to give an example of how you could do this. It's not necessarily the most efficient because it stores all of the results at every step. Given an input matrix A, it calculates a 2-output function [B, C] = MyFunction(A) and looks for either isequal(A, B) or isequal(A, C) . When that occurs, it outputs the depth of the tree at that point, ie how many iterations had to occur before there was a repetition. The bit with global variables is just so that I could do a simple example with an easy fixed point (the k'th iteration is just A^k). It will iterate a maximum of 10 times.

function depth = myRecursor(A)

global A_orig;
A_orig = A;

depth = 1;
max_depth = 10;

pvs_level = cell(1);
pvs_level{1} = A;


while depth < max_depth,
    this_level = cell(2*length(pvs_level), 1);     
    for ix = 1 : length(pvs_level),
        [B, C] = MyFunction(pvs_level{ix})
        if isequal(B, A) || isequal(C, A),
            return;
        end
        this_level{2*ix - 1} = B;
        this_level{2*ix} = C;
    end
    depth = depth + 1;
    pvs_level = this_level;
end

function [B, C] = MyFunction(A)

global A_orig;

B = A_orig*A;
C = 2*A;

So, for example myRecursor(eye(2)) gives 1 (duh) and myRecursor([0 1; 1 0]) gives 2.

I think you should use cells:

function [B]=Myfunction(A)
  B=cell(1,numel(A)*2);
  for n=1:numel(A)
    B{n}=func1(A{n}) %%% put some processing here
    B{numel(A)+n}=func2(A{n})  %%% put some other processing here
  end
end

EDIT: rewritten wrong alg

function [list] = newFunction(A)   % returns all matrix generated matrix

list{1}=A;

done=0;
ii = 1;

while(~done)
    [B C] = myFunction(list{ii});
    list = list{list{:}, B, C};

    for jj=1:numel(list)-2
       if(all(all(list{jj}==B)) || all(all(list{jj}==C)))
           done = 1;
       end
    end

    ii=ii+1;
end

end

UPDATE: a more general way to handle an unknown number of outputs is to modify myFunction so that it outputs all matrices within a single cell vector. This way you can concatenate list this way:

[newMat] = myFunctions(list{ii}); % where newMat={B,C,...}
list = {list{:}, newMat{:}}; % or list=cat(2,list,newMat)

for jj=1:numel(list)-numel(newMat)
    for nn=1:numel(newMat) % checking for repetitions
        if(all(all(list{jj}==newMat{nn})))
            done=1;
        end
    end
end

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