Tracer des fonctions "compliquées" en tex
Bonjour à tous
Je cherche à tracer en tex des fonctions ayant des définitions "compliquées". Il y a en particulier deux fonctions auxquelles je m'intéresse:
1) La fonction $\varphi: t \mapsto \sum\limits_{n=1}^{+ \infty} \frac{(-1)^n \cos (2^n t)}{2^n}$.
2) La fonction de Thomae : elle vaut $0$ sur les irrationnels et $\frac{1}{q}$ en $x = \frac{p}{q}$, où $\frac{p}{q}$ est la représentation irréductible de $x$ lorsque $x$ est rationnel.
Quelqu'un sait-il comment faire cela de façon simple en tex (il est par exemple hors de question de tracer des points un par un pour la seconde fonction, ni d'écrire une par une les fonctions à sommer jusqu'à un nombre assez grand pour la première fonction) ?
Je vous remercie d'avance pour votre aide !
Réponses
-
Bonjour,J'aurais justement attaqué le problème par ce que tu qualifies de "hors de question". Je connais mal le tracé de fonctions en tex mais j'imagine qu'il fonctionne plus ou moins comme Matplotlib en Python (au pire, fais ton graphique en Python et insère la figure en Tex qui va avec). Dans ce cas, l'outil trace bien la fonction point par point. Pour ces 2 fonctions, un calcul point par point ne me semble pas du tout délirant, je m'explique :1) La somme converge relativement vite, tu peux majorer la valeur absolue du reste par $\frac{1}{2^n}$. Tu auras donc juste besoin des 20 premiers termes pour avoir une précision à $10^{-6}$ : c'est tout à fait gérable pour un ordi.2) Ici, tu peux tracer ta fonction en plaçant directement les points $(p/q,1/q)$ sur ton graphique. Il faut donc une manière d'énumérer un bon nombre de rationnels, par exemple pour $1 \leqslant p \leqslant q \leqslant N$ (la fonction est 1-périodique). La densité ne sera pas uniforme mais, pour $N$ assez grand, ça ne se verra pas sur le graphique. Inutile de tracer ta fonction sur les irrationnels, tu verras la fonction nulle se dessiner sous ton nuage de points rationnels automatiquement.
-
Bonjour,
Peut-être qu'avec une boucle du style "\foreach \i in {0,1,...,3}{+(-1)^\i * cos(2^\i*\x)/2^\i }" on peut faire calculer la somme par LaTeX. Mais je ne sais pas comment le mettre en pratique (ni si ça peut marcher). -
Pour ce genre de fonctions je crois qu'il vaut mieux importer un pdf tracé avec un logiciel dédié, par ex. Sage.
-
Le problème d'importer des images d'autres logiciels c'est de se retrouver avec des polices de caractères différentes. Ca fait bien moche.
-
Ce que je fais quand j'ai des fonctions un peu compliquées à tracer : je fais les calculs avec Sage ou Python, ou Maple. J'exporte la liste des coordonnées des points dans un fichier, et ensuite, j'utilise tikz pour faire le graphique et l'intégrer dans mon document LaTeX (on peut lui dire de tracer une courbe passant par les points listés dans un fichier externe).
-
Sage est capable de mettre des textes dans la polices standard de LaTeX. Sinon on peut faire une figure sans texte et les mettre après dans un environnement tikz.
-
Joaopa a dit :Le problème d'importer des images d'autres logiciels c'est de se retrouver avec des polices de caractères différentes. Ca fait bien moche.
-
Merci pour vos réponses !J'ai déjà les tracés des figures dans d'autres logiciels, mais je cherche à les reproduire en tex pour avoir un document assez "self contained", et de plus, comme l'a dit @Joaopa , je me retrouve souvent avec des polices différentes ou des caractères plus gros que dans le document tex (et c'est alors toujours un bazar pour trouver le bon "scale" pour remettre les caractères de la figure à la taille exacte.Est-ce qu'il existe une instruction "somme" pour pouvoir sommer des fonctions de 1 à un certain nombre sans avoir à les écrire une par une à la main?
-
adrien2019 a dit :Est-ce qu'il existe une instruction "somme" pour pouvoir sommer des fonctions de 1 à un certain nombre sans avoir à les écrire une par une à la main?Oui avec l'instruction Sum de pstricks-add\Sum( <index name>,<start>,<step>,<end>,<function> )soit ici pour tracer entre -10 et 10\psplot{-10}{10}{Sum(i,1,10,(-1)^i*cos(x*2^i)/(2^i)}
-
Exemple : le fichier python
import numpy as np import matplotlib.pyplot as plt import seaborn as sns sns.set_style("darkgrid") plt.ion() def f(x : float) -> float: """ Paramètre --------- x : réel Résultat -------- y : réel Valeur approchée de sum (-1)**n*cos(2**n*x)/2**n """ y = sum((-1)**n*np.cos(2**n*x)/2**n for n in range(1, 50)) return y plt.figure("Graphe", figsize = [6.4, 4.8]) X = np.linspace(-np.pi, np.pi, 1 + 2**10) Y = f(X) plt.plot(X, Y, color = 'C0', label = r'$y = \sum_{n = 1}^{+\infty}\frac{(-1)^{n}\cos\left(2^{n}x\right)}{2^{n}}$') plt.xlim(-np.pi, np.pi) plt.ylim(-0.5, 1) plt.legend() plt.savefig('graphe.pgf', bbox_inches = 'tight')
Insertion dans un fichier tex (ici pour produire une figure autonome au format pdf avec lualatex et des polices personnalisées) :
\documentclass[12pt]{standalone} \usepackage{tikz, xcolor, fontspec, fouriernc} \setsansfont[Scale = 0.92]{texgyreschola} \begin{document} \input{graphe.pgf} \end{document}
-
Un exemple de ce que je pourrais faire (avec une autre fonction) :code python :
import math f=open("fichier.txt","w") for i in range(100): x=-1.1+2.2*i/100 y=math.erf(x) f.write(str(x)+"\t"+str(y)+"\n") f.close()
Et ensuite, on fait un joli graphique avec tikz :\begin{center} \definecolor{gris}{rgb}{0.75,0.75,0.75} \begin{tikzpicture}[x=4.0cm,y=4.0cm] % Quadrillage \draw[color=gris,dash pattern=on 2pt off 2pt, xstep=2.0cm,ystep=2.0cm] (-1.1,-1.1) grid (1.1,1.1); % Axes \draw[->,color=black] (-1.1,0) -- (1.1,0); \foreach \x in {-1,-0.5,0.5,1}<br>\draw[shift={(\x,0)},color=black] (0pt,2pt) -- (0pt,-2pt) node[below] {\footnotesize $\x$}; \draw[->,color=black] (0,-1.1) -- (0,1.1); \foreach \y in {-1,-0.5,0.5,1}<br>\draw[shift={(0,\y)},color=black] (2pt,0pt) -- (-2pt,0pt) node[left] {\footnotesize $\y$}; \draw[color=black] (0pt,-10pt) node[right] {\footnotesize $0$}; % Graphique \draw[color=red, smooth] plot file {fichier.txt}; % Légende \draw[color=red] (0.5,0.6) node[rotate=40, scale=0.8]{$y=erf(x)$}; \end{tikzpicture} \end{center}
Ce qui donne le résultat en pièce jointeÉdit : je ne comprends pas pourquoi à chaque fois que je poste du code, ça me met tout sur une seule ligne.
Édit 2 : merci Math Coss -
Astuce : cliquer sur le bouton < / > (tout à droite de la barre d'outils) avant de copier-coller entre les balises "code", de sorte que les retours chariot soient pris littéralement et pas transformés en balises "br". Exemple :
import math f=open("fichier.txt","w") for i in range(100): x=-1.1+2.2*i/100 y=math.erf(x) f.write(str(x)+"\t"+str(y)+"\n") f.close()<br>
et...\begin{center} \definecolor{gris}{rgb}{0.75,0.75,0.75} \begin{tikzpicture}[x=4.0cm,y=4.0cm] % Quadrillage \draw [color=gris,dash pattern=on 2pt off 2pt, xstep=2.0cm,ystep=2.0cm] (-1.1,-1.1) grid (1.1,1.1); % Axes \draw[->,color=black] (-1.1,0) -- (1.1,0); \foreach \x in {-1,-0.5,0.5,1} \draw[shift={(\x,0)},color=black] (0pt,2pt) -- (0pt,-2pt) node[below] {\footnotesize $\x$}; \draw[->,color=black] (0,-1.1) -- (0,1.1); \foreach \y in {-1,-0.5,0.5,1} \draw[shift={(0,\y)},color=black] (2pt,0pt) -- (-2pt,0pt) node[left] {\footnotesize $\y$}; \draw[color=black] (0pt,-10pt) node[right] {\footnotesize $0$}; \clip(-1.1,-1.1) rectangle (1.1,1.1); % Graphique \draw[color=red, smooth] plot file {fichier.txt}; % Légende \draw[color=red] (0.5,0.6) node[rotate=40, scale=0.8]{$y=erf(x)$}; \end{tikzpicture} \end{center}
-
Vu que notre ami @adrien2019 ne précise pas quel $\TeX$ il utilise, je propose (pour la postérité) une réponse à la fois simple, rapide et efficace à l'aide de ConTeXt et MetaPost (adaptable assez facilement en LaTeX pour ceux qui utilisent lua(la)tex):
\startTEXpage \startluacode function MP.phi(t) total = 0.0 for n=1,32 do total = total + (-1)^n*math.cos(2^n*t)/2^n end return total end \stopluacode \startMPcode begingroup ; vardef phi(expr t) = MP.phi(t) enddef ; draw function(1, "x", "phi(x)", 0, 10, .001) ; endgroup ; \stopMPcode \stopTEXpage
où function s'utilise comme suit:function(1, "x", "f(x)", XMIN, XMAX, STEP)
Pour plus de détails, voir page 238 et suivantes dans le manuel MetaFun.De plus, pour peu que soit utilisé ConTeXt LMTX ou luameta(la)tex, il est possible de rendre le tout encore plus "simple" (en quelque sorte car la grande force de luametafun est surtout de permettre la réalisation de différentes sortes de graphes: 2D, 3D, histogrammes, surfaces... voir dans le manuel dont le lien est plus bas):\startTEXpage \startluacode function MP.phi(t) total = 0.0 for n=1,32 do total = total + (-1)^n*math.cos(2^n*t)/2^n end return total end \stopluacode \startMPcode draw lmt_function [ xmin = 0, xmax = 10, xstep = .001, ymin = -1, ymax = 1, code = "MP.phi(x)", ]; \stopMPcode \stopTEXpage
-
MetaFun, c'est le fun ?
-
Je trouve que les morceaux de code que j’ai posté le prouve bien, oui. En tout cas comparé à ces hacks du démon qu’il faut réaliser avec TikZ.Attention toutefois. TikZ a aussi ses avantages, ainsi selon les scénarios celui-ci sera peut-être plus simple d’utilisation que MetaPost/MetaFun, même si en général ils sont tout aussi puissant l’un que l’autre et permettent de faire à peu près les mêmes choses.
-
Merci pour vos réponses !J'essaye de trouver des solutions utilisant exclusivement Tikz (sans importer de graphe réalisé à l'aide d'un logiciel extérieur). J'ai importé le package pstricks-add, mais je n'ai pas réussi à utiliser la fonction "sum" (sans doute parce que je n'ai pas encore lu tout le manuel d'utilisation du package, et que je ne sais donc pas quelle(s) balise(s) mettre autour de la fonction). J'ai tenté d'écrire "à la main" les 20 premières fonctions, mais j'ai assez vite reçu un message d'erreur me disant "dimension too large". Voici le code (sans doute non minimal, puisque j'ai laissé un certain nombre de packages que j'utilise d'habitude et qui ne sont peut-être pas tous utiles ici):
\documentclass[a4paper,8pt]{article} \usepackage[utf8]{inputenc} \usepackage[T1]{fontenc} \usepackage[french]{babel} \usepackage{amsfonts} \usepackage{amssymb} \usepackage{caption} \usepackage{graphicx} \usepackage{pstricks} \usepackage{pstricks-add} \usepackage{tikz} \usepackage{amsthm} \usepackage{mathtools} \usepackage{nameref} \usepackage{hyperref} \usepackage{xcolor} \usepackage{tikz} \usetikzlibrary{decorations.pathreplacing, calligraphy, tikzmark, matrix, fit, positioning,calc} \usepackage[left=2.8cm,right=2.9cm,margin=2cm]{geometry} \setlength{\parindent}{0pt} \begin{document} \begin{figure}\centering \begin{tikzpicture} \draw[step=1cm, gray, very thin] (-6, -3) (6, 3); \draw[very thick, ->] (-6,0) -- (6,0) node[below left]{$x$}; \draw[very thick, ->] (0,-3) -- (0,3) node[left]{$y$}; \draw[blue, very thick] [domain=-6:6,samples=600] plot (\x,{cos(\x r) - cos(2*\x r)/2 + cos(4*\x r)/4 - cos (8*\x r)/8 + cos (16*\x r)/16 - cos (32*\x r)/32});
\end{tikzpicture} \captionsetup{labelformat=empty} \caption{Graphe de $\varphi$}\vspace{-1em} \end{figure} \end{document}Tex m'arrête à $2^n = 32$... quelqu'un sait-il comment aller plus loin, ou quelqu'un peut-il m'indiquer comment utiliser la fonction sum de @JavierT à l'intérieur de ce document ?Je vais également essayer de lire la documentation de MetaFun indiquée par @dp (j'utilise TexMaker, "compilation rapide" si c'était sa question). -
Je n'ai pas spécialement posé de question. C'est plus simplement que tu n'as pas précisé si tu utilises Plain TeX, Eplain, LaTeX ou ConTeXt, qui (grossièrement) bien qu'ayant tous pour objectif de produire des documents hautement qualitatifs, emploient des approches légèrement différentes (bien qu'étant tous basés sur Plain TeX de Donald E. Knuth).Dans mon cas, je t'ai proposé une solution qui utilise ConTeXt (et c'est "natif", donc ça fonctionne out-of-the-box -- oui, ça veut dire qu'il n'y a pas à se prendre la tête avec les paquets comme avec LaTeX.) qui ne fonctionnera pas sur LaTeX, tout du moins avec pdfLaTeX ou XeLaTeX par exemple. En revanche, ça devrait fonctionner avec des adaptations sur lua(la)TeX avec (notamment) les packages luacode et luamplib. Il est aussi possible de générer les fichiers "à côté" avec le binaire mpost une fois ConTeXt installé.Bref, plein solutions s'offrent à toi. Il ne te reste plus qu'à choisir celle qui répond le mieux à tes besoins.
-
Je me dis que ça pourrait être intéressant de montrer ce qu'il est possible de faire simplement et rapidement dans ce cas de figure avec ConTeXt et MetaPost [voir ce document pour commencer avec ConTeXt et ce document pour commencer avec MetaPost (il existe une version française de ce dernier mais ayant 20 ans d'age)].Commençons par réaliser une petite macro qui sera bien utile (écrite plus pour la compréhension que l’efficacité). Cette macro va nous servir à afficher un repère orthonormal $(0, \vec{\imath}, \vec{\jmath})$ où une unité de longueur correspond à $1$ centimètre.
def xyaxis(expr xmin, xmax, ymin, ymax) = path x, y ; x := (xmin*cm, 0cm) -- (xmax*cm, 0cm) ; y := (0cm, ymin*cm) -- (0cm, ymax*cm) ; % Grille d'arrière plan "grisée" drawoptions(dashed withdots withcolor .75white) ; for xx = ceiling xmin upto floor xmax: draw y shifted (xx*cm,0) ; endfor for yy = ceiling ymin upto floor ymax: draw x shifted (0,yy*cm) ; endfor % Axes x et y orthonormaux drawoptions(withpen pencircle scaled .5pt) ; %% origin draw textext.ulft("$O$") shifted origin shifted (-0.15cm,0.15cm) ; %% x axis drawarrow x scaled 1 ; draw textext.rt ("$x$") shifted (xmax*cm+0.15cm,0cm) ; %% y axis drawarrow y scaled 1 ; draw textext.top ("$y$") shifted (0cm,ymax*cm+0.15cm) ; % Graduation for xx = ceiling xmin upto floor xmax: if xx=xmax: elseif xx=0: else: draw (xx*cm, 0cm) -- (xx*cm, -0.15cm) ; draw textext.bot(xx) shifted (xx*cm,-0.30cm) ; fi endfor for yy = ceiling ymin upto floor ymax: if yy=ymax: elseif yy=0: else: draw (0cm,yy*cm) -- (-0.15cm, yy*cm) ; draw textext.lft(yy) shifted (-0.30cm,yy*cm) ; fi endfor enddef ;
Après avoir "importé" la macro (depuis un autre fichier ou simplement copier-coller), on réécrit mon code précédent (avec quelques modifications).On commence donc au début par créer la fonction $\varphi$ en lua. Pourquoi lua ? Eh bien, parce que ConTeXt utilise LuaTeX qui permet (parmi tant d'autres choses [voir les manuels de luatex et de luametatex]) de gérer du code écrit en lua. Ici on s'en sert pour générer les valeurs numériques d'une fonction mais on pourrait tout aussi bien s'en servir pour diagonaliser une matrice ou encore effectuer les divisions euclidiennes de polynômes. En réalité, il est possible de l'utiliser, notamment, pour automatiser tout ce que vous pouvez imaginer vouloir automatiser dans vos documents $\TeX$ [voir le manuel ConTeXt Lua Documents].S'en suit la génération du graphe. On commence évidement par afficher notre repère orthonormal à l'aide de la macro précédente. Pour ce qui est du graphe de $\varphi: t \mapsto \sum\limits_{n=1}^{+ \infty} \frac{(-1)^n \cos (2^n t)}{2^n}$ en lui-même, j'ai été assez gourmand en ressources ici, étant donné que j'ai décidé de générer deux fois plusieurs valeurs $\varphi(x)$ pour $x\in[-6,6]$. Ça fonctionne bien et rapidement ici car c'est la seule fonction affichée mais dans les faits avec un document plus long, comprenant plusieurs dizaines ou centaines de pages, il serait beaucoup judicieux de ne pas faire ça et générer les parties en pointillées uniquement pour les valeurs extrêmes de l'intervalle.\startTEXpage \startluacode function MP.phi(t) total = 0.0 for n=1,32 do total = total + (-1)^n*math.cos(2^n*t)/2^n end return total end \stopluacode \startMPcode begingroup ; % On utilise la macro précédemment introduite pour % afficher le repère orthonormal dans lequel la % fonction va prendre place. xyaxis(-7.5,7.5,-1.5,1.5) ; % On "importe" la fonction lua dans MetaPost. % Étape importante car `function` ne semble pas % accepter directement des fonctions lua. vardef phi(expr t) = MP.phi(t) enddef ; draw function(1, "x", "phi(x)", -7.5, 7.5, .001) % On commence par générer une première fois la fonction scaled 1cm % où 1 "unité" vaut 1cm dashed evenly % en pointillées withpen pencircle scaled .15pt % avec une courbe pas trop grosse withcolor darkred ; % de couleur rouge draw function(1, "x", "phi(x)", -6, 6, .001) % On génère de nouveau la fonction scaled 1cm % où 1 "unité" vaut 1cm withpen pencircle scaled .15pt % avec une courbe pas trop grosse withcolor darkred ; % de couleur rouge endgroup ; \stopMPcode \stopTEXpage
Le tout permet finalement d'obtenir cette représentation de la fonction $\varphi: t \mapsto \sum\limits_{n=1}^{+ \infty} \frac{(-1)^n \cos (2^n t)}{2^n}$:Enfin, évidement, ça fonctionne affreusement bien et en changeant simplement l'expression de $\varphi$ dans le code lua, par exemple pour $\phi: t \mapsto \sum\limits_{n=1}^{+ \infty} \frac{(-1)^n \textcolor{red}{\sin} (2^n t)}{2^n}$, on obtient très facilement (après une simple recompilation):Je joins en pièce jointe le fichier minimal tel qu'il devrait être écrit pour donner ce rendu. À compiler avec ConTeXt comme suit$ context phi.tex
le résultat se trouvera alors dans le fichier phi.pdf.
Connectez-vous ou Inscrivez-vous pour répondre.
Bonjour!
Catégories
- 165.6K Toutes les catégories
- 65 Collège/Lycée
- 22.2K Algèbre
- 37.7K Analyse
- 6.3K Arithmétique
- 61 Catégories et structures
- 1.1K Combinatoire et Graphes
- 13 Sciences des données
- 5.1K Concours et Examens
- 26 CultureMath
- 51 Enseignement à distance
- 2.9K Fondements et Logique
- 10.8K Géométrie
- 86 Géométrie différentielle
- 1.1K Histoire des Mathématiques
- 79 Informatique théorique
- 3.9K LaTeX
- 39K Les-mathématiques
- 3.5K Livres, articles, revues, (...)
- 2.7K Logiciels pour les mathématiques
- 30 Mathématiques et finance
- 344 Mathématiques et Physique
- 5K Mathématiques et Société
- 3.4K Pédagogie, enseignement, orientation
- 10.1K Probabilités, théorie de la mesure
- 806 Shtam
- 4.2K Statistiques
- 3.8K Topologie
- 1.4K Vie du Forum et de ses membres