我已经多次针对mathematica理解函数的输入数据声明类型遇到了这个问题。
似乎Mathematica了解以下类型声明: _整数, _List, _?MatrixQ, _?VectorQ
但是:_Real,_Complex声明例如导致函数有时不计算。知道为什么吗?
这里的一般规则是什么?
答案 0 :(得分:10)
当您执行f[x_]:=Sin[x]
之类的操作时,您正在做的是定义模式替换规则。如果您改为说f[x_smth]:=5
(如果您同时尝试两者,请在第二个示例之前执行Clear[f]
),您实际上是在说“无论您在哪里看到f[x]
,请检查x
的头部}是smth
,如果是,则替换为5“。例如,尝试
Clear[f]
f[x_smth]:=5
f[5]
f[smth[5]]
因此,要回答您的问题,规则是在f[x_hd]:=1;
中,hd
可以是任何内容,并且与x的头部匹配。
还可以有更复杂的定义,例如f[x_] := Sin[x] /; x > 12
,如果x> 12(当然这可以任意复杂化),它将匹配。
Clear[f];f[x_Real]=Sin[x]
,它适用于例如f [12。]。但您必须记住,虽然Head[12.]
为Real
,但Head[12]
为Integer
,因此您的定义将不匹配。
答案 1 :(得分:6)
因为没有其他人提及它,所以请快速注意。您可以对多个Head
进行模式匹配 - 这比使用?
或/;
的条件匹配更快。
f[x:(_Integer|_Real)] := True (* function definition goes here *)
对于作用于Real或Integer参数的简单函数,它在大约75%的时间内运行,因为类似的定义
g[x_] /; Element[x, Reals] := True (* function definition goes here *)
(正如WReach指出的那样,75%的时间都在运行
作为g[x_?(Element[#, Reals]&)] := True
)。
后一种形式的优点是它可以使用符号常量,例如Pi
- 尽管如果你想要一个纯粹的数字函数,可以使用N
修复前一种形式
答案 2 :(得分:4)
最可能的问题是用于测试功能的输入。例如,
f[x_Complex]:= Conjugate[x]
f[x + I y]
f[3 + I 4]
返回
f[x + I y]
3 - I 4
第二个人工作的原因而第一个工作的原因是在查看他们的FullForm
x + I y // FullForm == Plus[x, Times[ Complex[0,1], y]]
3 + I 4 // FullForm == Complex[3,4]
在内部,Mathematica将3 + I 4
转换为Complex
对象,因为每个术语都是数字,但x + I y
与x
和{{1}的处理方式不同是y
。同样,如果我们定义
Symbols
并使用它们
g[x_Real] := -x
此处的关键是g[ 5 ] == g[ 5 ]
g[ 5. ] == -5.
是5
,不会被识别为Integer
的子集,但通过添加小数点,它变为Real
。
正如acl指出的那样,模式Real
意味着与_Something
的任何内容匹配,而Head === Something
和_Real
这两种情况都非常严格给出了那些_Complex
s。