函数的平方根在 x 轴附近“行为不当”

函数的平方根在 x 轴附近“行为不当”

$H(x,y)=y^2+u(x)$我正在尝试通过对 进行多次绘图来绘制形式为 的函数的高度线$\pm\sqrt{c-u(x)}$。问题是,对于某些值,$c$域很棘手且不易计算。我尝试通过绘图来绕过这个问题$\pm\max{\sqrt{c-f(x)},0}$(被 x 轴“吸收”),但这会导致那些可见的、令人讨厌的“峰值”。我需要一个聪明的想法来摆脱它们。

我的代码:

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}[
declare function = {u(\x) = 0.5*pow(\x-2,3)-\x+4;}
]
\draw[->] (-0.5,0)--(4.5,0);
\draw[->] (0,-2.2)--(0,2.2);

\clip (-0.5,-2.2) rectangle (4,2.2);
\def\samp{200}
\foreach \c in {0,0.8,...,3.6}
{
    \draw plot[domain=-0.5:4, samples=\samp] (\x, {sqrt(max(\c-u(\x),0)))});
    \draw plot[domain=-0.5:4, samples=\samp] (\x, {-sqrt(max(\c-u(\x),0)))});
}
\end{tikzpicture}
\end{document}

结果:

在此处输入图片描述

答案1

看起来你需要做的就是增加样本量。因为这需要更长的时间,也许你只能在 y==0 附近进行,即有一个过程(200 个样本)和一个有限的精细区域(2000 个样本)。或者你只是花时间等待。

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}[
declare function = {u(\x) = 0.5*pow(\x-2,3)-\x+4;}
]
\draw[->] (-0.5,0)--(4.5,0);
\draw[->] (0,-2.2)--(0,2.2);

\clip (-0.5,-2.2) rectangle (4,2.2);
\def\samp{2000}% <<--
\foreach \c in {0,0.8,...,3.6}
{
    \draw plot[domain=-0.5:4, samples=\samp] (\x, {sqrt(max(\c-u(\x),0)))});
    \draw plot[domain=-0.5:4, samples=\samp] (\x, {-sqrt(max(\c-u(\x),0)))});
}
\end{tikzpicture}
\end{document}

在此处输入图片描述

附言:如果您有更多这样的图纸,并且担心将它们合并到更大的 Latex 文档中,可以采用以下方法:

  • 通过至少一个单独的 Latex 文档创建图纸
  • 另存为 .eps
  • 将 .eps 图像加载到您的关键文档中

参见章节“7.1 导出为 pdf/eps“在大型 tikz 手册(pgfplots.pdf)中。

答案2

为了比较,编译时使用渐近线

size(7cm);

import contour;

// H(x,y)=y^2+u(x) with u(x)=0.5*(x-2)^3-x+4;
real f(real x, real y){ return y^2+0.5*(x-2)^3-x+4;}

// Array c={0,0.8,...,3.6}
real[] c;
for (int i=0; i<=36; i=i+8) {  c.push(i/10); }

draw((-0.5,0)--(4.5,0),Arrow);
draw((0,-2.2)--(0,2.2),Arrow);

// one-dimensional pen array
pen[] pp={red, green, blue, gray};
pp.cyclic=true; // See 6.12 Arrays

// two-dimensional guide array
guide[][] g=contour(f,(-0.5,-2.2),(4,2.2),c,400); // 400 is ngraph!
guide[] G=concat(... g); // See 6.12 Arrays

for (int i=0; i<G.length; ++i)
  draw(G[i],pp[i]);

在此处输入图片描述

可以增加默认分辨率ngraph x ngraph (此处 ngraph 默认为),以获得更高的准确性。100

另请参阅8.35 contour(主要文档)以了解更多信息。

您可以像这样手动处理每个指南:

size(7cm);

import contour;

// H(x,y)=y^2+u(x) with u(x)=0.5*(x-2)^3-x+4;
real f(real x, real y){ return y^2+0.5*(x-2)^3-x+4;}

// Array c={0,0.8,...,3.6}
real[] c;
for (int i=0; i<=36; i=i+8) {  c.push(i/10); }

draw((-0.5,0)--(4.5,0),Arrow);
draw((0,-2.2)--(0,2.2),Arrow);

// two-dimensional guide array
guide[][] g=contour(f,(-0.5,-2.2),(4,2.2),c,400); // 400 is ngraph!
guide[] G=concat(... g); // See 6.12 Arrays

write(G.length); // Outputs: 7

draw(Label("$0$",EndPoint),G[0],red,Arrow);
draw(Label("$1$",BeginPoint),G[1],green,Arrow);
draw(Label("$2$",BeginPoint),G[2],blue+dashdotted,Arrow);
draw(Label("$3$",BeginPoint),G[3],red+dashed,Arrow);
draw(Label("$4$",EndPoint),G[4],gray,Arrow);
draw(Label("$5$",BeginPoint),G[5],magenta,Arrow);
draw(Label("$6$",EndPoint),G[6],cyan,Arrow);

在此处输入图片描述

答案3

我们可以用 Ti 来做到这一点Z,但使用的样本也较少。但在这种情况下,我们需要帮助 TiZ做任务。

只需选择一种数值微积分软件,然后找出多项式何时具有多个根(三次方程),然后求出它的根。接下来,只绘制正值部分。

我认为在这种情况下Z 可能可以处理数学(卡尔达诺和朋友或牛顿-拉夫森?)但我们在样本中节省的时间将用于数学,因此不值得付出努力。

我的示例每个图最多有 100+100 个样本。如果我们将曲线分成更多部分并在根部附近放置更多样本,这个数字可以减少。

这是我的代码(我使用 Python 来查找根):

\documentclass[tikz,border=2mm]{standalone}

\tikzset
{% abs is to prevent rounding errors causing a 'false negative' number
   declare function={f(\x,\y)=sqrt(abs(-0.5*\x*\x*\x+3*\x*\x-5*\x+\y));},
   my color/.style={blue, opacity={-0.4*abs(2-#1)+1.2}}
}

\begin{document}
\begin{tikzpicture}
\draw[-latex] (-0.5,0)-- (4.5,0);
\draw[-latex] (0,-3)  -- (0,3);
\def\samp{100}
% one piece
\foreach\d/\r in {0/0,0.4/0.0842,0.8/0.1786,1.2/0.2871,2.8/3.7129,3.2/3.8214,3.6/3.9158,4/4} \foreach\j in {-1,1}
  \draw[my color=\d] plot[domain=-0.5:\r, samples=\samp] (\x, {\j*f(\x,\d)}) -- (\r,0);
% two pieces
\foreach\d/\r/\s/\t in {1.6/0.4171/2.4437/3.1392,2/0.5858/2/3.4142,2.4/0.8608/1.5563/3.5829,2.5443/1.1835/1.1835/3.633} \foreach\j in {-1,1}
  \draw[my color=\d] plot[domain=-0.5:\r, samples=\samp] (\x, {\j*f(\x,\d)}) -- (\r,0)
           (\s,0) -- plot[domain=\s:\t,   samples=\samp] (\x, {\j*f(\x,\d)}) -- (\t,0);
\fill[blue] (2.8165,0) circle (1pt);
\end{tikzpicture}
\end{document}

输出结果如下:

在此处输入图片描述

相关内容