【问题标题】:How to have a variable argument list in Mathematica如何在 Mathematica 中有一个变量参数列表
【发布时间】:2011-04-21 16:22:24
【问题描述】:

现在我有代码,其中一些函数 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 每个术语都独立于后续术语。我不确定您所说的“将 getY 应用于 2 个以上的变量”是什么意思?
  • 我认为如果你发布你的数学会更容易提供帮助。
  • 我看到它与您的数据无关,但我的意思是 getY[a,b,c] 会导致 getX[a,b,c] 没有被评估,因为它没有定义,这是关键为什么您的代码没有正确评估。我想说的更多,但Sasha 打败了我。

标签: wolfram-mathematica


【解决方案1】:

Use __,例如

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}

【讨论】:

  • 感谢您的回答,但它对我来说还不是很有效。我会更新问题。
  • @belisarius 我确定它不起作用,但我也确定我在做一些愚蠢的事情,哈哈。我仍在尝试隔离问题,做简单的测试给出了我想要的结果
  • 也许你需要 BlankNullSequence ?见reference.wolfram.com/mathematica/ref/BlankNullSequence.html
  • @wrong,您能否发布不起作用的代码,作为您问题的更新?这将有助于诊断问题所在。
  • @rcollyer 和 @belisarius,我已经发布了!
【解决方案2】:

问题在于,在第一个版本中,具有明确数量的参数,您使用 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]])]

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

【讨论】:

  • 非常感谢您的解决方案!是否有一些文档可以解释您使用的各种符号?
  • “不知道要使用 getX 的哪个签名”,因此在给定数值之前不会对其进行评估。此时,缺少任何变量,导数为 0。
  • @wrongusername Mathematica 带有完整的可编辑文档。选择您要查找的符号,然后使用菜单帮助 > “查找所选功能”。例如@@@@@ 都会引导你到Apply&Function 的快捷方式,##SlotSequence;;Span。使用这些符号编写的 Mathematica 代码有时称为“符文代码”。我个人认为符文 Mathematica 值得在 T 恤上展示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-02
  • 1970-01-01
  • 2016-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多