如何使用 pgfplots 绘制 W-lambert 函数的逆?

如何使用 pgfplots 绘制 W-lambert 函数的逆?

这是我绘制 w-lambert 及其逆的努力,但是我得到了一个错误:

        \begin{figure}[t]
            \centering
            \begin{subfigure}[scale = 1]{0.4\textwidth}
    %           \includegraphics[width=\textwidth]{lambert_a.jpg}
                \begin{tikzpicture}
        \begin{axis}[
            samples=1001,
            enlarge x limits=false,
            axis lines=middle,
            xmin=-3.1,
            ymax=1.4,
            ytick={-1, 1},
            xtick={-3,-2,-1, 1, 2},
            yticklabels={{$-1$}, {$1$}},
            yticklabel pos=right,
            width=10cm,
            xlabel = \(x\),
            xlabel style={xshift=0.5cm, yshift=-0.2cm},
            every y tick label/.style={
                anchor=near yticklabel opposite,
                xshift=0.2em,
            },
            ylabel = \(y(x)\),
            ylabel style={xshift=-0.5cm, yshift=0.6cm},
            ]
            
    %       \addplot [red!80!black, domain=-4.2:-1, line width=0.3mm, dashed] (x * exp(x), x);
            
            \addplot [green!60!black, domain=-3:1.1, line width=0.5mm] (x, x * exp(x));
    %       
            \draw[dotted] (-1,-0.367879441171442321595523770161460867445811131031767834507836801) -- 
            (0, -0.367879441171442321595523770161460867445811131031767834507836801);
            \node[right] at (0, -0.4){\normalsize{$-1/e$}};
        \end{axis}
    \end{tikzpicture}
    
                \caption{
                    $y=x e^{x}$}
                \label{fig:first}
            \end{subfigure}
            \hfill
            \begin{subfigure}[scale =1]{0.4\textwidth}
    %           \includegraphics[width=\textwidth]{lambert_b.jpg}
                \begin{tikzpicture}[scale=1,thick]
                    \begin{axis}[
                        samples=1001,
                        enlarge y limits=false,
                        axis lines=middle,
                        xmin=-1.1,
                        ymax=1.4,
                        ytick={-4, -3, -2, -1, 1},
                        xtick={-1, 1, 2, 3},
                        yticklabels={{$-4$}, {$-3$}, {$-2$}, {$-1$}, {$1$}},
                        yticklabel pos=right,
                        width=10cm,
                        xlabel = \(x\),
                        xlabel style={xshift=0.5cm, yshift=-0.2cm},
                        every y tick label/.style={
                            anchor=near yticklabel opposite,
                            xshift=0.2em,
                        },
                        ylabel = \(W(x)\),
                        ylabel style={xshift=-0.5cm, yshift=0.6cm},
                        ]
                        
                        \addplot [red!80!black, domain=-4.2:-1, line width=0.3mm, dashed] (x * exp(x), x);
                        
                        \addplot [blue!80!black, domain=-1:1.1, line width=0.3mm] (x * exp(x), x);
                        
                        \draw[dotted] (-0.367879441171442321595523770161460867445811131031767834507836801,-1) -- (-0.367879441171442321595523770161460867445811131031767834507836801, 0);
                        \node[above] at (-0.4, 0){\tiny{$-1/e$}};
                    \end{axis}
                \end{tikzpicture}
                \caption{
                    $W(x),\quad x \geq \frac{-1}{e}$
                }
                \label{fig:second}
            \end{subfigure}
            \caption{
                $W(x)$
    and
    its inverse
            }
            \label{fig:figures}
        \end{figure}
    \end{definition}
``´

答案1

Dimension too large现在我明白你遇到的问题了:尝试绘图时可能会出现错误(pgfplots使用隐式缩放)两个分支的逆图Lambert W 函数(即f(x)=x*exp(x))与 Lambert W 函数位于同一轴上。

以下是我建议的一些方法。

第一种方式:使用几何变换;清楚的TikZ;如果我们想要的话,可以进行明确的缩放;可以应用于任何path

