Tag Info

Hot answers tagged

20

Mathematica has to be able to tell that the default arguments can't be rules. So, for some special cases, you could do Options[f] = {"g" -> Identity}; f[x_, y_Integer: 2, z_Integer: 3, OptionsPattern[]]:= OptionValue["g"][x + y + z] Testing: f[1, 2, 3, "g" -> (#^2 &)] 36 f[1] 6 f[1, "g" -> (#^2 &)] 36


19

As far as I know there is no way to do this with the named parameter form of Function but you can use destructuring methods with SlotSequence (##): f = {##} /. {u_: 1, v_: 0} :> body[u, v] &; f[] f[7] f[7, 8] body[1, 0] body[7, 0] body[7, 8] It is possible to give your pure function Attributes using an undocumented form. For Hold attributes ...


18

Edit: better answer below. I voted for Rojo's answer. If for some reason you cannot be that specific about your arguments you might use the converse: nr = Except[_?OptionQ]; f[x_, y : nr : 2, z : nr : 3, OptionsPattern[]] := OptionValue["g"][x + y + z] If for some further reason you need the optional arguments to be rules themselves, you could filter ...


15

A bit late-to-the-party post, and complementary to the other solutions. Several answers addressed the question quite well IMO. I had my shot on a similar one here, with a solution similar to the one by @Mr.Wizard. But now I just want to stress one subtle point missed by other answers: using OptionQ will leak evaluation for functions which are HoldAll and ...


15

Perhaps this? foo[x : (_?IntegerQ) : 1] := x; foo[] foo[7] foo["string"] 1 7 foo["string"] As Leonid reminds, if the default value does not match the test function it will not be returned. To allow for this you can explicitly include the value in the pattern: ClerAll[foo] foo[x : (_?IntegerQ | "default") : "default"] := x; foo[] foo[7] ...


13

Here is another method that I learned through reading Inside the Mathematica Pattern Matcher: Options[f] = {"g" -> Identity}; f[x_, Shortest[y_: 2, 1], Shortest[z_: 3, 2], OptionsPattern[] ] := OptionValue["g"][x + y + z] From the documentation for Shortest: Shortest[p, pri] is given priority pri to be the shortest sequence. Matches for ...


13

The syntax The answer is yes. I use this construct all the time. Here is the form: add[x_, y : (_?Positive) : 1] := x + y; You can test that it passes all the test cases. Sutble behavior to watch out for There is one additional subtlety associated with this construct: the default value must match the pattern specified for the explicit argument. So, for ...


12

You can't easily do this with optional arguments (but see Leonid's answer for a work around), but you can use the fact that you can have multiple definitions for a given function: f[x_, y_:0] := {x, y, y} f[x_, y_, z_] := {x, y, z} will do what you want. For further use of this style you could also do this as: f[x_] := {x, 0, 0} f[x_, y_] := {x, y, y} ...


11

Here's another possibility that makes use of a more involved pattern to delimit the arguments from the options. It seems to me that people writing "function definitions" are inclined to think of them rigidly in that way, commonly forgetting that these are still just patterns and can be used (and abused) as such. However, bearing in mind the true nature of ...


11

It gives those errors because you explicitly specified that pfunc only has "test" as an option. OptionValue is finicky and will complain if it sees options that it doesn't recognize. There are a couple of alternatives that I can think of: 1: Use FilterRules everywhere instead of OptionValue ClearAll@pfunc2 pfunc2[x0_, plotopts : OptionsPattern[]] := ...


11

I don't know why no one mentioned this, but all you have to do is to use a special form of OptionsPattern: pfunc[x0_, plotopts : OptionsPattern[{Plot, pfunc}]] := your-code where inside OptionsPattern go all sub-functions you need, in a list. Now everything is fine and dandy. There might be a downside of this, in case when several sub-functions can take ...


10

Yes you can, although this is not completely trivial: Module[{yy}, f[x_, y_: 0, z_: yy] := Block[{yy = y}, {x, y, z}] ] What is happening here is that I set the default to a local variable, which I then dynamically set (via Block) to a second argument. So, {f[1,2],f[1]} (* {{1,2,2},{1,0,0}} *)


10

The problem isn't with Optional but with the fact that Plus will evaluate pattern sequences as in _ + _ to get unpleasant results like 2 _. In your pattern, you can prevent this by simply wrapping everything in HoldPattern: intPolyQ[HoldPattern[ Optional[_Integer] + Plus[Optional[_Integer] x_Symbol^Optional[_Integer] ...]], x_] := True; ...


8

Prioritizing patterns If you only want the default values for the leading parameters (or some other order you choose), and not an arbitrary parameter at the time of the function call, you can prioritize the patterns as described here. f[ Shortest[u_: 1, 3], Shortest[v_: 2, 2], Shortest[w_: 3, 1] ] := u^2 + v^3 + w^4 f[v, w] 1 + v^3 + w^4 ...


8

The complete list of possible methods is given by Optimization`NMinimizeDump`$Methods: Optimization`NMinimizeDump`$Methods (* -> {Automatic, DifferentialEvolution, NelderMead, SimulatedAnnealing, RandomSearch, NonlinearInteriorPoint} *) As you can see, there is one undocumented method: NonlinearInteriorPoint. The probable reason for its being ...


