I have bumped into t开发者_运维知识库his problem several times on the type of input data declarations mathematica understands for functions.
It Seems Mathematica understands the following types declarations: _Integer, _List, _?MatrixQ, _?VectorQ
However: _Real,_Complex declarations for instance cause the function sometimes not to compute. Any idea why?
What's the general rule here?
When you do something like f[x_]:=Sin[x]
, what you are doing is defining a pattern replacement rule. If you instead say f[x_smth]:=5
(if you try both, do Clear[f]
before the second example), you are really saying "wherever you see f[x]
, check if the head of x
is smth
and, if it is, replace by 5". Try, for instance,
Clear[f]
f[x_smth]:=5
f[5]
f[smth[5]]
So, to answer your question, the rule is that in f[x_hd]:=1;
, hd
can be anything and is matched to the head of x.
One can also have more complicated definitions, such as f[x_] := Sin[x] /; x > 12
, which will match if x>12 (of course this can be made arbitrarily complicated).
Edit: I forgot about the Real part. You can certainly define Clear[f];f[x_Real]=Sin[x]
and it works for eg f[12.]. But you have to keep in mind that, while Head[12.]
is Real
, Head[12]
is Integer
, so that your definition won't match.
Just a quick note since no one else has mentioned it. You can pattern match for multiple Head
s - and this is quicker than using the conditional matching of ?
or /;
.
f[x:(_Integer|_Real)] := True (* function definition goes here *)
For simple functions acting on Real or Integer arguments, it runs in about 75% of the time as the similar definition
g[x_] /; Element[x, Reals] := True (* function definition goes here *)
(which as WReach pointed out, runs in 75% of the time
as g[x_?(Element[#, Reals]&)] := True
).
The advantage of the latter form is that it works with Symbolic constants such as Pi
- although if you want a purely numeric function, this can be fixed in the former form with the use of N
.
The most likely problem is the input your using to test the the functions. For instance,
f[x_Complex]:= Conjugate[x]
f[x + I y]
f[3 + I 4]
returns
f[x + I y]
3 - I 4
The reason the second one works while the first one doesn't is revealed when looking at their FullForm
s
x + I y // FullForm == Plus[x, Times[ Complex[0,1], y]]
3 + I 4 // FullForm == Complex[3,4]
Internally, Mathematica transforms 3 + I 4
into a Complex
object because each of the terms is numeric, but x + I y
does not get the same treatment as x
and y
are Symbols
. Similarly, if we define
g[x_Real] := -x
and using them
g[ 5 ] == g[ 5 ]
g[ 5. ] == -5.
The key here is that 5
is an Integer
which is not recognized as a subset of Real
, but by adding the decimal point it becomes Real
.
As acl pointed out, the pattern _Something
means match to anything with Head === Something
, and both the _Real
and _Complex
cases are very restrictive in what is given those Head
s.
精彩评论