1

I am testing a function containing nlfilter on a matrix. For the purpose I have created a random 11X11 matrix and use a 7x7 moving window with the help of nlfilter. My function is as follows:

function funct(fh)
I = rand(11,11)
ld = input('Enter the lag = ') % prompt for lag distance
fh = @dirvar,@diagvar;
A = nlfilter(I, [7 7], fh);


% Subfunction
    function [h] = dirvar(I)
        c = (size(I)+1)/2
        EW = I(c(1),c(2):end)
        h = length(EW) - ld
    end

% Subfunction
    function [h] = diagvar(I)
        c = (size(I)+1)/2
        NE = diag(I(c(1):-1:1,c(2):end))
        h = length(NE) - ld
    end
end 

When I run funct('dirvar') it asks for lag, selects 4 elements of first row and progresses element by element. From 9th to 11th element of the first row it takes 0s as last elements(automatic padding) which is expected behavior.

But when I run funct('diagvar') the function behaves the same(as in dirvar) instead of selecting elements diagonally and going for padding. For 1st row I expect it to select first element from first row and 3 zeros and so on till end of row; when it comes to 2nd row - 1st element it will be the 2nd row - 1st element + 1st row - 2nd element followed by 2 zeros and so on.

If I just create a random matrix of order 11X11 and run lines from diagvar it selects the central value from the matrix and progresses as expected.

Chethan S.
  • 558
  • 2
  • 8
  • 28

2 Answers2

2

You are defining fh as your input variable, but then you overwrite fh with the following line:

fh = @dirvar,@diagvar;

And what is this line doing? Well, you have one variable on the left side and two function handles in a comma-separated list on the right side. What will MATLAB do with this? Well, the first entry @dirvar in the comma-separated list will be assigned to fh, and the second entry @diagvar will be assigned to nothing. Hence, this line always sets fh equal to @dirvar, which is why you always get a result as though dirvar is being used.

If you'd like to select one of your nested functions by inputting a string argument to funct, you should look at this answer I gave to another SO question, specifically options #2 and #3.

Community
  • 1
  • 1
gnovice
  • 125,304
  • 15
  • 256
  • 359
0

Try calling

funct(@diagvar)

instead; and remove the following line:

fh = @dirvar,@diagvar;

What you are doing now, doesn't change the function you are using.

Egon
  • 4,757
  • 1
  • 23
  • 38
  • As you suggested if I call `funct(@diagvar)` after removing `fh = @dirvar,@diagvar;`, that results in errors: `??? Error using ==> feval Undefined function or method 'diagvar' for input arguments of type 'double'. Error in ==> nlfilter at 61 b = mkconstarray(class(feval(fun,aa(1+rows,1+cols),params{:})), 0, size(a)); Error in ==> funct at 6 A = nlfilter(I, [7 7], fh);`. On the other hand if I have only `fh = @diagvar` and I call using `funct(@diagvar)`, the function works perfectly. – Chethan S. Apr 18 '11 at 12:36