Question

I have written a function to perform permutations of n obejects. I have the variables a=[1],[2],[3];k=1 and n=4;a contains the objects which are 1,2 and 3 respectively.The following is the function code that i have written:

function [res]=perm(a,k,n,jj)

if k==n
    res{jj}=a;
    jj=jj+1;

else
    for i=k:n
        t=a{k};
        a{k}=a{i};
        a{i}=t;
    perm(a,k+1,n,jj)
    t=a{k};
    a{k}=a{i};
    a{i}=t;
    end
end
end

However, when i call the function as:

jj=1;

    [res]=perm(a,k,n,jj)

I am getting the following error displayed:

Error in ==> perm at 3
if k==n

??? Output argument "res" (and maybe others) not assigned during call to "J:\main
project\perm.m>perm".

Error in ==> mainp at 254
    [res]=perm(a,k,n,jj)

The following is the code in the main program with regard to the permutation:

mr=4
    for i=1:mr
        a{i}=i;
    end
    n=mr;
    %This assignment is for the ease to work with.
    %just stored the indices till mr for the purpose of permutation
    k=1;
    %this is the k that the function perm has

  jj=1;

    [res]=perm(a,k,n,jj)

Can somebody please help me resolve this?Thanks in advance.

Was it helpful?

Solution

Your else block leaves res undefined.

I think you're assuming that res is a global variable and all invocations of perm will write into different parts of a single cell array. That isn't true. It is an output variable, local to the current call. There's no sharing during recursion, they all have independent cell arrays named res. The parameter jj is also not shared, so adding one is useless as well.

If you want to use this technique of building up the output, you'll need to make sure it is defined at a wider scope than the recursion. For example, use a local helper function:

function [res]=perm(a,k,n,jj)
    res = {};
    perm_impl(a,k);

    function [] = perm_impl(a,k) // doesn't get its own local res, n, or jj
        if k==n
            res{jj}=a;
            jj=jj+1;
        else
            for i=k:n
                t=a{k};
                a{k}=a{i};
                a{i}=t;
                perm_impl(a,k+1)
                t=a{k};
                a{k}=a{i};
                a{i}=t;
            end
        end
    end
end

Now all runs of perm_impl work on the same cell array res, because Matlab documentation says:

Variables within nested functions are accessible to more than just their immediate function. A variable, x, to which you assign a value or use within a nested function resides in the workspace of the outermost function that both contains the nested function and accesses x.

If you intentionally use a variable in this manner, it is not a problem. For examples, see the MATLAB Programming Demo on Nested Functions.

However, if you unintentionally use a variable in this manner, it can result in unexpected behavior. If the highlighting indicates that the scope of a variable spans multiple functions, and that was not your intent, consider:

  • Renaming the nested function variable so it does not match the outer function variable name.

  • Passing the variable into the function as an input argument instead of using the variable directly within the nested function

I can't tell whether a was supposed to be shared or not...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top