如何在Mathematica中使用可变参数列表

5

现在我有一些代码,其中一些函数func在其定义中给定特定参数时以我想要的方式执行(因此我将其定义为func[x1_,x2_]:=...,然后稍后我将其定义为func[x1_,x2_,x3_]:=...而不改变任何其他内容,它按照我想要的方式工作)。是否有一种自动替换我指定的任何参数来代替这个函数的方法?

更新:

我还没有分离出问题代码,但是这里的代码不是我想要的:

(* Clear all stuff each time before running, just to be safe! *)
\
Clear["Global`*"]

data = {{238.2, 0.049}, {246.8, 0.055}, {255.8, 0.059}, {267.5, 
    0.063}, {280.5, 0.063}, {294.3, 0.066}, {307.7, 0.069}, {318.2, 
    0.069}};
errors = {{x1, 0.004}, {x2, 0.005}};

getX[x1_, x2_] := 1/x2^2

getY[x__] = 
 Evaluate[Simplify[
   Sqrt[Sum[(D[getX[x], errors[[i]][[1]]] errors[[i]][[2]])^2, {i, 
      Length[errors]}]]]]

map[action_, list_] := action @@@ list

y = map[getY, data];
y

getY[2, 3]

这段代码的作用是:(将y的值设为{67.9989, 48.0841, 38.9524, 31.994, 31.994, 27.8265, 24.3525, 24.3525}

(* Clear all stuff each time before running, just to be safe! *) \ Clear["Global`*"]

data = {{238.2, 0.049}, {246.8,
0.055}, {255.8, 0.059}, {267.5, 
    0.063}, {280.5, 0.063}, {294.3, 0.066}, {307.7, 0.069}, {318.2, 
    0.069}}; errors = {{x2, 0.004}, {x1, 0.005}};

getX[x1_, x2_] := 1/x2^2

getY[x1_, x2_] :=   Evaluate[Simplify[ Sqrt[Sum[(D[getX[x1, x2], errors[[i]][[1]]] 
        errors[[i]][[2]])^2, {i, Length[errors]}]]]]

map[action_, list_] := action @@@ list

y = map[getY, data]; y

getY[2, 3]

更新2:

我的计算方法是:

我打算对getX函数的所有偏导数的平方和进行开方,从而得到getY函数的主体。然后我想要针对不同的x1x2值来评估该表达式。因此,我有了getY的参数。


问题出在 getY 函数中。由于 getX 函数只“理解”两个变量,所以在 getY 函数中的表达式 getX[x] 将会出现问题。因此,您需要定义您希望从将 getY 应用于超过 2 个变量中获得什么结果,然后您可以确定 getX 函数必须扮演什么角色。例如,给定列表 {a,b,c},求和中的每一项是否依赖于列表中的连续项,即您应该对 {{a,b},{b,c}} 进行求和? - rcollyer
@rcollyer,每个术语都独立于后续术语。我不确定您所说的“将getY应用于超过2个变量”的意思是什么? - wrongusername
如果您发布您的数学问题,我认为帮助您会更加容易。 - Dr. belisarius
1
我知道这与你的数据无关,但我的意思是 getY[a,b,c] 会得到 getX[a,b,c],但由于它没有被定义,所以不会被计算,这就是你的代码不能正确计算的关键。我可以说更多,但Sasha已经说过了。 - rcollyer
2个回答

5
使用 __,例如:BlankSequence
In[4]:= f[x__] = {x}
Out[4]= {x}

In[5]:= f[1,2,3,4,5,6]
Out[5]= {1, 2, 3, 4, 5, 6}

In[6]:= f[a,b,c]
Out[6]= {a, b, c}

谢谢你的回答,但对我来说还不太起作用。我会更新问题。 - wrongusername
@belisarius 我确定它不起作用,但我也确定我在做一些愚蠢的事情,哈哈。我仍然在努力分离问题,进行简单的测试可以得到我想要的结果。 - wrongusername
1
也许你需要BlankNullSequence?请参阅http://reference.wolfram.com/mathematica/ref/BlankNullSequence.html - Sasha
@wrong,请您将不起作用的代码作为问题的更新发布一下,这将有助于诊断出问题所在。 - rcollyer
@rcollyer和@belisarius,我已经发布了! - wrongusername

3

问题在于,在第一个版本中,你使用了Evaluate来评估右侧的参数数量。当参数数量是可变的时候,你不能这样做,因为求值器不知道要使用哪个getX的签名。

所以解决方案是用以下内容替换getY

getY[x__] := (Simplify[
    Sqrt[(D[getX @@ 
          errors[[1 ;; Length[{x}], 1]], {errors[[All, 1]]}]. 
        errors[[All, 2]])^2]]) /. 
  Thread[errors[[1 ;; Length[{x}], 1]] -> {x}]

这将首先使用errors列表中的变量,数量与您在getY参数中提供的数量完全相同,进行符号导数计算,然后执行Dot而不是较慢的Sum。然后输出将是相同的。
请注意,在您的两个代码版本中,errors具有不同的值。
或者,您可以这样使用Derivative:
getY2[x__] := 
 Abs[(Derivative[##][getX][x] & @@@ 
     IdentityMatrix[Length[{x}]].errors[[All, 2]])]

使用它会得到相同的结果。

非常感谢提供的解决方案!是否有一些文档可以解释您使用的各种符号? - wrongusername
不知道该使用getX的哪个签名,因此在给定数值之后它被保留为未评估状态。此时,由于缺乏任何变量,导数为0。 - rcollyer
2
Mathematica附带完整的可编辑文档。选择您想查找的符号,使用菜单帮助 > "查找所选函数"。例如,@@@@@都会引导您到Apply&Function的快捷方式,##SlotSequence;;Span。使用这些符号编写的Mathematica代码有时被称为“符文代码”。我个人认为,符文Mathematica的一些片段值得展示在T恤上。 - Sasha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接