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

时间:2011-09-12 21:12:24

标签: wolfram-mathematica

我正在尝试定义一个接收矩阵的函数,当它的尺寸未作为输入提供时,在可选参数d

中计算这些尺寸

这不起作用但是给你一个想法(options参数需要是常量):

Options[DimM] = {d -> Dimensions[A]};
DimM[A_?MatrixQ, OptionsPattern[]] := OptionValue@d;

实际上,简单的方法是输入一个不可能的值,并在函数def中输入if条件,如

Options[DimM] = {d -> 0};
DimM[A_?MatrixQ, OptionsPattern[]] :=If[OptionValue@d==0,Dimensions[A],OptionValue@d]

如何最有效地完成这项工作?

2 个答案:

答案 0 :(得分:9)

对于您的原始配方,@ WReach给出了一个很好的答案。但是,重新考虑一下您的设计可能有意义:请注意,在任何情况下{/ 1}} 都有(依赖于输入参数)值。可选参数的设计完全符合 - 可选。在您的情况下,默认参数似乎更合适。您可以使用d进行设置,类似于@WReach建议的内容:

Automatic

要在代码中的多个位置使用此功能,您需要引入辅助变量或常量(使用dimMAuto[a_?MatrixQ, d_: Automatic] := If[d === Automatic, Dimensions[a], d]; With)来存储此值。作为替代方案,您还可以使用以下代码:

Module

的优点是您可以在函数体中的任何位置使用相同的原始参数Module[{dims}, dimM[a_?MatrixQ, d_: dims] := Block[{dims = Dimensions[a]}, d] ] 。这里发生的事情非常重要:d用于生成唯一符号,然后将其作为Module的默认值给出,并用于动态计算维度。请注意,d本地化不是符号Block,而是dims生成的唯一符号dims$77542ModuleModule的这种组合使这项技术完全安全。使用示例:

Block

我认为In[1466]:= dimM[IdentityMatrix[3],{1,1}] Out[1466]= {1,1} In[1467]:= dimM[IdentityMatrix[3]] Out[1467]= {3,3} Module的这种组合是一种有趣的技术,可能会找到其他用途。从本质上讲,它是动态范围的一个版本,通过词法范围(或更准确地说,它在Mathematica中的模仿)变得安全 - 因为动态范围的主要危险之一是动态本地化符号与同名的无意碰撞。

在不相关的事情上 - 最好不要用大写字母开始你的变量和函数,因为它们可能会与系统符号发生碰撞。

答案 1 :(得分: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} *)