7

This is possible to do, in at least two ways. The first method is to make sure that your function's definition is entered first, so that the default variable var has no value yet: ClearAll[var,f]; f[a_: var] := {a}; var = 2; f[] (* {2} *) var = 5; f[] (* {5} *) The second method would work regardless of whether or not the variable var has currently ...


7

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 ...


7

NOTE: it actually turned out that some of the conclusions here are not quite correct, will be corrected soon. Please see the comment of Oleksandr R. below. A simple case Just compile as you would do for a full list of arguments, such as compJ = Compile[{x, y}, x + y] and then delegate the execution from your main function j to compiled one as j[x_, ...


6

You can use functions with optional arguments For example: ClearAll@f; Options[f] = Options[Plot]; f[p_, opt : OptionsPattern[]] := Plot[Sin[p*x], {x, 0, 2 Pi}, opt] f[3] f[3, PlotStyle -> {Red, Thick}, ImageSize -> Small] For completeness sake: you can define your function to accept other options (not just those of Plot). In that case you ...


6

The two definitions you used don't work because Optional cannot be used as the first argument in PatternTest, thus ruling out addv1. This is mentioned in the documentation for General::patop: A pattern based on Optional cannot be used as the first argument in PatternTest, Condition, Repeated, RepeatedNull, or Optional, or as the second argument in ...


6

I too like Rojo's answer. And Mr. Wizard's answer is intriguing as always. A third possibility is adding the condition that the Heads of second and third arguments are not Rule after the LHS. So, the following also works Options[f] = {"g" -> Identity}; f[x_, y_: 2, z_: 3, OptionsPattern[]] /; (Head[y] =!= Rule && Head[z] =!= Rule):= ...


6

A simple solution After writing a very long answer with one related method and four workarounds it suddenly hit me: We need the behavior of a Symbol with the OneIdentity attribute! Observe: Attributes[foo] = {OneIdentity}; MatchQ[Null, foo[Null, i_: 1]] True Times is such a function, therefore we may use: f[Null i_: 1 | i_, Null j_: 2 | j_, Null ...


6

Here's one way to get the desired behavior, although it is not done with a single pattern: Clear[f]; f[Null, v_, w_] := f[1, v, w]; f[u_, Null, w_] := f[u, 2, w]; f[u_, v_, Null] := f[u, v, 3]; f[u_, v_, w_] := u^2 + v^3 + w^4; f[, v, w] f[u, , w] f[u, v,] f[u, ,] f[, v,] f[, , w] f[, ,] 1 + v^3 + w^4 8 + u^2 + w^4 81 + u^2 + v^3 89 + u^2 82 + v^3 9 + ...


5

I have left bottom part of this answer as a warning against not thinking :) Here is my improvement. It is not so handy but it allows us to specify which argument has to take it's optional value. edit - scoping. f = Module[{x, y, z}, Function[{u, v, g}, x^2 y^4 + z^4 /. {x -> (u /. Null -> 3), y -> (v ...


5

OptionValue and OptionsPattern[] are magical constructs, which work by certain macro-like trick at run-time. So, I am not surprised that OptionValue did not work here. I would suggest to use it's long form: OptionValue[f, {opts}, optionName], and declare options as opts:OptionsPattern[], rather than just OptionsPattern[] - it will work then, and ...


5

This question and Leonid's interpretation of it don't make sense to me. This definition: f[first_, arg___] := (arg === "ArgValue") Will give True for f[1, "ArgValue", "ArgValue"] while Leonid's method will not. Perhaps you want: ClearAll[f] f[first_, arg : "ArgValue" ...] := {} =!= {arg} {f[1], f[1, "ArgValue", "ArgValue"]} {False, True} Without ...


5

Already late to the party, but here is another approach: ClearAll[f] f[x_, y_: Automatic] := If[y === Automatic, {x, x}, {x, y}] Another Optional trick is the following: ClearAll[f] f[x : (y_) : 1] := {x, y} Here the colon is used twice. Once as shorthand for Pattern and once as shorthand for Optional. This is not appropriate for you question. I ...


5

I believe you need to add all of Plot's options to pfunc as well, like this: Options[pfunc] = Join[ Options[Plot], {"test" -> True, ...} ] I'd like to note that this is what builtins do as well. For example, Plot also carries all possible Graphics options. The downside is that any changes to the default options of Plot won't affect pfunc. The upside ...


5

The third parameter allows control of Optional behavior for multiple function definitions. It is not attached to the number of actual arguments passed to the function but rather to the number of arguments that appear in the function definition itself. Consider this example: ClearAll[f]; Default[f, 1, 3] = a1; Default[f, 2, 3] = a2; Default[f, 3, 3] = a3; ...


4

Don't quite understand why, but one needs both patterns (Jens' and ywdr1987's) to get True for all the expressions in the example. This can be done using Alternatives or adding an additional definition to cover the pattern in Jens's answer: ClearAll[intPolyQa]; intPolyQa[HoldPattern[Optional[_Integer] + Plus[Optional[_Integer] x_Symbol^Optional[_Integer] ...



Only top voted, non community-wiki answers of a minimum length are eligible