views:

1314

answers:

1

If I use the inline function in matlab I can create a single function name that could respond differently depending on previous choices:

if (sometimes)
  p = inline('a - b','a','b');
else
  p = inline('a + b','a','b');
end

c = p(1,2);
d = p(3,4);

But the inline functions I'm creating are becoming quite epic, so I'd like to move them to included function files instead of inline functions.

I have Mercator.m, KavrayskiyVII.m and a few others (all taking a value for phi and lambda) and I'd like to assign the chosen function to p in the same way as I have above so that I can call it many times (with variable sized matrices and things, that make eval impossible, I believe).

I have a variable, type, that will be one of the names of the functions required (eg. 'Mercator', 'KavrayskiyVII'), I figure I need to make p into a pointer to the function named inside the type variable. Any ideas?

+9  A: 

Option 1:

Use the STR2FUNC function (assumes the string in type is the same as the name of the function):

p = str2func(type);  %# Create function handle using function name
c = p(phi,lambda);   %# Invoke function handle

NOTE: There's one limitation to using STR2FUNC that's mentioned in the documentation:

Nested functions are not accessible to str2func. To construct a function handle for a nested function, you must use the function handle constructor, @.

Option 2:

Use a SWITCH statement and function handles:

switch type
  case 'Mercator'
    p = @Mercator;
  case 'KavrayskiyVII'
    p = @KavrayskiyVII;
  ...                    %# Add other cases as needed
end
c = p(phi,lambda);       %# Invoke function handle

Option 3:

Use EVAL and function handles (suggested by Andrew Janke):

p = eval(['@' type]);  %# Concatenate string name with '@' and evaluate
c = p(phi,lambda);     %# Invoke function handle

As Andrew points out, this avoids the limitations of STR2FUNC and the extra maintenance associated with a switch statement.

gnovice
How about Option 3: dynamic function handle constructors: "p = eval(['@' type])". Avoids the str2func limitation without a hand-maintained switch statement.
Andrew Janke
@Andrew: Good point... option added. ;)
gnovice
+1: Detailed and exhaustive(?) answer!
kigurai
Excellent answer! Thank you very much indeed!
JP

related questions