Phi*_*hil 5 wolfram-mathematica
我试图定义一个接收矩阵的函数,当它的尺寸没有作为输入提供时,在可选参数中计算这些尺寸 d
这不起作用,但给你的想法(选项参数需要是常量):
Options[DimM] = {d -> Dimensions[A]};
DimM[A_?MatrixQ, OptionsPattern[]] := OptionValue@d;
Run Code Online (Sandbox Code Playgroud)
实际上,简单的方法是输入一个不可能的值,并在函数def中输入if条件
Options[DimM] = {d -> 0};
DimM[A_?MatrixQ, OptionsPattern[]] :=If[OptionValue@d==0,Dimensions[A],OptionValue@d]
Run Code Online (Sandbox Code Playgroud)
我怎样才能最有效地完成这项工作?
对于您的原始配方,@ WReach给出了一个很好的答案.但是,重新考虑一下你的设计可能是有意义的:注意你d 在任何情况下都有一个(取决于输入参数)值.可选参数是专门为此设计的 - 是可选的.在您的情况下,默认参数似乎更合适.您可以使用Automatic@WReach建议的方式进行设置:
dimMAuto[a_?MatrixQ, d_: Automatic] :=
If[d === Automatic, Dimensions[a], d];
Run Code Online (Sandbox Code Playgroud)
要在代码中的多个位置使用它,您需要引入一个辅助变量或常量(使用With或Module)来存储该值.作为替代方案,您还可以使用以下代码:
Module[{dims},
dimM[a_?MatrixQ, d_: dims] :=
Block[{dims = Dimensions[a]},
d]
]
Run Code Online (Sandbox Code Playgroud)
它的优点是你可以d在函数体中的任何地方使用相同的原始参数.这里发生的事情非常重要:Module用于生成唯一符号,然后将其作为默认值d并用于动态计算维度.请注意,Block本地化不是符号dims,而是由dims$77542生成的唯一符号Module.的组合Module,并Block使得这一技术完全安全的.使用示例:
In[1466]:= dimM[IdentityMatrix[3],{1,1}]
Out[1466]= {1,1}
In[1467]:= dimM[IdentityMatrix[3]]
Out[1467]= {3,3}
Run Code Online (Sandbox Code Playgroud)
我认为这种组合Module和Block是一种有趣的技术可能会找到其他用途.从本质上讲,它是动态范围的一个版本,通过词法范围(或更确切地说,它在Mathematica中的模仿)变得安全 - 因为动态范围的主要危险之一是动态本地化符号与同名的无意碰撞.
在一个不相关的问题上 - 最好不要用大写字母来启动变量和函数,因为它们可能会与系统符号发生冲突.
这并不是对"简单方法"的改进,但对于许多内置的Mathematica函数,符号Automatic被用作"不可能的值".例如:
Options[DimM] = {d -> Automatic};
DimM[A_?MatrixQ, OptionsPattern[]] := OptionValue[d] /. Automatic->Dimensions[A]
DimM[RandomInteger[10, {2, 2}]]
(* {2, 2} *)
DimM[RandomInteger[10, {2, 2}], d -> {5, 5}]
(* {5, 5} *)
Run Code Online (Sandbox Code Playgroud)