Tag Info

27

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

22

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

21

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

21

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

19

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

16

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

16

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

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}} *)

15

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

14

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. This has been explained already in this answer of Mr. Wizard, so this answer ...

13

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

13

Why not use something like f[first_, arg___] := {arg} === {"ArgValue"}; For general tests, you can compare {arg} to {}, to determine whether or not the arg is empty.

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

13

Define function with Null inputs Clear[f] f[a_String: "a", Null, c_String: "c"] := a <> "b" <> c; f[Null, b_String: "b", c_String: "c"] := "a" <> b <> c; f[Null, Null, c_String: "c"] := "a" <> "b" <> c; f[a_String: "a", b_String: "b", c_String: "c"] := a <> b <> c; {f["x", "y", "z"], f["x", "y"], f["x", , ...

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

Here is what I do in such cases: ClearAll[g, f]; Options[f] = {optA -> 1, optB -> 1, optC -> 1}; f[x_, opts : OptionsPattern[]] := {OptionValue[optA], OptionValue[optB], OptionValue[optC]} Options[g] = {optA -> 0, optB -> 0}; g[x_, opts : OptionsPattern[{g, f}]] := f[x, opts, Sequence @@ Options[g]] In other words, only define options ...

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

9

We can use BlankNullSequence to keep from listing all possibilities of missing arguments. We can use recursion f[a_]:=f[b] to keep from having to repeatedly write the function body. f[a___, Null, b___] := (* pair inputs with defaults *) Transpose[{ {a, Null, b}, {"defaultA", "defaultB", "defaultC", "defaultD"} }]// (* input or default? *) ...

8

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

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

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):= ...

8

data = Reverse@Table[{2^n, 1}, {n, 1, 6}]; Graph[Table[DirectedEdge[i, i + 1], {i, Length@data - 1}], VertexLabels -> "Name", VertexCoordinates -> ({#2 Cos[#1], #2 Sin[#1]} & @@@ data), Axes -> True, ImageSize -> 300]

7

A less elegant version than Gabriel's, and a less economic than Leonid's, using ReplaceAll: f[x_, y_: 0, z_: Automatic] := {x, y, z /. Automatic -> y}

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

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

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

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

6

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

6

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

6

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

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