使用可选值定义函数,该值默认为mathematica中函数的另一个参数的函数

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)

我怎样才能最有效地完成这项工作?

Leo*_*rin 9

对于您的原始配方,@ WReach给出了一个很好的答案.但是,重新考虑一下你的设计可能是有意义的:注意你d 在任何情况下都有一个(取决于输入参数)值.可选参数是专门为此设计的 - 是可选的.在您的情况下,默认参数似乎更合适.您可以使用Automatic@WReach建议的方式进行设置:

dimMAuto[a_?MatrixQ, d_: Automatic] :=
     If[d === Automatic, Dimensions[a], d];
Run Code Online (Sandbox Code Playgroud)

要在代码中的多个位置使用它,您需要引入一个辅助变量或常量(使用WithModule)来存储该值.作为替代方案,您还可以使用以下代码:

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)

我认为这种组合ModuleBlock是一种有趣的技术可能会找到其他用途.从本质上讲,它是动态范围的一个版本,通过词法范围(或更确切地说,它在Mathematica中的模仿)变得安全 - 因为动态范围的主要危险之一是动态本地化符号与同名的无意碰撞.

在一个不相关的问题上 - 最好不要用大写字母来启动变量和函数,因为它们可能会与系统符号发生冲突.


WRe*_*ach 5

这并不是对"简单方法"的改进,但对于许多内置的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)