问题

问题

下列宏定义\f[#1]及其导数\fp[#1]

\def\f[#1]{((#1)*(#1-1)*(#1-2)*(#1-3)*(#1-5)/10+1.5)}
\edef\fp[#1]{Derive(1,\f[#1])}

问题

我想定义一个可重复使用的宏\g{<contant>}{<variable-x>}。不幸的是, 这是否意味着at\fp[0.8]的值始终等于零?df/dxx=0.8df[0.8]/dx

\documentclass[pstricks]{standalone}
\usepackage{pstricks-add,pst-eucl}
\def\f[#1]{(#1)*(#1-1)*(#1-2)*(#1-3)*(#1-5)/10+1.5}
\def\fDerivation#1#2{ 
    /x #1 def /F (Derive(1,#2)) tx@AlgToPs begin AlgToPs end cvx def 
    x F}
\def\g#1#2{(\fDerivation{#1}{\f[#2]})*(#2-#1)+\f[#1]} % y = f'(x0)*(x-x0) +f(x0)
\begin{document}
\begin{pspicture}[showgrid,algebraic](0,-2)(3,3)
\psplot[linecolor=blue]{0}{2}{\f[x]}
\psplot{0}{2}{\g{2}{x}}
\pstInterFF{\f[x]}{\g{2}{x}}{5}{A} % <------- this is important part!
\end{pspicture}
\end{document}

答案1

这是在 的帮助下polexpr

\documentclass{article}
\usepackage{pstricks-add,pst-eucl}
\usepackage{polexpr}

\poldef f(x):=x(x-1)(x-2)(x-3)(x-5)/10+1.5;
\PolReduceCoeffs{f}
\PolDiff{f}{f'}
\PolReduceCoeffs{f'}

\let\PolToExprOneTerm\PolToExprOneTermStyleB
\edef\f{\PolToExpr{f}}% uses x (\PolToExprVar default)
% \show\f % style "B" puts denominators on the right
% > \f=macro:
% ->x^5/10-11*x^4/10+41*x^3/10-61*x^2/10+3*x+3/2.

% first try:

% \def\g#1#2{\PolEval{f'}\At{#1}*(#2-#1) + 
%            \PolEval{f}\At{#1}} % y = f'(x0)*(x-x0) +f(x0)

% but this is bad:
% \edef\test{\g{.8}{x}}
% \show\test 
% uses xintfrac internal notation, which are no good for pstricks

% malax things to get output syntax understandable by external world
% (I should make it easier)
\newcommand\g[2]{\PolDecToString{\xintREZ{\PolEval{f'}\At{#1}}}*(#2-#1) + 
                 \PolDecToString{\xintREZ{\PolEval{f}\At{#1}}}} % y = f'(x0)*(x-x0) +f(x0)

% \edef\test{\g{.8}{x}}
% \show\test % -0.936*(x-.8) + 1.677408

% \xintverbosetrue
% \poldef k(x) := f(x) - (\g{1.4}{x}); don't forget parentheses here!
% \typeout{\PolToExpr{k}, \PolEval{k}\At{1.4}}% ok, evaluates to zero
% \PolToSturm{k}{k}
% \PolSturmIsolateZeros{k}
% \PolEnsureIntervalLengths{k}{-10}
% Package xintexpr Info: (on line 40)
%     Variable "kL_3" globally defined with value 32629939266/1[-10].

\begin{document}

\begin{pspicture}[showgrid,algebraic](0,-2)(6,4)
\psplot[linecolor=blue]{0}{5.18}{\f}

\psplot[linecolor=red]{0}{6}{\g{2}{x}}
\pstInterFF{\f}{\g{2}{x}}{5}{A} % <------- this is important part!

% This is ok
\psplot[linecolor=black]{0}{6}{\g{1.5}{x}}
\pstInterFF{\f}{\g{1.5}{x}}{5}{C}
\pstInterFF{\f}{\g{1.5}{x}}{3}{D}

\psplot[linecolor=black]{0}{6}{\g{1.4}{x}}
\pstInterFF{\f}{\g{1.4}{x}}{5}{C1}
\pstInterFF{\f}{\g{1.4}{x}}{3.2629939266}{D1}%  we have to input almost exact abscissa !!

\psplot[linecolor=black]{0}{6}{\g{1.3}{x}}
\pstInterFF{\f}{\g{1.3}{x}}{5}{C2}
\pstInterFF{\f}{\g{1.3}{x}}{3}{D2}

\psplot[linecolor=black]{0}{6}{\g{1.2}{x}}
\pstInterFF{\f}{\g{1.2}{x}}{5}{C3}
\pstInterFF{\f}{\g{1.2}{x}}{3.7}{D3}% we have to input very close abscissa !!

\psplot[linecolor=black]{0}{6}{\g{1.1}{x}}
\pstInterFF{\f}{\g{1.1}{x}}{5}{C4}
\pstInterFF{\f}{\g{1.1}{x}}{3.9}{D4}% we have to input very close abscissa !!


% \psplot[linecolor=green]{0}{6}{\g{0.8}{x}}
% \pstInterFF{\f}{\g{0.8}{x}}{5}{E}% no
% (I get errors on ghostscript side)

%\psplot[linecolor=cyan]{0}{6}{\g{3}{x}}
%\pstInterFF{\f}{\g{3}{x}}{4.8}{B}% fails to find it!

\end{pspicture}
\end{document}

备注:例如,我在使用 ghostscript 时遇到了一些问题

Running `Ps2pdf' on `testpstricks' with ``ps2pdf testpstricks.ps''
DEBUG: FC_WEIGHT didn't match

但更糟糕的是,当\pstInterFF找不到点时。但我不太了解 Ghostscript。

我的经验是,\pstInterFF有时无法预测到附近的根。对于 D1,我给出了我最好的视觉估计,精度为 1 位小数,但它找不到,所以我polexpr首先通过精度为 10 位小数来计算。

由于分数的内部符号,使用polexpr它并不总是可以立即与外部世界对话。没有在输出上使用它,但是确实在输出上使用它,所以我不得不将这个输出包装到一些额外的例程中。xintfracA/B[N]\PolToExpr\PolEval

在此处输入图片描述



仍然在polexpr我已经确定了切线与曲线在另一点再次相切相交的所有点。

事实证明,这样的点恰好有 3 对,总共 6 个点,其中 2 个点距离非常非常近,肉眼根本无法区分。

\documentclass[pstricks, preview]{standalone}
\usepackage{pstricks-add,pst-eucl}
\usepackage{polexpr}

\poldef f(x):=x(x-1)(x-2)(x-3)(x-5)/10+1.5;
\PolReduceCoeffs{f}
\PolDiff{f}{f'}
\PolDiff{f'}{f''}
\PolDiff{f''}{f3}
\PolDiff{f3}{f4}
\PolDiff{f4}{f5}


% \xintverbosetrue

\poldef Delta(x) := subs(subs(subs(subs(
                         18*a*b*c*d-4b^3d+b^2c^2-4a*c^3-27a^2d^2,
                   d=f''(x)/2), c=f3(x)/6), b=f4(x)/24), a=f5(x)/120);

\PolReduceCoeffs{Delta}% coefficients are not automatically reduced to
% smallest terms, let's do it. (but any way the Sturm chain polynomials 
% automatically are made integer coefficients with no common factor)

\PolToSturm{Delta}{DeltaSturm}
\PolSturmIsolateZeros{DeltaSturm}
\PolEnsureIntervalLengths{DeltaSturm}{-20}

\let\PolToExprOneTerm\PolToExprOneTermStyleB
\newcommand\f{}
\edef\f{\PolToExpr{f}}% uses x (\PolToExprVar default)
% \show\f % style "B" puts denominators on the right
% > \f=macro:
% ->x^5/10-11*x^4/10+41*x^3/10-61*x^2/10+3*x+3/2.

% malax things to get output syntax understandable by external world
% (I should make it easier)
\newcommand\g[2]{\PolDecToString{\xintREZ{\PolEval{f'}\At{#1}}}*(#2-#1) + 
                 \PolDecToString{\xintREZ{\PolEval{f}\At{#1}}}} % y = f'(x0)*(x-x0) +f(x0)

% \edef\test{\g{.8}{x}}
% \show\test % -0.936*(x-.8) + 1.677408

\begin{document}

\begin{preview}
\PolPrintIntervals{DeltaSturm} % (or use \xintverbosetrue and check in log)

% 1 0.38196601125010515179...
% 2 0.69722436226800535344...
% 3 0.89706136340735988338...
% 4 2.61803398874989484820...
% 5 4.30277563773199464655...
% 6 4.30293863659264011661...
\end{preview}

\begin{pspicture}[showgrid,algebraic](0,-2)(6,4)
\psplot[linecolor=blue]{0}{5.18}{\f}

% 3 0.89706136340735988338...
\psplot[linecolor=red]{0}{6}{\g{\PolSturmIsolatedZeroLeft{DeltaSturm}{3}}{x}}

\end{pspicture}

\begin{pspicture}[showgrid,algebraic](0,-2)(6,4)
\psplot[linecolor=blue]{0}{5.18}{\f}

% 2 0.69722436226800535344...
\psplot[linecolor=green]{0}{6}{\g{\PolSturmIsolatedZeroLeft{DeltaSturm}{2}}{x}}

\end{pspicture}

\begin{pspicture}[showgrid,algebraic](0,-2)(6,4)
\psplot[linecolor=blue]{0}{5.18}{\f}

% 1 0.38196601125010515179...
\psplot[linecolor=magenta]{0}{6}{\g{\PolSturmIsolatedZeroLeft{DeltaSturm}{1}}{x}}

\end{pspicture}
\end{document}

在此处输入图片描述

在此处输入图片描述

在此处输入图片描述

在此处输入图片描述

前两个并不相同(红色和绿色切线不是同一条直线)。希望我没有犯下一些愚蠢的错误,在建立计算Delta(x_0)3 次多项式的判别式的公式(f(x) - f(x_0) - f'(x_0)(x-x_0))/(x-x_0)^2时,该公式恰好在 处的切线有另一个切点时消失x_0。它似乎在视觉上起作用,两个点几乎重合,这很有趣。

当然有了这样的任意精度软件polexpr我们才不会被愚弄!



更新关于计算具有双切线的点的 6 次多项式,嵌套subs(subs(...是为了进行轻微优化,a, b, c, d只对 进行一次求值,但这里a, b, c, d不是用数值而是“多项式”替换,因此嵌套的收益subs几乎为零(当人们知道内部工作原理时)。无论如何,首先将 3 次多项式的判别式定义为函数,然后在语法中使用它,\poldef这样更清楚。xintexpr\poldef

% polexpr allows only to define one-variable polynomials (currently)
% but we only need this as a "function" (i.e. a complicated nested
% usages of xintfrac macros):

\xintdeffunc Delta3(a, b, c, d) := 18a*b*c*d-27a^2d^2-4a*c^3-4b^3d+b^2c^2;

% and we can then use this "function" with arguments being
% _polynomials_, to create a genuine _polynomial_

\poldef Delta(x) := Delta3(f5(x)/120, f4(x)/24, f3(x)/6, f''(x)/2);

% or, and we could as well have written 18*(f5(x)/120)*(f4(x)/24)*....
% but this would be barely readable, so we use the nested "subs" for clarity
% \poldef Delta(x) := subs(subs(subs(subs(
%                          18a*b*c*d-27a^2d^2-4a*c^3-4b^3d+b^2c^2;
%                    d=f''(x)/2), c=f3(x)/6), b=f4(x)/24), a=f5(x)/120);
\PolReduceCoeffs{Delta}

% \let\PolToExprOneTerm\PolToExprOneTermStyleB
% \typeout{HERE IT IS: \PolToExpr{Delta}}

6 次多项式正是这样的:

-x^6/50+33*x^5/125-3223*x^4/2500+1796*x^3/625-7457*x^2/2500+1741*x/1250-579/2500

(顺便说一下,手工完成所有这些计算并不难)

答案2

\documentclass{minimal}
\usepackage{pstricks-add}
\def\f[#1]{(#1)*(#1-1)*(#1-2)*(#1-3)*(#1-5)/10+1.5}
\def\fDerivation#1#2{ 
    /x #1 def /F (Derive(1,#2)) tx@AlgToPs begin AlgToPs end cvx def 
    x F}
\begin{document}
\begin{pspicture}[showgrid](0,-2)(3,3)
\psplot[algebraic,linecolor=blue]{0}{2}{\f[x]}
\psplot[algebraic]{0}{2}{Derive(1,\f[x])}
\psdot[dotscale=2,linecolor=red](!\fDerivation{0.8}{\f[x]})
\end{pspicture}

\end{document}

在此处输入图片描述

选择:

\documentclass{minimal}
\usepackage{pst-calculate,pstricks-add}
\def\f[#1]{(#1)*(#1-1)*(#1-2)*(#1-3)*(#1-5)/10+1.5}
\def\fDerivation#1#2{ 
    /x #1 def /F (Derive(1,#2)) tx@AlgToPs begin AlgToPs end cvx def 
    x F /M exch def pop}
\begin{document}
    \begin{pspicture}[showgrid](0,-2)(3,3)
    \psplot[algebraic,linecolor=blue]{0}{2}{\f[x]}
    \psplot[algebraic]{0}{2}{Derive(1,\f[x])}
    \psplot[linecolor=red,algebraic]{0}{3}[\fDerivation{0.8}{\f[x]}]{%
        M*(x-0.8)+\pscalculate{\f[0.8]}}
    \end{pspicture}

\end{document}

在此处输入图片描述

在此处输入图片描述

相关内容