Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I want to have the argument 'a' for myf2 in form of optional argument, but at the same time I need to evaluate the function only if 'a' is Numeric, see also my previous question.

Options[myf2] = {"a" -> 1};
myf2[b_?NumericQ, opts : OptionsPattern[]] := Module[{y, x, a},
   a = OptionValue["a"];
   If[NumericQ[a], First[y /.NDSolve[{a y'[x] == b y[x] Cos[x + y[x]], y[0] == 1}, 
       y, {x, 0, 30}]][10]]
   ];

datamyf2 = {#, myf2[1, #] + 0.01 RandomReal[]}&/@Range[0.5, 1.5,0.1]

model = NonlinearModelFit[datamyf2, myf2[b, "a" -> a], b, a]

When I tried to add the NumericQ test for 'a' in myf2, the problem is that it returns Null upon evaluating with symbol 'y' {myf2[1, "a" -> y]}, instead of leaving it unevaluated at all (as for the case when 'a' was specified as regular argument with a_?NumericQ)

How can I than specify that it should have numeric value for 'a' in the option?

Thanks!

share|improve this question
1  
Is there a good reason why you want a to be an optional argument? At least in your example it doesn't look optional to me. –  sebhofer Aug 7 '13 at 9:43
    
I posted an example function, but in real application I'm using quite many optional arguments in a physical simulation function. In that case optional arguments are very handy, see i.e. (reference.wolfram.com/mathematica/tutorial/…) –  Cendo Aug 7 '13 at 9:53
    
I'm still not convinced by this approach. I would rather define different parameter sets (e.g. as lists of replacement rules) and pass these sets to the function. –  sebhofer Aug 7 '13 at 9:59
    
Thanks for the Accept! However, I always recommend that users wait 24-hours before selecting an answer so as to give everyone around the world a chance to reply before a question appears concluded. –  Mr.Wizard Aug 7 '13 at 10:25
add comment

1 Answer

up vote 7 down vote accepted

This question appears to be about Options, not optional arguments. While it is true that OptionsPattern[] is a form of optional argument that is not typically how options themselves are described. Edit: I see that the tutorial refers to options as "named optional arguments" so I guess my understanding of convention was incorrect.

The meat of your question seems to be how to check an option value according to a pattern and return your expression (function call) unevaluated if it does not pass. You can do this with a Condition on the right-hand side of the definition:

Options[fn] = {"a" -> 1};

fn[b_?NumericQ, OptionsPattern[]] := 
  stuff[OptionValue["a"], b] /; NumericQ @ OptionValue["a"]

fn[3.5]
fn[3.5, "a" -> 7]
fn[3.5, "a" -> y]
stuff[1, 3.5]

stuff[7, 3.5]

fn[3.5, "a" -> y]

Note that opts : was not needed here as OptionValue is being used rather than e.g. FilterRules.

You could also make use of sharing between a condition and function body for more complicated tests or simply to avoid having to use OptionValue["a"] twice. (See mid-way through Using a PatternTest versus a Condition for pattern matching for an explanation of this behavior.)

ClearAll[fn]

Options[fn] = {"a" -> 1};

fn[b_?NumericQ, OptionsPattern[]] := 
  Module[{a = OptionValue["a"]}, stuff[a, b] /; NumericQ[a]]

fn[3.5]
fn[3.5, "a" -> 7]
fn[3.5, "a" -> y]
stuff[1, 3.5]

stuff[7, 3.5]

fn[3.5, "a" -> y]
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.