使用NArgMax与FindArgMax在Mathematica中进行PLOT

时间:2010-11-06 19:14:41

标签: plot wolfram-mathematica

我在使用Plot绘制复杂的复合函数时遇到了一些麻烦。

我正在尝试绘制复合函数ArgMax的{​​{1}}。

F[]涉及多个级别的嵌套复合函数,其中许多函数涉及F[]Solve[]Min[]

Max[]在我的程序中执行的方式没有任何问题(可能除了它在Plot中呈现的方式),所以我不会包含定义F[]的冗长代码和它现在的基础更简单的功能。

当我尝试使用

F[],我得到了一个非常快速的输出返回,这大部分都是正确的,除了我得到一个带有一些错误的错误值的范围,这些值似乎被渲染为错误的垂直段。部分情节。

我已经在发生bugginess的范围内评估Plot[FindArgMax[F[],{vars}],并确认正确的值与下面第二张图中显示的平滑曲线一致。

enter image description here

F[],我得到的正确情节不包括bugginess / false垂直线段,但需要相当长的时间。

我无法发布第二个链接,但Plot[NArgMax[[F[],{vars}]绘图生成的图片与上面相同,但是光滑且没有孔和垂直线段。

如果没有详细介绍NArgMax,是否有一种快速简便的方法可以让F[]在这里正常工作?基本上,这是Plot的一个常见问题,它有一个众所周知的修复,或者如果我想能够使用快速的FindArgMax,我是否需要花更多的时间来重新编码我的FindArgMax和底层复合函数的定义在我的剧情中命令?

在论坛上的第一个计时器提前感谢您的帮助。 :)

编辑:我程序麻烦部分的示例代码:

 a = 3000; b = 1/10; cc = 1/10; d = 1;

G1[x_, y_] := a Log[b x + cc y + d]

Gx1[x_, y_] := Derivative[1, 0][G1][x, y]; Gy1[x_, y_] := Derivative[0, 1][G1][x, y];

piPP1 = {y, x};

c1ycrit0[fy_, mu1_] := Max[0, Flatten[ Solve[Gy1[x, y] == fy mu1 && piPP1[1] == piPP1[[2]], y, x]][1][[2]]]

c1xcrit1[fx_, fy_, mu1_] := Max[Quiet[ Flatten[ Solve[Gx1[x, Flatten[Solve[piPP1[1] == piPP1[[2]], y]][1][[2]]] == mu1 fx, x]][1][[2]]], Quiet[Flatten[ Solve[Gx1[x, Max[0, Flatten[ Solve[Gy1[x, y] == fy*mu1 && piPP1[1] == piPP1[[2]], y, x]][1][[2]]]] == mu1 fx, x]]][1][[2]]]

c1xcrit2[fx_, fy_, mu1_, T1_] := Max[Quiet[ Flatten[Solve[T1 == x fx + fy c1ycrit0[fy, mu1] , x, y]][1][[2]]], Quiet[Flatten[ Solve[{piPP1[1] == piPP1[[2]], T1 == x fx + fy piPP1[[2]]}, x, y]][1][[2]]]]

Manipulate[ Quiet[Plot[(fx - xc) Max[0, Min[c1xcrit1[fx, fy, mu1], c1xcrit2[fx, fy, mu1, T1]]], {fx, 0, fxMax}, PlotRange -> {{0, fxMax}, {0, xPTmax}}]], {{mu1, 10, Subscript[Mu, 1]}, 0, 100}, {{xc, 3}, 0, 100}, {{fy, 10}, 0, 100}, {{T1, 100}, 0, 1000}, {{fxMax, 50}, 0, 100}, {{xPTmax, 100}, 0, 400}, ContinuousAction -> None]

BRX[fy_, xc_, mu1_, T1_] := Quiet[FindArgMax[(fx - xc) (Min[{c1xcrit1[fx, fy, mu1], c1xcrit2[fx, fy, mu1, T1]}]), {fx, xc}]]

BRX1[fy_, xc_, mu1_, T1_] := Quiet[NArgMax[(fx - xc) (Min[{c1xcrit1[fx, fy, mu1], c1xcrit2[fx, fy, mu1, T1]}]), fx]]

Manipulate[ xBR = Plot[BRX[fy, xc, mu1, T1], {fy, 0, hmax}, PlotRange -> {{0, hmax}, {0, hmax}}], {{mu1, 10, Subscript[Mu, 1]}, 0, 100}, {{xc, 3}, 0, 10}, {{T1, 100}, 0, 1000}, {{hmax, 40}, 0, 100}, ContinuousAction -> None]

Manipulate[ xBR1 = Plot[BRX1[fy, xc, mu1, T1], {fy, 0, hmax}, PlotRange -> {{0, hmax}, {0, hmax}}], {{mu1, 10, Subscript[Mu, 1]}, 0, 100}, {{xc, 3}, 0, 10}, {{T1, 100}, 0, 1000}, {{hmax, 40}, 0, 100}, ContinuousAction -> None]

进一步编辑:更改起始点“xc”以解决BRX []函数中的“fx”会大幅改变绘图的结果,这让我相信我可能不太可能有用完全使用FindArgMax。我认为由于底层函数中的所有MIN和MAX,导数都有点过于棘手。我仍然希望这里有一个可以使用FindArgMax的修复程序,但是在尝试了目前为止建议的一些事情后,我不那么乐观了。

到目前为止,再次感谢大家的帮助! :)

1 个答案:

答案 0 :(得分:2)

相关答案(见下文原件)

查看您的代码,问题在于理解Mathematica中的延迟/即时评估。例如,与第一个Manipulate相比,观察以下呈现效果如何。

Manipulate[
 Plot[Evaluate[(fx - xc) Max[0, 
     Min[c1xcrit1[fx, fy, mu1], c1xcrit2[fx, fy, mu1, T1]]]], {fx, 0, 
   fxMax}, PlotRange -> {{0, fxMax}, {0, xPTmax}}], {{mu1, 10, 
   Subscript[Mu, 1]}, 0, 100}, {{xc, 3}, 0, 100}, {{fy, 10}, 0, 
  100}, {{T1, 100}, 0, 1000}, {{fxMax, 50}, 0, 100}, {{xPTmax, 100}, 
  0, 400}]

Mathematica graphics

正如您所看到的,唯一的区别是Evaluate,它评估要一次性绘制的表达式,而不是每次需要新绘图时进行所有符号数学运算。我怀疑在你修复错误后,以类似的方式添加Evaluate可以解决其他问题。

如果您想了解如何对上述内容进行编码,以下是一些研究要点:

  • 了解Rule->)和ReplaceAll./):您应该使用Flatten[{{y->x+2}}[[1]][[2]]而不是y/.First[{{y-> x+2}}]。< / LI>
  • 放弃Quiet。他们都是。现在! ;)真的 - 除非你完全确定自己在做什么,Quiet只会隐瞒你的错误。
  • 了解Set=)vs SetDelayed:=)。作为示例,请参阅下面我将如何实现您的c1xcrit1:使用=代替:=意味着在定义x1xcrit1时,所有符号数学都将完成 而不是每次评估。

