无论使用smooth
还是增加sample
点数,我都会得到这个 9 次多项式的非常锯齿状的图。
有想法吗?
\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usetikzlibrary{fpu}
\begin{document}
\begin{tikzpicture}[scale=.55]
\begin{axis}[
xlabel={$x$}, ylabel={$y$}
,restrict y to domain=-10^9:10^9
,axis lines=middle
,samples=2000,
%,grid
,thick
,domain=0:4
,xtick={0,1,2,3,4}
,ytick={0,9}
,xmin=0
,xmax=4.5
,ymin=-1
,ymax=1.8
,xlabel shift={1in}
,y tick label style={yshift={5pt}}
%,legend pos=outer north east
]
\addplot+[black,no marks,smooth]{1.5*x + 3.83333*x^2 - 15.0104*x^3 + 22.7454*x^4 - 19.2028*x^5 +
9.37731*x^6 - 2.5978*x^7 + 0.377315*x^8 - 0.0222801*x^9};
\end{axis}
\end{tikzpicture}
\end{document}
答案1
正如评论的那样约翰·科米洛,这里的问题在于精度——添加样本不会有帮助。
我的建议是将多项式拆分为二阶部分项;这样可以避免有问题的高次幂(如x^9
)。我编写了一个小型 SymPy 来执行此操作,结果您的多项式等同于:
-0.0222801*x*(x - 4.04307547777127)*(x + 0.193642687986076)*(x**2 - 7.81990533113625*x + 15.3415387466162)*(x**2 - 4.09164256641596*x + 4.41554633036612)*(x**2 - 1.1740869290557*x + 1.26942721414423)
通常情况下,这是一个计算性能更好的函数。你可以看到:
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usetikzlibrary{fpu}
\begin{document}
\begin{tikzpicture}[scale=.55]
\begin{axis}[
xlabel={$x$}, ylabel={$y$}
,restrict y to domain=-10^9:10^9
,axis lines=middle
,samples=200,
%,grid
,thick
,domain=0:4
,xtick={0,1,2,3,4}
,ytick={0,9}
,xmin=0
,xmax=4.5
,ymin=-1
,ymax=1.8
,xlabel shift={1in}
,y tick label style={yshift={5pt}}
%,legend pos=outer north east
]
% \addplot+[black,no marks,]{1.5*x + 3.83333*x^2 - 15.0104*x^3 + 22.7454*x^4 - 19.2028*x^5 +
% 9.37731*x^6 - 2.5978*x^7 + 0.377315*x^8 - 0.0222801*x^9};
\addplot+[red,no marks,]{-0.0222801*x*(x - 4.04307547777127)*(x + 0.193642687986076)
*(x*x - 7.81990533113625*x + 15.3415387466162)
*(x*x - 4.09164256641596*x + 4.41554633036612)
*(x*x - 1.1740869290557*x + 1.26942721414423)};
\end{axis}
\end{tikzpicture}
\end{document}
(如果您愿意,我可以分享 Python 代码 --- 但这只是一个技巧,可能这里的每个人都可以编写一些更优雅的东西)。
SymPi 代码用于获取多项式的二阶项形式
(根据请求,这里是 python 代码);请注意,我留下了公式的 mathjax 代码,因为 PNG 真的很小……
import sys
import os
# BEWARE only for command line interactive usage
from math import *
import scipy as sp
import numpy as np
import matplotlib.pyplot as plt
sys.path.append("/home/romano/lib/python")
import sympy as sym
from sympy import init_printing
init_printing()
sym.__version__
'1.1.1'
x, y, z = sym.symbols("x y z")
在此处输入多项式
Y=1.5*x + 3.83333*x**2 - 15.0104*x**3 + 22.7454*x**4 - 19.2028*x**5 +9.37731*x**6 - 2.5978*x**7 + 0.377315*x**8 - 0.0222801*x**9
P=sym.Poly(Y); P
$$\operatorname{Poly}{\left( - 0.0222801 x^{9} + 0.377315 x^{8} - 2.5978 x^{7} + 9.37731 x^{6} - 19.2028 x^{5} + 22.7454 x^{4} - 15.0104 x^{3} + 3.83333 x^{2} + 1.5 x, x, domain=\mathbb{R} \right)}$$
求多项式的根
rs=sym.polys.polyroots.roots(P, multiple=True); rs
$$\left [ -0.193642687986076, \quad 0, \quad 4.04307547777127, \quad 0.587043464527849 - 0.961668958061643 i, \quad 0.587043464527849 + 0.961668958061643 i, \quad 2.04582128320798 - 0.479751610251982 i, \quad 2.04582128320798 + 0.479751610251982 i, \quad 3.90995266556812 - 0.23196745382247 i, \quad 3.90995266556812 + 0.23196745382247 i\right ]$$
获得 sos(二阶段)形式的肮脏黑客。它依赖于根的顺序是固定的这一事实,我不确定这是否正确:复共轭项必须一个接一个地出现。
tot=1
skip = False
for r in rs:
rr = complex(r)
if rr.imag==0:
term = (x-rr)
tot = tot*term
else:
if skip==False: #first complex root
skip=True
a = rr.real
b = rr.imag
term = (x*x-2*a*x+(a*a+b*b))
tot = term * tot
else:
skip=False
tot
$$x \left(x - 4.04307547777127\right) \left(x + 0.193642687986076\right) \left(x^{2} - 7.81990533113625 x + 15.3415387466162\right) \left(x^{2} - 4.09164256641596 x + 4.41554633036612\right) \left(x^{2} - 1.1740869290557 x + 1.26942721414423\right)$$
f=sym.LC(P); print(f); print (f*tot)
-0.0222801000000000
-0.0222801*x*(x - 4.04307547777127)*(x + 0.193642687986076)*(x**2 - 7.81990533113625*x + 15.3415387466162)*(x**2 - 4.09164256641596*x + 4.41554633036612)*(x**2 - 1.1740869290557*x + 1.26942721414423)
检查两件事是否相同……你永远不知道
Z=sym.expand(f*tot); Z
$$- 0.0222801 x^{9} + 0.377315 x^{8} - 2.5978 x^{7} + 9.37731 x^{6} - 19.2028 x^{5} + 22.7454 x^{4} - 15.0104 x^{3} + 3.83333 x^{2} + 1.5 x$$
Y
$$- 0.0222801 x^{9} + 0.377315 x^{8} - 2.5978 x^{7} + 9.37731 x^{6} - 19.2028 x^{5} + 22.7454 x^{4} - 15.0104 x^{3} + 3.83333 x^{2} + 1.5 x$$