Précision des calculs avec tikzmaths

Bonjour,
Les nombres calculés avec tikzmath s'arrêtent à la sixième décimale. L'un d'entre vous connaîtrait-il le moyen d'augmenter cette précision ?
(J'utilise la librarie tikzmath, je fais une image animée sur le nombre dérivé, avec affichage du taux qui tend vers le nombre dérivé, j'aimerais aller plus loin que 0,000006...)
cb

Réponses

  • Tu peux te renseigner sur la FPU de PGF (Floating Point Unit Library dans le manuel). Le package xfp permet également de faire des calculs assez précis, et de manière développable (avec \fpeval). Après, il faut interfacer ces outils avec ton code...

    Il y a un exemple traité avec les deux techniques ici (TeX.SE).
  • Une autre piste : Sagetex.
  • Merci pour les pistes, je vais regarder ca
  • Ca n'a pas l'air simple de de faire fonction pgf/fpu et tikz, beaucoup d'incompatibilité....
    Surtout que je viens de découvrir les incompatibilités entre French Babel et Tikz.
    Je vais voir avec SageTex, même si la distribution n'est pas incluse sur Overleaf.
    Je suis preneur d'autre solution, s'il y en a.
    cb
  • Bien sûr, Sagetex ne marche pas s'il n'y a pas Sage quelque part sur l'ordinateur.

    La façon dont je procéderais, ce serait de faire les calculs sur un script à part (Python ou, dans mon cas, Sage...) et stocker des listes de points dans des fichiers tex annexes.

    Si tu décrivais plus précisément ce que tu veux faire ou si tu postais ta figure imparfaite en précisant ce que tu veux améliorer, on pourrait participer.
  • Voilà le fichier,
    Une animation classique pour l'approche de la limite du taux de variation et la dérivabilité. Mais le h bloque sur 0,00006 sur les dernières images, j'aimerais descendre au moins jusqu'a 10^(-9) voir plus...
    CB
  • Merci pour le code.

    Pour $h$ assez petit, il me semble qu'on peut éviter de faire un calcul avec toutes les décimales. Côté graphique, pas la peine de se casser la tête : la corde est indiscernable de la tangente pour $h\le1/100$. Côté numérique à droite, pour $h=k\cdot10^{-d}$, il est plus facile d'écrire $3{,}$ puis le bon nombre de $0$ (i.e. $d-1$ ou $d-2$) et enfin $3k$.

    (OK, c'est un contournement qui conduit à du bricolage... Pas complètement convainquant.)
  • Voila un essai avec luaLaTeX.
    J'ai commenté la partie qui donne l'animation parce que je ne sais pas comment ça marche.
    J'ai aussi réécrit certains morceaux que je trouvais maladroits.
    J'enlève le code, parce que le forum a l'air de ne pas l'aimer.
    Je ne sais pas si l'animation marche parce que je n'ai pas de lecteur pdf qui sache faire ça.91232
  • @laulite

    Je n'ai pas le temps d'analyser en détail mais je fais confiance à Math Coss pour les ordres de grandeur. Je ne peux pas non plus tester le code tel quel (avec l'option dvisvgm passée à \documentclass) car j'ai une erreur bizarre au chargement d'animate.sty :
    /usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty:95: LaTeX3 Error: Backend configuration already set.
    
    For immediate help type H <return>.
     ...                                              
                                                      
    l.95 \keys_set:nV { sys } \l__expl_options_clist
    
    Je pense que c'est un bug récemment introduit (raisons : 1) message d'erreur qui a l'air récent et 2) j'ai la même erreur avec cet exemple, or il me semble que je pouvais le compiler il y a quelques mois).

    Bref. Tout ça pour dire que si le seul problème est la précision des calculs dans \tikzmath{...} (autrement dit, assure-toi d'abord que tu ne réclames pas quelque chose d'inutile ou délirant :-)), ceci devrait aider :
    \documentclass ...
    \usetikzlibrary{math,fpu}
    
    ...
    
    \pgfkeys{/pgf/fpu=true}
    \tikzmath{...}
    \pgfkeys{/pgf/fpu=false}
    
    \draw ...
    
    Non testé, évidemment.

    Edit : j'ai oublié un ingrédient important. Quand la fpu de pgfmath est active, les résultats sont dans un format spécial qui revient à un triplet composé de drapeaux (nul, positif, négatif, Nan, $+\infty$, $-\infty$), d'une mantisse et d'un exposant. Or les fonctions de tracé de TikZ ne supportent pas ce format, il faut donc convertir sous forme d'une bête écriture décimale (format 'fixed' dans la terminologie de la bibliothèque fpu) avant d'utiliser les résultats avec des fonctions de tracé. Je vais montrer comment faire dans le message suivant.

    On peut aussi raccourcir \pgfkeys{/pgf/fpu=true} en \pgfset{fpu=true}.
  • @laulite

    Je retire le code de l'animation (que je ne peux pas compiler) et te fabrique un exemple complet avec une image au choix (ici, par exemple, j'ai mis \def\n{20} ce qui, peut-être à une unité près, revient à la plus grande valeur de \n dans ta boucle). Puisque tu te souciais de problèmes de compatibilité entre TikZ et babel/french, j'ajoute le code standard pour gérer cela, bien que ça n'intervienne pas ici. Si \usetikzlibrary{babel} provoque une erreur, c'est sans doute que la distribution TeX est trop vieille (installer une vraie distro, pas Overleaf).

    Si tu as une distro à jour, normalement tu n'as plus qu'à remettre ton animate et ça devrait rouler. Tu peux vérifier que le même code en enlevant :
      \pgfset{fpu=true}
    
    et
      \pgfset{fpu=false}
      \clistMapInline{\a,\xA,\yA,\xB,\yB,\xC,\yC,\xM,\yM,\h,\xh}
        { \convertResultToFixedFormat{#1} }
    
    provoque une erreur telle que :
    ./docu.tex:42: Dimension too large.
    <recently read> \pgfmath@xa 
    
    Voici donc l'exemple complet, avec une image au choix définie par \n :
    \documentclass[french]{article}
    \usepackage{babel}
    \usepackage{amsmath}
    \usepackage{tikz}
    \usepackage{expl3}
    \usetikzlibrary{babel,fpu,math}
    
    \ExplSyntaxOn
    \cs_set_eq:NN \clistMapInline \clist_map_inline:nn
    \ExplSyntaxOff
    
    \newcommand*{\convertResultToFixedFormat}[1]{%
      \pgfmathfloattofixed{#1}%
      \let#1\pgfmathresult
    }
    
    \begin{document}
    
    \begin{tikzpicture}[xscale=1.7, yscale=0.7]
      \def\n{20}                    % par exemple
      \pgfset{fpu=true}
    
      \tikzmath{
        function g(\x)
        {
          return 2*\x+1;
        };
    %
        \y=g(3);
        \xA=1;
        \yA=(\xA)^3+1;
        \h=1/1.1^((\n)^2);
        \xM=\xA+\h;
        \yM=(\xM)^3+1;
        \xh=(\xA+\xM)/2;
        \e=0.25;
        \xB=\xA-2*\e;
        \a=3*(\xA)^2+\h*(\xA+2)+(\h)^2;
        \yB=\yA+\a*(\xB-\xA);
        \xC=\xA+1+\e;
        \yC=\yA+\a*(\xC-\xA);
        \y=10^(-\n);
      }
    
      \pgfset{fpu=false}
      \clistMapInline{\a,\xA,\yA,\xB,\yB,\xC,\yC,\xM,\yM,\h,\xh}
        { \convertResultToFixedFormat{#1} }
    
      \draw[->,color=black] (-1.5,0) -- (6,0);
      \draw[->,color=black] (0,-2) -- (0,11.5);
      \draw[domain=-1:2.1, color=blue, smooth,line width=0.5mm, line cap=butt] plot(\x,{\x*\x*\x+1});
      \draw(-1,0) [ color=blue] node[above]{{\boldmath $\mathcal{C}_f$}};
      \coordinate(B) at (\xB,\yB) node at (B) {};
      \coordinate(C) at (\xC,\yC) node at (C) {};
      \draw[ color=red,line width=0.5mm, line cap=butt](B)--(C);
      \draw[ color=red] (\xA,0) node[below] {$a$};
      \draw[ color=red] (0,\yA) node[ left] {$f(a)$};
      \draw[ color=red,loosely dashed] (\xA,0)--(\xA,\yA);
      \draw[ color=red,loosely dashed] (0,\yA)--(\xA,\yA);
      \draw[ color=red,fill=red] (\xM,0) node[below right] {$a+h$};
      \draw[ color=red,fill=red] (0,\yM) node[above left] {$f(a+h)$};
      \draw[ color=red,loosely dashed] (\xM,0)--(\xM,\yM);
      \draw[ color=red,loosely dashed] (0,\yM)--(\xM,\yM);
      \draw[ color=red, ->] (\xA,0.2)--(\xM,0.2);
      \draw (\xh,0.2) [ color=red,above] node{$h$};
      \coordinate(A) at (\xA,\yA) node[ color=red] at(A) {$\bullet$} node[ color=red,above left] at (A) {$A$};
      \coordinate(M) at (\xM,\yM) node[ color=red] at(M) {$\bullet$} node[ color=red,right] at (M) {$M$};
      \draw (2.5,10) node [ right]{$n=\n$};
      \draw (2.5,8) node [ right]{$f:x \mapsto x^3+1$};
      \draw (2.5,6) node [ right]{$a=1$};
      \draw (2.5,4) node [ right]{$h=\h$};
      \draw (2.5,1.5) node[ right] {$\dfrac{f(1+h)-f(1)}{h}=\a$};
    \end{tikzpicture}
    
    \end{document}
    
    (Les espaces après de nombreux crochets ouvrants servent à éviter une mauvaise interprétation par le logiciel du forum.)

    Pour l'implémentation de ma macro \convertResultToFixedFormat, on pourrait aussi utiliser \pgfset{fpu/output format=fixed} et \pgfmathsetmacro comme ici, mais je pense que ma technique est (un peu) plus rapide.

    Note : tu peux obtenir un joli formatage des nombres dans ta « légende » en utilisant \pgfmathprintnumber. C'est très paramétrable(*). Exemple simple : remplace la fin du document précédent par ceci :
      % Pour le formatage des nombres par \pgfmathprintnumber
      \pgfset{number format/precision=5}
      \draw (2.5,10) node [ right]{$n = \pgfmathprintnumber{\n}$};
      \draw (2.5,8) node [ right]{$f\colon x \longmapsto x^3+1$};
      \draw (2.5,6) node [ right]{$a = \pgfmathprintnumber{1}$};
      \draw (2.5,4) node [ right]{$h = \pgfmathprintnumber{\h}$};
      \draw (2.5,1.5) node[ right]
        {$\dfrac{f(1+h)-f(1)}{h} = \pgfmathprintnumber{\a}$};
    \end{tikzpicture}
    
    \end{document}
    
    (*) Exemple sympathique tiré du manuel de TikZ & PGF :
    \pgfkeys{
      /pgf/number format/.cd,
      sci,
      sci generic={mantissa sep=\times,exponent={10^{#1}}}}
    \pgfmathprintnumber{12.345};
    \pgfmathprintnumber{0.00012345}
    

    Edits : 1) j'avais oublié de convertir \a. 2) Compléments avec notamment \pgfmathprintnumber.91248
    91242
  • @marsup,
    merci beaucoup pour ton code, le résultat est vraiment convaincant. Par contre j'ai une erreur TIKZ à la compilation "Did you forgot a semicolon", je regarderai ça en détail plus tard.
    Je retiens aussi les améliorations du code qui sont effectivement judicieuse, je ne connaissais pas.

    @brian
    merci pour ton travail aussi, et pour les conseils enrichissants.
    CB
  • J'ai réessayé avec l'animation :
    • l'erreur “LaTeX3 Error: Backend configuration already set.” disparaît si j'omets l'option 'dvisvgm' dans l'appel à \documentclass (je l'avais mise après avoir lu la doc d'animate, peut-être que j'ai mal compris...) ;
    • il y a effectivement un problème entre \tikzmath et babel/french : \tikzmath ne reconnaît pas les « ; » terminant une instruction car babel/french les rend actifs.
    Donc en retirant l'option 'dvisvgm' dans l'appel à \documentclass, en ajoutant
    \shorthandoff{;}
    
    avant \begin{animateinline}[controls]{2} et
    \shorthandon{;}
    
    après \end{animateinline}, je peux compiler avec LaTeX. S'il y a des points-virgules dans la figure qui doivent être gérés par babel/french, à cause du \shorthandoff{;}, il faut alors explicitement appeler la commande « ; » de babel/french. Pour cela, avant le \shorthandoff{;}, on peut mettre :
    \let\pointVirgule ;
    
    et utiliser \pointVirgule{} dans la figure aux endroits où l'on veut un point-virgule géré par babel/french.

    Avec ces changements, la compilation avec 'latex' fonctionne pour moi, en revanche l'étape suivante avec GhostScript ne marche pas :
    dvisvgm --font-format=woff --exact --zoom=-1 anim.dvi
    pre-processing DVI file (format version 2)
    
     *** WARNING - you have selected SAFER, indicating you want Ghostscript
    
    (...)
    
               processing page 1
      PostScript error: undefined in get
      Operand stack:
          --nostringval--  --nostringval--  --nostringval--  --nostringval--  --nost
      ringval--  --nostringval--  1  1  --nostringval--  .setopacityalpha
    
    Voici l'exemple complet avec ces petites modifications :
    \documentclass[11pt,a4paper,french]{article}
    \usepackage{babel}
    \usepackage{amsmath}
    \usepackage{expl3}
    \usepackage{animate}
    \usepackage{tikz}
    \usetikzlibrary{babel,math,fpu}
    
    \ExplSyntaxOn
    \cs_set_eq:NN \clistMapInline \clist_map_inline:nn
    \ExplSyntaxOff
    
    \newcommand*{\convertResultToFixedFormat}[1]{%
      \pgfmathfloattofixed{#1}%
      \let#1\pgfmathresult
    }
    
    \pagestyle{empty}
    
    \begin{document}
    
    \let\pointVirgule ;% sauvegarde de la commande point-virgule de babel/french
    \shorthandoff{;}
    \begin{animateinline}[controls]{2}
    \multiframe{20}{n=0+1}{%
      \begin{tikzpicture}[xscale=1.7, yscale=0.7]
        \pgfset{fpu=true}
    
        \tikzmath{
          function g(\x)
          {
            return 2*\x+1;
          };
          %
          \y=g(3);
          \xA=1;
          \yA=(\xA)^3+1;
          \h=1/1.1^((\n)^2);
          \xM=\xA+\h;
          \yM=(\xM)^3+1;
          \xh=(\xA+\xM)/2;
          \e=0.25;
          \xB=\xA-2*\e;
          \a=3*(\xA)^2+\h*(\xA+2)+(\h)^2;
          \yB=\yA+\a*(\xB-\xA);
          \xC=\xA+1+\e;
          \yC=\yA+\a*(\xC-\xA);
          \y=10^(-\n);
        }
    
        \pgfset{fpu=false}
        \clistMapInline{\a,\xA,\yA,\xB,\yB,\xC,\yC,\xM,\yM,\h,\xh}
          { \convertResultToFixedFormat{#1} }
    
        \draw[->,color=black] (-1.5,0) -- (6,0);
        \draw[->,color=black] (0,-2) -- (0,11.5);
        \draw[domain=-1:2.1, color=blue, smooth,line width=0.5mm, line cap=butt] plot(\x,{\x*\x*\x+1});
        \draw(-1,0) [ color=blue] node[above]{{\boldmath $\mathcal{C}_f$}};
        \coordinate(B) at (\xB,\yB) node at (B) {};
        \coordinate(C) at (\xC,\yC) node at (C) {};
        \draw[ color=red,line width=0.5mm, line cap=butt](B)--(C);
        \draw[ color=red] (\xA,0) node[below] {$a$};
        \draw[ color=red] (0,\yA) node[ left] {$f(a)$};
        \draw[ color=red,loosely dashed] (\xA,0)--(\xA,\yA);
        \draw[ color=red,loosely dashed] (0,\yA)--(\xA,\yA);
        \draw[ color=red,fill=red] (\xM,0) node[below right] {$a+h$};
        \draw[ color=red,fill=red] (0,\yM) node[above left] {$f(a+h)$};
        \draw[ color=red,loosely dashed] (\xM,0)--(\xM,\yM);
        \draw[ color=red,loosely dashed] (0,\yM)--(\xM,\yM);
        \draw[ color=red, ->] (\xA,0.2)--(\xM,0.2);
        \draw (\xh,0.2) [ color=red,above] node{$h$};
        \coordinate(A) at (\xA,\yA) node[ color=red] at(A) {$\bullet$} node[ color=red,above left] at (A) {$A$};
        \coordinate(M) at (\xM,\yM) node[ color=red] at(M) {$\bullet$} node[ color=red,right] at (M) {$M$};
        % Pour le formatage des nombres par \pgfmathprintnumber
        \pgfset{number format/precision=5}
        \draw (2.5,10) node [ right]{$n = \pgfmathprintnumber{\n}$};
        \draw (2.5,8) node [ right]{$f\colon x \longmapsto x^3+1$};
        \draw (2.5,6) node [ right]{$a = \pgfmathprintnumber{1}$};
        \draw (2.5,4) node [ right]{$h = \pgfmathprintnumber{\h}$};
        \draw (2.5,1.5) node[ right]
          {$\dfrac{f(1+h)-f(1)}{h} = \pgfmathprintnumber{\a}$};
      \end{tikzpicture}%
    }
    \end{animateinline}
    \shorthandon{;}
    
    \end{document}
    
  • Bonjour,
    J'ai travaillé avec la solution de marsup qui offre plus de décimal (luatatex). J'ai viré un boldmath qui faisait une erreur, le résultat est ce que j'espérais, merci beaucoup.
    J'ai enlevé le package babel pour éviter les problèmes de conflit. Bizarrement je n'ai pas de problème d'accent, même sans french babel.
    Pour ma part j'utilise la police arev, elle est sans empattement, pour les dyslexiques c'est mieux et pour les autres aussi, elle est très lisible. Elle est aussi pensée pour la vidéo projection, légèrement plus grande donc lisible en projection en 12pt, ce qui permet aussi d'imprimer 2 feuilles sur un A4 en gardant la lisibilité, très pratique cette police.
    Overleaf me convient, je me lance rarement dans des trucs trop pointus alors c'est vraiment efficace et je peux bosser partout et en collaboration avec mes collègues. Et puis il a compilé le code sans problème, donc ce n'est pas si mal.
    En tout cas c'était très instructif de lire vos codes, merci encore.
    Christophe
  • Les conseils de brian sur le formatage des nombres avec `\pgfmathprintnumber` me semblent très intéressants à suivre pour cette application.
  • Content que ça marche.

    @laulite

    Si ton document ne contient que cette animation, c'est sûr que l'absence de babel ne va pas beaucoup se remarquer. Tu dis que les accents fonctionnent, mais détaillons un peu :
    • LaTeX utilise UTF-8 comme codage d'entrée par défaut depuis quelques années, donc par exemple un « é » en UTF-8 dans le fichier .tex revient à entrer \'e sans que tu n'aies rien à faire, du moment que tu ne charges pas 'inputenc' avec un autre codage ;
    • mais si tu n'as pas la combinaison babel/french + \usepackage[T1]{fontenc}, les mots ne seront pas coupés correctement en fin de ligne pour le français ;
    • sans babel/french, l'espace précédant la double ponctuation (:;?!) ne sera pas automatique (ce qui est possible mais non imposé avec babel/french) et surtout sera une espace intermot sécable (donc en particulier, tu peux te retrouver avec ces signes de ponctuation en début de ligne sans avoir rien demandé...).
    Edit : les deux premiers points ne sont pas applicables tels quels à LuaTeX et XeTeX (sauf erreur, ils utilisent toujours UTF-8 en entrée et Unicode par défaut en sortie, via fontspec en lieu et place de fontenc). Mais une moitié du deuxième point doit s'appliquer, celle qui dit que sans babel (ou un package du même genre tel que polyglossia), les motifs de coupure de mots chargés (hyphenation patterns) seront ceux de l'anglais.

    Il y a bien-sûr d'autres choses que babel/french change, comme par exemple :
    • les mots ou expressions du genre Table des matières, Chapitre, Figure, Table ;
    • le formatage des listes (itemize...) ;
    • etc.
Connectez-vous ou Inscrivez-vous pour répondre.