我希望这会有所帮助 - 但实际上,如果你想使用Mathematica,你应该找一个教程或其他东西来教你基础知识。

c1xcrit1[fx_, fy_, mu1_] = With[{
   y1 = y /. First@Solve[piPP1[[1]] == piPP1[[2]], y], 
   y2 = y /. First@Solve[Gy1[x, y] == fy*mu1 && piPP1[[1]] == piPP1[[2]], y, x]
   },Max[
     x /. First@Solve[Gx1[x, y1] == mu1 fx, x], 
     x /. First@Solve[Gx1[x, y2] == mu1 fx, x]]]

原始答案

您要比较的两个函数使用非常不同的算法:FindArgMaxFindMaximum的便利前端,而NArgMaxNMaximize的前端。比较两种功能可用的方法

  • FindMaximum / FindArgMax:ConjugateGradient,PrincipalAxis,LevenbergMarquardt,Newton和QuasiNewton(所有差异方法),
  • NArgMax / NMaximize:NelderMead,DifferentialEvolution,SimulatedAnnealing和RandomSearch(所有逐点方法)。

换句话说:使用FindMaximumFindArgMax来获得很好的功能,衍生产生有用的信息。对于令人讨厌的功能,请使用NArgMax / NMaximize

由于FindArgMax几乎可以工作,我会假设你的功能很好。 对于差分方法,首先进行演化,以试图建立梯度的解析表达式。引用文档:“FindArgMax首先对所有变量的值进行本地化,然后使用符号的变量计算f,然后以数字方式重复计算结果。”

听起来你的F足够复杂,以至于象征性的评价不会随处可见。如果是这种情况,则通过包装来防止符号评估。此外,同时添加缓存很少会受到伤害:

Fnum[args__/;And@@(NumericQ/@{args})]:=Fnum[args]=F[args]

您可能认为这将与NArgMax一样慢,但在许多情况下,您会发现QuasiNewton算法非常擅长构建所需衍生物的估算。

鉴于我们不知道你的F这当然是完全猜测 - 但我希望它有所帮助。