如何直接从Solve的输出创建一个函数

时间:2011-03-16 00:44:40

标签: wolfram-mathematica

如果我评估Solve[f[x,y]==0,x],我会得到一堆解决方案,如:

{{x -> something g[y]}, {x -> something else}}

现在我想将每个x->somethings转换为一个函数。通常情况下,我的要求很低,我的函数f[x]最多是一个立方体,有x的直接解决方案。所以我总是手动定义g1[y_]:=somethingg2[y_]:=...等。

但是,对于我现在拥有的函数,Solve输出一个运行4页长的复杂多项式,并且有4个这样的解。我尝试使用SimplifyCollectFactor等缩减为简单的表单,但这似乎是不可简化的。

有没有办法可以自动将它们分配给函数? (滚动页面并复制每个页面非常困难......我必须寻找下一页开始的位置!)

类似于:{g1[y_], g2[y_], g3[y_]} = output of Solve

5 个答案:

答案 0 :(得分:7)

看来西蒙打败了我的答案(我很高兴StackOverflow给了我一个弹出窗口让我知道!),因此我将采取不同的方法。您应该知道如何直接使用Solve的输出,因为很多时候这样做会很方便。

开始
ClearAll[a, x, sols]

sols = Solve[x^2 + a x + 1 == 0, x]

以下是您可以做的一些事情。


x

找到a == 7的解决方案
x /. sols /. a -> 7

绘制解决方案

这里使用

Evaluate并非出于基本功能的必要性,而是允许Plot函数单独设置每个解决方案的样式

Plot[Evaluate[x /. sols], {a, 1, 4}]

enter image description here


为第二个解决方案

定义a的新功能

请注意使用=而不是:=此处

g[a_] = x /. sols[[2]]

以下是Simon为每个解决方案定义函数的方法的替代方法

MapIndexed[(gg[#2[[1]]][a_] := #) &, x /. sols]

该函数随后使用语法gg[1][17]表示第一个解决方案,a == 17

Plot[gg[1][a], {a, 1, 4}]

gg[2] /@ {1, 2, 3}

这些用途通常要求a(在此示例中)保持未分配状态。

答案 1 :(得分:1)

这是一个可以清理的简单解决方案

In[1]:= solns = Solve[x^2+a x+b==0, x]
Out[1]= {{x -> 1/2 (-a-Sqrt[a^2-4 b])}, {x -> 1/2 (-a+Sqrt[a^2-4 b])}}

In[2]:= Table[Symbol["g"<>ToString[i]][a_,b_] := Evaluate[x/.solns[[i]]],
              {i,Length[solns]}];

In[3]:= DownValues/@{g1,g2}
Out[3]= {{HoldPattern[g1[a_,b_]]:>1/2 (-a-Sqrt[a^2-4 b])},
         {HoldPattern[g2[a_,b_]]:>1/2 (-a+Sqrt[a^2-4 b])}}

答案 2 :(得分:0)

以下函数会自动将Solve的输出转换为函数列表(假设Solve 找到解决方案):

solutionFunctions[expr_, var_] :=
  Check[Flatten @ Solve[expr, var], $Failed] /.
    (_ -> x_) :>
      Function[Evaluate[Union @ Cases[x, _Symbol?(!NumericQ[#]&), Infinity]], x]

以下是一个例子:

In[67]:= g = solutionFunctions[x^2+a x+1==0, x]
Out[67]= {Function[{a},1/2(-a-Sqrt[-4+a^2])],Function[{a},1/2(-a+Sqrt[-4+a^2])]}

可以单独调用这些函数:

In[68]:= g[[1]][1]
Out[68]= 1/2 (-1-I Sqrt[3])

In[69]:= g[[2]][1]
Out[69]= 1/2 (-1+I Sqrt[3])

或者,可以立即调用所有函数来返回所有解决方案:

In[70]:= Through[g[1]]
Out[70]= {1/2 (-1-I Sqrt[3]),1/2 (-1+I Sqrt[3])}

如果Solve找不到任何解决方案,该功能将失败:

In[71]:= solutionFunctions[Log[x]==Sin[x],x]
During evaluation of In[71]:=
  Solve::nsmet: This system cannot be solved with the methods available to Solve.
Out[71]= $Failed

自动识别变量:

In[72]:= solutionFunctions[a x^2 + b x + c == 0, x]

Out[72]= { Function[{a, b, c}, (-b - Sqrt[b^2 - 4 a c])/(2 a)],
           Function[{a, b, c}, (-b + Sqrt[b^2 - 4 a c])/(2 a)] }

答案 3 :(得分:0)

这是最简单的方法:

In[1]:= f = Solve[x^2 + ax + 1 == 0, x]
Out[1]= {{x -> -Sqrt[-1 - ax]}, {x -> Sqrt[-1 - ax]}}

In[2]:= g1[y_] := x /. f[[1]] /. a -> y
        g2[y_] := x /. f[[2]] /. a -> y

In[4]:= g1[a]
        g2[a]

Out[4]= -Sqrt[-1 - ax]
Out[5]= Sqrt[-1 - ax]

答案 4 :(得分:0)

这真的很酷。谢谢。通过将Solve结果转换为函数,我可以在Plot中使用Manipulate。像

这样的东西
In[73]:= g = solutionFunctions[x^2 + a x + b == 0, x]
Out[73] = {Function[{a, b}, 1/2 (-a - Sqrt[a^2 - 4 b])], 
  Function[{a, b}, 1/2 (-a + Sqrt[a^2 - 4 b])]}

In[74]:= Manipulate[Plot[g[[1]][a, b], {a, 0, 4}], {{b, 1}, 0, 10}]

你得到一个你可以操纵参数b

的情节