# Problem with tkz-tab and its the PSTricks package equivalent

My code:(use tkz-tab)

\documentclass[12pt,a4paper]{article}
\usepackage{amsmath,amssymb,newcent}
\usepackage{tkz-tab}
\begin{document}
\begin{tikzpicture}
\tkzTabInit{$x$ /1, $g'(x)$ /1, $g(x)$ /3.5}
{$-\infty$,$a$,$1$,$3$, $+\infty$}
\tkzTabLine{,-,0,+,0,-,0,+  }
\tkzTabVar{+/$+\infty$, -/$m-\dfrac{1}{4}$ , +/$g(1)$, -/$m$, +/$+\infty$}
\end{tikzpicture}
\end{document}


The result compiling:

Question:

1. How to move m-1/4 lower than m? It means

2. Does PSTricks has the command or package(I don't know) the same as tkz-tab? Assume without any the command or package, so how to create it only use the pspicture environment?

• You're right, it seems I misunderstood. I've added a new code (leaving the previous one, as it might be of interest to some). Is it better? – Bernard Dec 4 '18 at 14:09

For your first question, is this what you want? Note I replaced $\dfrac{1}{4}$ with $\mfrac{1}{4}$ (medium sized fraction from nccmath) , as I think that, used as a numerical coefficient, it looks nicer. The level alignment of m-\mfrac{1}{4} and m is obtained adding a \vphantom{\mfrac{1}{4}} to the latter, so the boxes containing both minima have the same height.

\documentclass[12pt,a4paper]{article}
\usepackage{amsmath, amssymb, newcent}
\usepackage{tkz-tab}
\usepackage{nccmath}

\begin{document}

\begin{tikzpicture}
\tkzTabInit{$x$ /1, $g'(x)$ /1, $g(x)$ /3.5}
{$-\infty$,$a$,$1$,$3$, $+\infty$}
\tkzTabLine{,-,0,+,0,-,0,+ }
\tkzTabVar{+/$+\infty$, -/$m-\mfrac{1}{4}$ , +/$g(1)$, -/$m\vphantom{\mfrac 14}$, +/$+\infty$}
\end{tikzpicture}

\end{document}


Edit: It seems I misundertood the requirement. I hope the following code is more like you want (same preamble):

\begin{tikzpicture}
\tkzTabInit{$x$ /1, $g'(x)$ /1, $g(x)$ /3.5}
{$-\infty$,$a$,$1$,$3$, $+\infty$}
\tkzTabLine{,-,0,+,0,-,0,+ }
\tkzTabVar{+/$+\infty$, -/$m-\mfrac{1}{4}$ , +/$g(1)$, -/\raisebox{4ex}{$m\vphantom{\mfrac{1}4}$}, +/$+\infty$}
\end{tikzpicture}


• I see it seem was not changed. " m-1/4 " = " m " – Trong Vuong Dec 4 '18 at 12:02
• Both ms are now at the same level, using a \vphantom{\mfrac{1}{4} for the rightmost m – Bernard Dec 4 '18 at 12:40
• You can edit your answer to show what you say. My english is not good. – Trong Vuong Dec 4 '18 at 12:58
• I've added some explanations. Is that clearer? – Bernard Dec 4 '18 at 13:28
• \smash[t]{\vphantom{\mfrac{1}{4}}} seems better. Or \dfrac, of course, if \dfrac is used in the other place. – egreg Dec 4 '18 at 13:40

You can use the new tablvar package (documentation in French):

\documentclass[12pt,a4paper]{article}
\usepackage{amsmath,amssymb}
\usepackage[tikz]{tablvar}

\begin{document}

$\begin{tablvar}{4} \hline x & -\infty && a && 1 && 3 && +\infty \\ \hline g'(x) && - & 0 & + & 0 & - & 0 & + & \\ \hline \variations{ \mil{g(x)} & \haut{+\infty} && \bas{m-\dfrac{1}{4\mathstrut}} && \haut{g(1)} && \bas{m} && \haut{+\infty} } \hline \end{tablvar}$

\end{document}


Removing the tikz option makes the package rely on PSTricks.

If you want to easily move the m up (which I can't see the necessity of), raise it.

\documentclass[12pt,a4paper]{article}
\usepackage{amsmath,amssymb}
\usepackage[tikz]{tablvar}

\begin{document}

$\begin{tablvar}{4} \hline x & -\infty && a && 1 && 3 && +\infty \\ \hline g'(x) && - & 0 & + & 0 & - & 0 & + & \\ \hline \variations{ \mil{g(x)} & \haut{+\infty} && \bas{m-\dfrac{1}{4\mathstrut}} && \haut{g(1)} && \bas{\raisebox{2ex}{m\mathstrut}} && \haut{+\infty} } \hline \end{tablvar}$

\end{document}


• Thank you but you should see edited question! My aim is to set "m" at that position. – Trong Vuong Dec 4 '18 at 14:02
• @chishimotoji Added. Probably there are more features in the package documentation. – egreg Dec 4 '18 at 14:04

Out of topic! For polynomials and rational functions with minimum one rational zero we can do the factorization and finding the (only) rational roots with the help of the xintexpr and polexpr packages. Then the table is build automatic.

So we can type for e.g. in the document

\poldef zf1(x):=(-1/4)(x^2-4x+3)(x-2)^2(x^2+1)(x^2+2);
\PolReduceCoeffs{zf1}
Given is the derivative:
$f^{\prime}:t \mapsto \PolTypeset[t]{zf1} = \typesetFactors[t]{zf1}$

\medskip
\renewcommand{\arraystretch}{1.2}%
\VZTabelle[f][t][zf1]


Here is the code for a full example.

\documentclass[fleqn,svgnames,x11names,dvipsnames]{article}

\usepackage[a4paper,margin=1.25cm]{geometry}
\usepackage{amsmath,amssymb}
\usepackage{xintexpr}
\usepackage{polexpr}
\usepackage{xfp,xparse,expl3,xstring}
\usepackage{booktabs}
\usepackage{siunitx}
\sisetup{group-separator={\,},output-decimal-marker={,},exponent-product=\cdot,per-mode=fraction,product-units=single,
input-product=*,output-product=\cdot,unit-mode=text,quotient-mode=fraction,locale=DE,range-phrase = { bis }}
\usepackage{pstricks}

\let\funk\PolToExpr
\let\STZeroL\PolSturmIsolatedZeroLeft

\NewExpandableDocumentCommand{\XcalcR}{sO{8}m}{%  calculates #3 and rounds to #2 decimals; non formating: for formated output use \Xcalc not \XcalcR
\PolDecToString{\xintREZ{\xinttheiexpr[#2]reduce(#3)\relax}}%
}

\NewDocumentCommand{\Xcalc}{t+stDsO{2}m}{% calculates #5, rounds to #4 decimals (trailing zeros are supressed) and typesets the number with num-macro formatting
\IfBooleanT{#1}{\xintifSgn{\xinttheexpr #6\relax}{}{+}{+}}%  or as fraction, reduced or not reduced and with #3=D is a boolean in displaystyle
\IfBooleanTF{#2}%
{\IfBooleanT{#3}{\displaystyle}%
\IfBooleanTF{#4}%
{\xintSignedFrac{\xinttheexpr #6\relax}}%
{\xintSignedFrac{\xinttheexpr reduce(#6)\relax}}%
}%
{\num{\PolDecToString{\xintREZ{\xinttheiexpr[#5]reduce(#6)\relax}}}}%
}

\newcommand{\NullStellen}[1]{%
\xintFor* ##1 in {\xintSeq{1}{\PolSturmNbOfIsolatedZeros{#1}}}
\do
{x_{##1} = \Xcalc{\PolSturmIsolatedZeroLeft{#1}{##1}}%
\xintifForLast{}{; }}%
}

\NewDocumentCommand{\hackNst}{O{nt}D(){x}m}{%
\xintifboolexpr{\PolSturmNbOfIsolatedZeros{#3}=0}{}{%
\xintiloop [1+1]
\expandafter\def\expandafter\tmp\xintbracediloopindex
\xintdefvar #2\tmp = \PolSturmIsolatedZeroLeft{#3}\tmp;
\xintdefvar #1\tmp = \PolSturmIsolatedZeroMultiplicity{#3}\tmp;
\ifnum\xintiloopindex<\numexpr\PolSturmNbOfIsolatedZeros{#3}\relax
\repeat
}%
}

\NewDocumentCommand{\GenFloatSturmZeros}{ssO{9}D(){x}m}{%
\IfBooleanTF{#1}%
{%
\PolToSturm{#5}{#5}%
\PolSturmIsolateZeros**{#5}%
\PolEnsureIntervalLengths{#5}{-#3}%
\IfBooleanF{#2}{\hackNst(#4){#5}}%
}%
{%
\PolGenFloatVariant{#5}%
\PolToSturm{#5}{#5}%
\PolSturmIsolateZeros**{#5}%
\PolEnsureIntervalLengths{#5}{-#3}%
}%
}

\def\smstext{steigt}%
\def\smftext{fällt}
\def\HPtext{Hochpkt.}
\def\TPtext{Tiefpkt.}
\def\SPtext{Terrassenpkt.}
\def\DiffRowtxt{f^{\prime}}
\def\lueckColor#1{\colorlet{lckColor}{#1}}
\lueckColor{BrickRed}
\def\Poltxt{\textcolor{lckColor}{Polstelle}}
\def\Lueckentxt{\textcolor{lckColor}{Def.-Lücke}}
\def\Notdeftxt{\textcolor{lckColor}{\diagup}}

\NewDocumentCommand{\VZTabelle}{sO{f}O{x}O{#21}!d()}{%
\IfValueTF{#5}{%
\PolGCD{#4}{#5}{commonfactorA}%
\poldef erwzaehlerA(x) := (#4(x)#5(x))/(commonfactorA(x))^2 ;%
\poldef gekuerzterNenner(x) := #5(x)/commonfactorA(x) ;%
\PolGCD{erwzaehlerA}{commonfactorA}{commonfactorB}%
\poldef commonfactorC(x) := commonfactorA(x)/commonfactorB(x) ;%
\poldef erwzaehler(x) := erwzaehlerA(x)commonfactorC(x) ;%
}%
{%
\poldef erwzaehler(x) := #4(x) ;%
\poldef commonfactorC(x) := 1 ;%
}%
\PolToSturm{erwzaehler}{erwzaehler}%
\PolSturmIsolateZeros**{erwzaehler}%
\PolEnsureIntervalLengths{erwzaehler}{-9}%
\begin{tabular}{*{\XcalcR{2+2*\PolSturmNbOfIsolatedZeros{erwzaehler}}}{>{$}c<{$}}}
\IfBooleanF{#1}{\toprule}
\IfValueTF{#5}{\Firstrow{erwzaehler}{#3}{#5}}{\Firstrow{erwzaehler}{#3}{1}}
\IfValueTF{#5}{\VZmakerows{erwzaehler}{#5}{#4}{#3}}{\VZmakerows{erwzaehler}{1}{#4}{#3}}
\IfValueTF{#5}{\Diffrow{\DiffRowtxt}{erwzaehler}{#3}{#5}}{\Diffrow{\DiffRowtxt}{erwzaehler}{#3}{1}}
\IfValueTF{#5}{\Graphrow{#2}{erwzaehler}{#5}}{\Graphrow{#2}{erwzaehler}{1}}
\IfBooleanF{#1}{ \\ \bottomrule}
\end{tabular}%
}

\def\nst#1#2{\Xcalc*{\STZeroL{#1}{#2}}}

\def\VZfktwertL#1#2{\xintifSgn{\xinttheexpr #1(\xinttheexpr \STZeroL{#1}{#2}-0.001\relax)\relax}{-}{0}{+}}

\def\VZfktwertR#1#2{\xintifSgn{\xinttheexpr #1(\xinttheexpr \STZeroL{#1}{#2}+0.001\relax)\relax}{-}{0}{+}}

\def\VZfktwert#1#2{\xintifSgn{\xinttheexpr #1(\STZeroL{#1}{#2})\relax}{-}{0}{+}}

\def\tabfactor#1#2#3#4{%
\xintifboolexpr{\STZeroL{#1}{#2}=0}%
{#4}%
{(#4\Xcalc+*{-\STZeroL{#1}{#2}})
\xintifboolexpr{\PolSturmIsolatedZeroMultiplicity{#1}{#2}=1}%
{%
\xintifboolexpr{commonfactorC(\STZeroL{#1}{#2})=0}%
{^{0}}%
{}%
}%
{%
\xintifboolexpr{commonfactorC(\STZeroL{#1}{#2})=0}%
{%
^{0}
}%
{%
^{\PolSturmIsolatedZeroMultiplicity{#1}{#2}}
}%
}%
}%
}

\def\MonotonieL#1#2{\xintifSgn{\xinttheexpr #1(\XcalcR{\STZeroL{#1}{#2}-0.001})\relax}{\text{\smftext}}{0}{\text{\smstext}}}

\def\MonotonieR#1#2{\xintifSgn{\xinttheexpr #1(\XcalcR{\STZeroL{#1}{#2}+0.001})\relax}{\text{\smftext}}{0}{\text{\smstext}}}

\def\Extrema#1#2{\xintifboolexpr{\xinttheexpr (#1(\XcalcR{\STZeroL{#1}{#2}-0.001}))*(#1(\XcalcR{\STZeroL{#1}{#2}+0.001}))\relax >0}%
{\text{\SPtext}}%
{%
\xintifboolexpr{\xinttheexpr #1(\xinttheexpr \STZeroL{#1}{#2}-0.001\relax)\relax>0}%
{\text{\HPtext}}%
{\text{\TPtext}}%
}%
}%

\NewDocumentCommand{\VZtabfac}{st{>}mmm}{%
\IfBooleanTF{#1}%
{\xintifSgn{\xinttheexpr (-\STZeroL{#3}{#4}+\STZeroL{#3}{#5})^\xintifboolexpr{commonfactorC(\STZeroL{#3}{#4})=0}{0}%
{\PolSturmIsolatedZeroMultiplicity{#3}{#4}}\relax}{-}{0}{+}}%
{%
\IfBooleanTF{#2}%
{%
\xintifSgn{\xinttheexpr (-\STZeroL{#3}{#4}+\STZeroL{#3}{#5}+0.001)^\xintifboolexpr{commonfactorC(\STZeroL{#3}{#4})=0}{0}%
{\PolSturmIsolatedZeroMultiplicity{#3}{#4}}\relax}{-}{0}{+}%
}%
{%
\xintifSgn{\xinttheexpr (-\STZeroL{#3}{#4}+\STZeroL{#3}{#5}-0.001)^\xintifboolexpr{commonfactorC(\STZeroL{#3}{#4})=0}{0}%
{\PolSturmIsolatedZeroMultiplicity{#3}{#4}}\relax}{-}{0}{+}%
}%
}%
}

\newcommand{\VZmakerows}[4]{%
{%
\xintFor* ##1 in {\xintSeq{1}{\PolSturmNbOfIsolatedZeros{#1}}}
\do {  & - & - } \\ \midrule
}%
{}%
\xintFor* ##1 in {\xintSeq{1}{\PolSturmNbOfIsolatedZeros{#1}}}
\do
{\tabfactor{#1}{##1}{#3}{#4} & \VZtabfac{#1}{##1}{1}%
\xintFor* ##2 in {\xintSeq{1}{\PolSturmNbOfIsolatedZeros{#1}}}
\do
{  &
\IfDecimal{#2}%
{\VZtabfac*{#1}{##1}{##2}}%
{%
\xintifboolexpr{\xinttheexpr #2(\STZeroL{#1}{##2})\relax = 0}%
{\Notdeftxt}
{\VZtabfac*{#1}{##1}{##2}}%
}%
&   \VZtabfac>{#1}{##1}{##2}
}
\\ \midrule
}
}

\newcommand{\Firstrow}[3]{%
#2 & -\infty<#2<\nst{#1}{1} & \IfDecimal{#3}{#2=\nst{#1}{1}}%
{\xintifboolexpr{\xinttheexpr #3(\STZeroL{#1}{1})\relax = 0 }%
{\textcolor{lckColor}{#2=\nst{#1}{1}}}%
{#2=\nst{#1}{1}}%
}%
\xintifboolexpr{\PolSturmNbOfIsolatedZeros{#1}>1}{%
\xintFor* ##1 in {\xintSeq{1}{\PolSturmNbOfIsolatedZeros{#1}-1}}
\do
{%
& \nst{#1}{\xinttheexpr ##1\relax}<#2<\nst{#1}{\xinttheexpr ##1+1\relax} &
\IfDecimal{#3}%
{#2=\nst{#1}{\xinttheexpr ##1+1\relax}}%
{\xintifboolexpr{\xinttheexpr #3(\STZeroL{#1}{\xinttheexpr ##1+1\relax})\relax = 0 }%
{\textcolor{lckColor}{#2=\nst{#1}{\xinttheexpr ##1+1\relax}}}%
{#2=\nst{#1}{\xinttheexpr ##1+1\relax}}%
}%
}%
}%
{}%
& \nst{#1}{\PolSturmNbOfIsolatedZeros{#1}}<#2<+\infty\\ \midrule
}

\NewDocumentCommand{\Diffrow}{mmmm}{%
#1(#3)
\xintFor* ##1 in {\xintSeq{1}{\PolSturmNbOfIsolatedZeros{#2}}}
\do
{& \VZfktwertL{#2}{##1} &
\IfDecimal{#4}%
{\VZfktwert{#2}{##1}}%
{%
\xintifboolexpr{\xinttheexpr #4(\STZeroL{#2}{##1})\relax = 0}%
{\Notdeftxt}
{\VZfktwert{#2}{##1}}%
}%
}%
& \VZfktwertR{#2}{\PolSturmNbOfIsolatedZeros{#2}} \\ \midrule
}

\newcommand{\Graphrow}[3]{%
\text{G}_{#1}
\xintFor* ##1 in {\xintSeq{1}{\PolSturmNbOfIsolatedZeros{#2}}}
\do
{& \MonotonieL{#2}{##1} & \IfDecimal{#3}{\Extrema{#2}{##1}}{%
\xintifboolexpr{\xinttheexpr #3(\STZeroL{#2}{##1})\relax = 0}%
{%
\xintifboolexpr{\xinttheexpr gekuerzterNenner(\STZeroL{#2}{##1})\relax =0}%
{\text{\Poltxt}}
{\text{\Lueckentxt}}
}%
{\Extrema{#2}{##1}}%
}%
}%
& \MonotonieR{#2}{\PolSturmNbOfIsolatedZeros{#2}}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Begin of code for factorization %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Counter for LOOP over the roots of f
\newcount\zeroCount
% Set counter to 1
\zeroCount=1

% Proof if a root is "0" then only write x and not (x-0) ...
% factor the roots like (x-x_1) if x_1>0, (x+x_1) if x_1<0
\newcommand{\factorZeros}[1]{%
\xintifZero{\PolSturmIsolatedZeroLeft{#1}{\the\zeroCount}}%
{\varname}
{\left(\varname\xintiiifSgn{\PolSturmIsolatedZeroLeft{#1}{\the\zeroCount}}{+}{-}{-}
\xintSignedFrac{\xintIrr{\xintAbs{\PolSturmIsolatedZeroLeft{#1}{\the\zeroCount}}}}\right)
}
}

% Don't write multiplicity of a root in case it is =1
\newcommand{\ignoreMultiplicityOne}[1]{%
\xintifOne{\PolSturmIsolatedZeroMultiplicity{#1}{\the\zeroCount}}{}{\PolSturmIsolatedZeroMultiplicity{#1}{\the\zeroCount}}
}

% Hide leading coefficient if leading coefficient is + or - 1.
}

% Typeset polynomial as factors of its rational roots: f(x)=a_n(x-x_1)(x-x_2)...(x-x_n)(quotient function)
\newcommand{\typesetFactors}[2][x]{%
\def\varname{#1}%
% #1 = function
\PolToSturm{#2}{#2}%
\PolSturmIsolateZeros**{#2}%
\xintifboolexpr{\PolDegree{#2}<2}{\xintifboolexpr{\PolDegree{#2}<1}{\PolTypeset[\varname]{#2}}{\left(\PolTypeset[\varname]{#2}\right)}}{%
\xintifboolexpr{\PolDegree{#2}=\PolDegree{#2_norr}}{\PolTypeset[\varname]{#2}}{%
\poldef #2_rat(x) := #2(x)/#2_norr(x);
\PolToSturm{#2_rat}{#2_rat}%
\PolSturmIsolateZeros**{#2_rat}%
%
% Loop over all rational zeros of the function f = #2 ;  #2_rat is the part with only rational zeros
% #2_rat is defined as #2(x)/#2_norr(x), and #2_norr is the part of #2 with no rational roots (square-free version is #2_irr )
\loop
\factorZeros{#2_rat}^{\ignoreMultiplicityOne{#2_rat}}%
\ifnum \zeroCount<\xinttheexpr\PolSturmNbOfIsolatedZeros{#2_rat}+1\relax
\repeat
\xintifZero{\PolDegree{#2_norr}}%
{}%
{\left(\PolTypeset[\varname]{#2_norr_VZ}\right)}%
}}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% End of code for factorization %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def\smstext{$\nearrow$}
\def\smftext{$\searrow$}
\def\HPtext{H}
\def\TPtext{T}
\def\SPtext{Ter.}
\def\DiffRowtxt{f^{\prime}}
\def\Poltxt{\textcolor{lckColor}{Pol}}
\def\Lueckentxt{\textcolor{lckColor}{Loch}}

\begin{document}

\poldef zf1(x):=(-1/4)(x^2-4x+3)(x-2)^2(x^2+1)(x^2+2);
\PolReduceCoeffs{zf1}
Given is the derivative:
$f^{\prime}:t \mapsto \PolTypeset[t]{zf1} = \typesetFactors[t]{zf1}$

\medskip
\renewcommand{\arraystretch}{1.2}%
\VZTabelle[f][t][zf1]
\bigskip

\poldef zf1(x):=(x^2-4x+3)*(x-2);
\PolReduceCoeffs{zf1}
\poldef nf1(x):=(x^2+1)(x-2)^2;
\PolReduceCoeffs{nf1}
Given is the derivative:
$f^{\prime}:x \mapsto \frac{\PolTypeset{zf1}}{\PolTypeset{nf1}} = \frac{\typesetFactors{zf1}}{\typesetFactors{nf1}}$

\medskip
\renewcommand{\arraystretch}{1.2}%
\VZTabelle[f][x][zf1](nf1)

\end{document}


• (+1) Thank you for your problem expansion. But truly I don't understand anything. hihi :-)) – Trong Vuong Dec 6 '18 at 8:32
• very impressive but you seem to be using some development version of polexpr which finds rational roots as current version 0.6 does not have the double starred \PolSturmIsolateZeros**.... I am very jealous! – user4686 Dec 6 '18 at 9:51
• @jfbu yes, you are right. I actually forgot that. – user139826 Dec 6 '18 at 11:17
• I will make my best to ping the polexpr author to make soon a release of dev version.... – user4686 Dec 6 '18 at 13:41
• The code has been adapted to the new syntax of polexpr 0.7, which will appear shortly on ctan. Many thanks to the diligent author of polexpr. – user139826 Dec 8 '18 at 21:49