# Tag Info

## Hot answers tagged optional-arguments

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

I am not sure about the general solution to this problem. 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] ...

17

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

13

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

12

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

11

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

10

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

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

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

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

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

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

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

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

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

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

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

3

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

3

I propose using two separate OptionsPattern[] expressions, and placing the options for the second call in a list following the options for the first call (or anything else). foo[x_, y_, z_, opts1 : OptionsPattern[], PatternSequence[] | {opts2 : OptionsPattern[]}] := Grid[{{ Plot[Sin[x a], {a, y, z}, opts1], Plot[Cos[x a], {a, y, z}, opts2] }}] ...

3

CurrentTime[time_: Hold[DateList[]]] := {ReleaseHold@time, DateList[]}; Pause[1] CurrentTime[] {{2013, 6, 4, 8, 29, 34.8437500}, {2013, 6, 4, 8, 29, 34.8437500}} Edit This works too: Remove[CurrentTime] SetAttributes[CurrentTime, HoldAll] CurrentTime[time_: DateList[]] := {time, DateList[]};

1

One simple way is to bundle the various arguments in a vector. An example would be: f[x_]:=x^2 Obviously, this works fine for scalars x. If you make x a vector: f[{2, 3, 4}] {4,9,16} You can query the Length of the vector by Length[x] and then use this in your function. For example: g[x_] := Length[x]^2 does what you think it would, imitating ...

1

Use a doble underscore (triple if you want your function to accept no arguments at all): f[x__] := List[x] This is an example f[1] {1} f[1,2] {1,2} You can specify the type of argument, and you can also have composite data structures like sequences of two element lists, for example. As for determining the number of argument, in the simple ...

1

Not sure if this is something in the direction of the named parameters as mentioned by Nasser, however a possible alternative could be: gg[u[uu_:1],v[vv_:2],z[zz_:3]]:=Print[Column[{Row[{"u=", uu}],Row[{"v=", vv}],Row[{"z =",zz}]}]] gg[u[1], v[2], z[3]] u = 1 v = 2 z = 3 gg[u[], v[2], z[3]] u = 1 v = 2 z = 3 gg[u[], v[5], z[]] u = 1 v = 5 z = 3 ...

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