【问题标题】:How can I plot a function defined on the unit simplex in Mathematica?如何绘制在 Mathematica 中的单位单纯形上定义的函数?
【发布时间】:2011-02-23 21:52:37
【问题描述】:

我正在尝试在 Mathematica 中绘制一个在单位单纯形上定义的函数。举一个随机的例子,假设我想在所有 x1、x2、x3 上绘制 sin(x1*x2*x3),使得 x1、x2、x3 >= 0 并且 x1 + x2 + x3 = 1。 除了写类似

的明显方式之外,有没有一种简洁的方式来做到这一点
Plot3D[If[x+y<=1,Sin[x y(1-x-y)]],{x,0,1},{y,0,1}]

?

理想情况下,我想要的是一种在单纯形上绘制的方法。我发现网站 http://octavia.zoology.washington.edu/Mathematica/ 有一个旧包,但它不适用于我的最新版本的 Mathematica

【问题讨论】:

    标签: wolfram-mathematica plot


    【解决方案1】:

    如果您想获得像您链接的那个包中那样的对称图,您需要找出将单纯形放入 x/y 平面的旋转矩阵。您可以在下面使用此功能。这有点长,因为我在计算中留下了单纯形居中的问题。具有讽刺意味的是,4d 单纯形图的转换要简单得多。修改e变量得到不同的边距

    simplexPlot[func_, plotFunc_] := 
     Module[{A, B, p2r, r2p, p1, p2, p3, e, x1, x2, w, h, marg, y1, y2, 
       valid},
      A = Sqrt[2/3] {Cos[#], Sin[#], Sqrt[1/2]} & /@ 
         Table[Pi/2 + 2 Pi/3 + 2 k Pi/3, {k, 0, 2}] // Transpose;
      B = Inverse[A];
    
      (* map 3d probability vector into 2d vector *)
      p2r[{x_, y_, z_}] := Most[A.{x, y, z}];
    
      (* map 2d vector in 3d probability vector *)
      r2p[{u_, v_}] := B.{u, v, Sqrt[1/3]};
    
      (* Bounds to center the simplex *)
      {p1, p2, p3} = Transpose[A];
    
      (* extra padding to use *)
      e = 1/20;
    
      x1 = First[p1] - e/2;
      x2 = First[p2] + e/2;
      w = x2 - x1;
      h = p3[[2]] - p2[[2]];
      marg = (w - h + e)/2;
      y1 = p2[[2]] - marg;
      y2 = p3[[2]] + marg;
    
      valid = 
       Function[{x, y}, Min[r2p[{x, y}]] >= 0 && Max[r2p[{x, y}]] <= 1];
      plotFunc[func @@ r2p[{x, y}], {x, x1, x2}, {y, y1, y2}, 
       RegionFunction -> valid]
      ]
    

    这里是如何使用它

    simplexPlot[Sin[#1 #2 #3] &, Plot3D]
    


    (来源:yaroslavvb.com

    simplexPlot[Sin[#1 #2 #3] &, DensityPlot]
    


    (来源:yaroslavvb.com

    如果您想在原始坐标系中查看域,可以将绘图旋转回单纯形

    t = AffineTransform[{{{-(1/Sqrt[2]), -(1/Sqrt[6]), 1/Sqrt[3]}, {1/
          Sqrt[2], -(1/Sqrt[6]), 1/Sqrt[3]}, {0, Sqrt[2/3], 1/Sqrt[
          3]}}, {1/3, 1/3, 1/3}}];
    graphics = simplexPlot[5 Sin[#1 #2 #3] &, Plot3D];
    shape = Cases[graphics, _GraphicsComplex];
    Graphics3D[{Opacity[.5], GeometricTransformation[shape, t]}, 
     Axes -> True]
    


    (来源:yaroslavvb.com

    这是另一个单纯形图,使用来自 hereMeshFunctions-&gt;{#3&amp;} 的传统 3d 轴,完整代码 here


    (来源:yaroslavvb.com

    【讨论】:

    • 谢谢,@Yaroslav。不过,我真正希望的是轴将位于单纯形的两侧,这样我们就可以真正将情节视为在单纯形本身上。我想,一个可接受的替代方案是移除边框并标记到角 x1=1、x2=1 和 x3=1(当第三个等于 1 时,其余两个变量隐式为零)。
    • 再次感谢@Yaroslav。我想象的是一个像你上面的第一个图一样的情节,但减去了封闭的盒子,并且适当地标记了角落。但现在你已经给了我所有这些提示,我可能应该尝试自己解决,而不是搭便车!
    • 封闭框由Frame选项控制,您可以使用labels=Graphics[Text[#, p2r@#] &amp; /@ IdentityMatrix@3];制作角落标签,使用Show组合原始图和标签。
    【解决方案2】:

    试试:

    Plot3D[Sin[x y (1 - x - y)], {x, 0, 1}, {y, 0, 1 - x}]
    

    但你也可以使用PiecewiseRegionFunction

    Plot3D[Piecewise[{{Sin[x y (1 - x - y)], 
        x >= 0 && y >= 0 && x + y <= 1}}], {x, 0, 1}, {y, 0, 1}, 
     RegionFunction -> Function[{x, y}, x + y <= 1]]
    

    【讨论】:

    • 这些给出的结果与我在原始问题中发布的代码相同。
    猜你喜欢
    • 1970-01-01
    • 2021-04-24
    • 1970-01-01
    • 2019-11-30
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多