MATLAB- passing a function handle parameter into another function as a handle

user194638 picture user194638 · Oct 22, 2009 · Viewed 11.2k times · Source

Working on an assignment involving Genetic Algorithms (loads of headaches, loads of fun). I need to be able to test differing crossover methods and differing mutation methods, to compare their results (part of the paper I have to write for the course). As such, I want to just pass the function names into the Repopulate method, as function handles.

function newpop = Repopulate(population, crossOverMethod, mutationMethod)
  ...
  child = crossOverMethod(parent1, parent2, @mutationMethod);
  ...

function child = crossOverMethod(parent1, parent2, mutationMethod)
  ...
  if (mutateThisChild == true)
    child = mutationMethod(child);
  end
  ...

The key point here is like 3, parameter 3: how do I pass mutationMethod down another level? If I use the @ symbol, I get told:

"mutationMethod" was previously used as a variable,
 conflicting with its use here as the name of a function or command.

If I don't use the @ symbol, then mutationMethod gets called, with no parameters, and is quite unhappy.

While I am aware that yes, I could just rewrite my code to make it work differently, I'm now curious as to how to make it actually work.

Any help is greatly appreciated.

Answer

Amro picture Amro · Oct 22, 2009

Actually just dont use the @ symbol, use it when you call the Repopulate function instead. Example:

function x = fun1(a,m)
    x = fun2(a,m);
end

function y = fun2(b,n)
    y = n(b);
end

which we call as:

> fun1([1 2 3], @sum)
6

Refer to the documentation for Passing Function Handle Arguments


Note you can check if the argument is a function handle by: isa(m,'function_handle'). Therefore you can make your function Repopulate more flexible by accepting both a function handle and a function name as a string:

function x = fun(a,m)
    if ischar(m)
        f = str2func(m);
    elseif isa(m,'function_handle')
        f = m;
    else
        error('expecting a function')
    end
    x = fun2(a,f);
end

which now can be called both ways:

fun1([1 2 3], @sum)
fun1([1 2 3], 'sum')