首先将图形的一部分(将其视为 TikZ 的path45沿 y 轴逆时针旋转一定角度[rotate=45],然后反射到 y 轴[xscale=-1],最后旋转回来[rotate=-45]。注意在 TikZ 中,路径上的选项是从右向左执行的,即

[rotate=-45,xscale=-1,rotate=45]

在此处输入图片描述

完整代码

\documentclass[tikz,border=5mm]{standalone}
\begin{document}
\begin{tikzpicture}[declare function={f(\x)=\x*exp(\x);}]
\def\pathA{plot[domain=-1:-3.5] ({f(\x)},\x)}
\def\pathB{plot[domain=-1:1.1] ({f(\x)},\x)}

% decorations
\draw[orange!50] (-3,-3)--(3,3);
\draw[->] (0,-3.5)--(0,3.5) node[below left]{$y$};
\draw[->] (-3.5,0)--(3.5,0) node[below right]{$x$};
\draw[dashed,orange,nodes={black}] 
(1,0) node[below]{$1$}--(1,{exp(1)}) 
(0,{exp(1)}) node[left]{$e$}--(1,{exp(1)})
(0,1) node[left]{$1$}--({exp(1)},1) 
({exp(1)},0) node[below]{$e$}--({exp(1)},1)
(0,-1) node[right]{$-1$}--({-1/exp(1)},-1) 
({-1/exp(1)},0) node[above,scale=.8]{$-\frac{1}{e}$}--({-1/exp(1)},-1)
(-1,0) node[above]{$-1$}--(-1,{-1/exp(1)}) 
(0,{-1/exp(1)}) node[right,scale=.8]{$-\frac{1}{e}$}--(-1,{-1/exp(1)})
;

% 2 banches of the Lambert W-function
\draw[red,densely dashed,thick] \pathA node[above left]{$W_{-1}(x)$};
\draw[blue,densely dashed,thick] \pathB node[above]{$W_0(x)$};

% 2 banches of the inverse of the Lambert W-function
% It is exactly the graph of f(\x)=\x*exp(\x)
\draw[red,thick,rotate=-45,xscale=-1,rotate=45] \pathA +(-.5,0) node[right]{$y=x e^x$};
\draw[blue,thick,rotate=-45,xscale=-1,rotate=45] \pathB node[right]{$y=x e^x$};

% turing points
\fill (-1,{-1/exp(1)}) circle(1.5pt);
\fill ({-1/exp(1)},-1) circle(1.5pt);
\end{tikzpicture}
\end{document}

第二种方法:只是plot使用清楚的TikZ:plot ({f(\x)},\x)或者plot (\x,{f(\x)});如果我们想要的话,明确缩放;给出相同的数字。

\documentclass[tikz,border=5mm]{standalone}
\begin{document}
\begin{tikzpicture}[declare function={f(\x)=\x*exp(\x);}]
% decorations
\draw[orange!50] (-3,-3)--(3,3);
\draw[->] (0,-3.5)--(0,3.5) node[below left]{$y$};
\draw[->] (-3.5,0)--(3.5,0) node[below right]{$x$};
\draw[dashed,orange,nodes={black}] 
(1,0) node[below]{$1$}--(1,{exp(1)}) 
(0,{exp(1)}) node[left]{$e$}--(1,{exp(1)})
(0,1) node[left]{$1$}--({exp(1)},1) 
({exp(1)},0) node[below]{$e$}--({exp(1)},1)
(0,-1) node[right]{$-1$}--({-1/exp(1)},-1) 
({-1/exp(1)},0) node[above,scale=.8]{$-\frac{1}{e}$}--({-1/exp(1)},-1)
(-1,0) node[above]{$-1$}--(-1,{-1/exp(1)}) 
(0,{-1/exp(1)}) node[right,scale=.8]{$-\frac{1}{e}$}--(-1,{-1/exp(1)})
;

% 2 banches of the Lambert W-function
\draw[red,densely dashed,thick] plot[domain=-1:-3.5] ({f(\x)},\x) node[above left]{$W_{-1}(x)$};
\draw[blue,densely dashed,thick] plot[domain=-1:1.1] ({f(\x)},\x) node[above]{$W_0(x)$};

% 2 banches of the inverse of the Lambert W-function
% It is exactly the graph of f(\x)=\x*exp(\x)
\draw[red,thick] plot[domain=-1:-3.5] (\x,{f(\x)}) +(0,-.5) node[right]{$y=x e^x$};
\draw[blue,thick] plot[domain=-1:1.1] (\x,{f(\x)}) node[right]{$y=x e^x$};

% turing points
\fill (-1,{-1/exp(1)}) circle(1.5pt);
\fill ({-1/exp(1)},-1) circle(1.5pt);
\end{tikzpicture}
\end{document}

第三种方法:更好的方法是清楚的渐近线(另见这个答案);我们可以根据需要使用显式缩放( unitsize(1cm,5mm);)或隐式缩放( ),或者两者兼而有之。size(8cm);

在此处输入图片描述

unitsize(1cm);
// size(8cm);    // for auto (implicit) scaling
import graph;
import gsl;      // for Lambert W-functions
real f(real x){return x*exp(x);}
pen penlegend=orange;
pen penLeft=red+.8pt;
pen penRight=blue+.8pt;
pen mydashed=linetype(new real[]{2,2});

real a=3.5;
draw((-3,-3)--(3,3),penlegend+white);
draw(Label("$y$",EndPoint,align=2SW),(0,-a)--(0,a),Arrow(TeXHead));
draw(Label("$x$",EndPoint,align=2SE),(-a,0)--(a,0),Arrow(TeXHead));

pair A=(1,f(1)), B=(-1,f(-1));
draw((A.x,0)--A^^(0,A.y)--A^^(B.x,0)--B^^(0,B.y)--B,mydashed+penlegend);
label("$1$",(A.x,0),S);  label("$e$",(0,A.y),W);
label("$-1$",(B.x,0),N); label(scale(.8)*"$-\frac{1}{e}$",(0,B.y),E);

pair Aw=(f(1),1), Bw=(f(-1),-1);
draw((Aw.x,0)--Aw^^(0,Aw.y)--Aw^^(Bw.x,0)--Bw^^(0,Bw.y)--Bw,mydashed+penlegend);
label("$e$",(Aw.x,0),S);  label("$1$",(0,Aw.y),W);
label("$-1$",(0,Bw.y),E); label(scale(.8)*"$-\frac{1}{e}$",(Bw.x,0),N);

path fLeft=graph(f,-a,-1);
path fRight=graph(f,-1,1.1);
path invfRight=graph(W0,f(-1),a);
path invfLeft=graph(Wm1,f(-1),f(-a));

draw(Label("$y=x e^x$",EndPoint,align=E),fRight,penRight);
draw(Label("$y=x e^x$",BeginPoint,align=3SE),fLeft,penLeft);
draw(Label("$W_{-1}(x)$",EndPoint,align=NW),invfLeft,penLeft+mydashed);
draw(Label("$W_0(x)$",EndPoint,align=NW),invfRight,penRight+mydashed);

dot(B^^Bw);

相关内容