Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

# Default and head in function argument

52 views

### NP

Aug 7, 2010, 1:32:25 AM8/7/10
to
Hi,

I know how to define a function so that it evaluates only when the
head of the argument is of a certain type:

Clear[f];
f[x_Integer?Positive] := x^3
f[3]
f[3.1]
f[-3]

27
f[3.1]
f[-3]

and I also know how to set default to an argument of a function like
so:

Clear[f]
f[x_:3]
f[]

27

How do I do both i.e., specify head and default value?

Thanks,

NP

### Leonid Shifrin

Aug 7, 2010, 6:22:52 AM8/7/10
to
Hi,

Clear[f];
f[x : (_Integer?Positive) : 3] := x^3

Regards,
Leonid

### Simon

Aug 7, 2010, 6:30:34 AM8/7/10
to
the thing to remember here is that x_ is just shorthand for x:_ and is
not always applicable

In[1]:= x_ // FullForm
Out[1]//FullForm= Pattern[x,Blank[]]

In[2]:= x:_ // FullForm
Out[2]//FullForm= Pattern[x,Blank[]]

In[3]:= x:(_Integer?Positive):3 // FullForm
Out[3]//FullForm=
Optional[Pattern[x,PatternTest[Blank[Integer],Positive]],3]

Simon

On Aug 7, 8:22 pm, Leonid Shifrin <lsh...@gmail.com> wrote:
> Hi,
>
> Clear[f];
> f[x : (_Integer?Positive) : 3] := x^3
>
> Regards,
> Leonid
>

### David Park

Aug 8, 2010, 7:19:47 AM8/8/10
to
f[x : (_Integer?Positive) : 3] := x^3

{f[3], f[], f[3.1], f[-3]}

{27, 27, f[3.1], f[-3]}

The parentheses in the definition are necessary.

Here is a somewhat more complicated case with two default arguments. The
first one has alternatives. As long as Mathematica can distinguish the
conditions you can omit either of the two arguments, or both of them.

g[x : (_Integer?Positive | Sqrt[2]) : 3,
y : (_Integer?(# <= 0 &)) : 0] := {x, y}

{g[], g[4], g[Sqrt[2]], g[-2], g[.5, -2], g[3, -1/2], g[-1, 3]}

{{3, 0}, {4, 0}, {Sqrt[2], 0}, {3, -2}, g[0.5, -2], g[3, -(1/2)],
g[-1, 3]}

### Scot T. Martin

Aug 8, 2010, 7:23:09 AM8/8/10
to
I believe that you're after:

f[x:_Integer?(Positive):3] := x^3

The important point is the use of "(...)" to keep Mathematica oriented

### NP

Aug 9, 2010, 5:15:46 AM8/9/10
to
Hi,

Thank you all so much for the helpful solutions with explanations!

On a similar theme, I got the following to work for the case where
options are not constants

Clear[f1];
f1[A_?MatrixQ, epsilon_: Automatic] := Module[{cv = epsilon},
If[cv === Automatic,
cv = IdentityMatrix[Dimensions[A][[1]]] + (1/Det[A]) A,
IdentityMatrix[Dimensions[A][[1]]] + epsilon A]]
f1[{{1, 2}, {3, 4}}]

but not the following (only change is in the second argument)

Clear[f2];
f2[A_?MatrixQ, epsilon:(_?NumericQ):Automatic] :=
Module[{cv = epsilon},
If[cv === Automatic,
cv = IdentityMatrix[Dimensions[A][[1]]] + (1/Det[A]) A,
IdentityMatrix[Dimensions[A][[1]]] + epsilon A]]
f2[{{1, 2}, {3, 4}}]

NP

### Leonid Shifrin

Aug 10, 2010, 3:58:11 AM8/10/10
to
Not that this is a complete answer, but I have a hunch that the value of
the constant part in the optional pattern must match the pattern. In the

x:(_Integer?Positive):3,

and 3 was matching the pattern (_Integer?Positive). Now, Automatic does not
match the pattern _?NumericQ, thus your result. The following hack
therefore
works:

Clear[f3];
f3[A_?MatrixQ, epsilon : (_?NumericQ | Automatic) : Automatic] :=

Module[{cv = epsilon},
If[cv === Automatic,
cv = IdentityMatrix[Dimensions[A][[1]]] + (1/Det[A]) A,
IdentityMatrix[Dimensions[A][[1]]] + epsilon A]]

In[9]:= f3[{{1, 2}, {3, 4}}]

Out[9]= {{1/2, -1}, {-(3/2), -1}}

Regards,
Leonid

0 new messages