Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • orestis.malaspin/math_tech_info
  • jerome.chetelat/math_tech_info
  • julien.borel/math_tech_info
  • xavier.perret/math_tech_info
  • ilias.nhairi/math_tech_info
  • julien.seemulle/math_tech_info
  • michael.elkharro/math_tech_info
  • fabien.lometti/math_tech_info
  • guillaum.pin/math_tech_info
  • quentin.rod/math_tech_info
  • simon.cirilli/math_tech_info
11 results
Select Git revision
Show changes
Showing with 484 additions and 4277 deletions
Source diff could not be displayed: it is too large. Options to address this: view the blob.
\newcommand{\ux}{\bm{x}}
\newcommand{\dd}{\mathrm{d}}
\newcommand{\real}{\mathbb{R}}
\newcommand{\grad}{\mathrm{grad}}
\ No newline at end of file
# Modélisation d'épidémies
**Avertissement:** Dans cette brève introduction nous n'avons pas la prétention
de présenter des modèles très précis ayant une grande valeur prédictive.
L'objectif est plutôt de se familiariser avec le concept de modèle mathématique
ainsi que d'étudier un modèle simplifié de propagation d'épidémieet de voir quels peuvent
être les effets de la quarantaine sur une propagation libre.
## L'exponentielle
Un modèle mathématique d'une épidémie est une abstraction mathématique de la réalité permettant
de faire des prédictions sur l'évolution du nombre de personne atteinte et leur guérison possible
guérison. Elle permet ainsi de prévoir l'effet des politiques publiques pour contenir
les épidémies: quarantaine, vaccination, ...
Imaginons d'abord un modèle très simple où nous considérons une fonction, $M(t)$,
qui donne le nombre nombre d'individus ayant contracté une maladie en fonction
du temps. La valeur $M_0=M(0)$ est le nombre de malades le jour où la maladie
se déclare pour la première fois. On aimerait décrire l'évolution
de cette maladie. Pour ce faire, nous allons écrire une équation
qui va calculer $M(t+\delta t)$ à partir de $M(t)$ qui est supposé connu.
Supposons dans notre modèle très simplifié, que chaque personne malade
contamine exactement deux personnes saines en un temps $\delta t$.
Supposons également qu'il y a une infinité
de personnes saines (c'est pas très réaliste mais cela simplifie les choses pour le moment).
Nous avons donc que le nombre de personne infectées au temps $t+\delta t$, $M(t+\delta t)$
est donné par
$$
M(t+\delta t)=M(t)+\delta t \cdot 2\cdot M(t).
$$
A gauche de cette équation nous avons le nombre de malades au temps $t+\delta t$ qui
est donné par le nombre de malade le jour $t$, auquel on additionne le nombre de nouveaux malades
qu'ils ont contaminés en une journée (2 fois leur nombre).
Si $\delta t$ est un jour, et que nous avons au premier jour une seul malade, $M(0)=1$,
on a la suite suivante
\begin{align}
M(0)&=1\mbox{ malades},\\
M(1)&=M(0)+1\cdot 2 M(0)=1 + 2=3\mbox{ malades},\\
M(2)&=M(1)+1\cdot 2 M(1)=3 + 6=9\mbox{ malades},\\
M(3)&=M(2)+1\cdot 2 M(2)=9 + 18=27\mbox{ malades},\\
\vdots&
\end{align}
On peut facilement se convainque qu'au bout de $n$ jours, le
nombre de malades a atteint $3^n$. On a une croissance **exponentielle**
du nombre de malades.
Ce qu'on a fait ici comme modèle est un modèle compartimental (on a compartimenté la population):
on a divisé la population en une classe, celle des malades $M(t)$. Puis
on a adjoint une règle d'évolution à cette classe: chaque jour chaque malade infecte
deux nouvelles personnes. Ce modèle est très simpliste mais il illustre très bien
comment on construit un modèle d'épidémie.
Par ailleurs, on peut se rendre compte que l'équation que nous avons écrite plus
haut décrit l'évolution du *taux de variation* de $M(t)$. En effet, en réarrangeant les termes de cette équation, on a que
$$
\underbrace{\frac{M(t+\delta t)-M(t)}{\delta t}}_{\mbox{taux de variation}}=2M(t).
$$
Si nous prenons la limite pour $\delta t\rightarrow 0$ des deux côtés
nous obtenons
$$
M'(t)=2M(t).
$$
Ceci est une **équation différentielle**, une équation dont l'inconnue est une fonction
et qui relie sa forme avec ses dérivées. Nous allons utiliser
ce type d'équations pour voir un modèle un peu plus réaliste de modèle
d'épidémies dans la section suivante.
## Modèles compartimentaux
Les modèles compartimentaux, créés autour des années 1920, sont des modèles
mathématiques permettant de représenter la propagation des épidémies.
Ces modèles divisent une population en plusieurs *classes* épidémiologiques (compartiments)
comme les individus sains mais susceptibles d'être infectés, les individus infectieux, et
les individus guéris (qui ont acquis une immunité suite à une infection). Ces trois compartiements
sont notés respectivement, $S$, $I$, et $R$. Il en existe d'autres, mais nous ne les
discuterons pas dans le cadre de cette petite introduction.
Une fois les compartiments définis, il est nécessaire de définir les *règles* permettant de passer d'un compartiment à l'autre. Dans le cas à trois classes ci-dessus, nous voulons
décrire les transitions entre les patients sains (susceptibles d'attraper la maladie) et inféctieux,
$$
S\rightarrow I,
$$
puis entre infectieux et guéris
$$
S\rightarrow I.
$$
La transition $S\rightarrow I$ est décrite par le taux de transmission de la maladie, $\beta\cdot I$. $\beta$ est le nombre de contacts par personne multipliée par la probabilité de transmission de la maladie quand une personne infectieuse rencontre une personne susceptible d'attraper la malade.
De même la transition $I\rightarrow R$ est donnée par $\lambda=1/d$, le taux de guérison (ou de mort) qui est simplement
l'inverse du temps nécessaire à la guérison (ou à la mort).
A présent, nous pouvons écrire les équations différentielles
régissant l'évolution de $S(t)$, $I(t)$ et $R(t)$.
Le nombre d'individus susceptible d'attraper la maladie
va décroître proportionnellement au taux de transmission de la maladie multiplié par la fraction du nombre d'individus susceptible de l'attraper sur leur nombre total
$$
S'(t)=-\frac{\beta I(t)\cdot S(t)}{N},
$$
où $N=I(t)+S(t)+R(t)$ est la population totale (c'est une constante). Étant donné qu'il n'y a pas d'individus sains
injectés dans le système il n'y a pas de façon de faire croître $S(t)$.
Le nombre de personnes guéries va croître proportionnellement
au nombre de personnes infectées
$$
R'(t)=\lambda I(t).
$$
Finalement, le nombre de personnes infectieuses va croître exactement du
même nombre que le nombre de personne saine ayant attrapé la maladie, et décroître du nombre de personne guéries
$$
I'(t)=\frac{\beta I(t)\cdot S(t)}{N} - \lambda I(t).
$$
Nous avons donc un système d'équations différentielles.
\begin{align*}
S'(t)&=-\frac{\beta I(t)\cdot S(t)}{N},\\
I'(t)&=\frac{\beta I(t)\cdot S(t)}{N} - \lambda I(t),\\
R'(t)&=\lambda I(t).
\end{align*}
La dynamique de ce système est pilotée par $R_0$,
le taux de reproduction de base qui est donné par le rapport du taux de transmission de la maladie avec le taux de guérison
$$
R_0=\frac{\beta}{\lambda}.
$$
Ce système d'équations est **non-linéaire** mais possède une solution analytique. Nous n'allons pas nous intéresser à sa résolution analytique, mais plutôt le résoudre numériquement.
En nous rappelant que la définition de $f'(t)$ est
$$
f'(t)=\lim_{t\rightarrow 0}\frac{f(t+\delta t) - f(t)}{\delta t},
$$
on voit qu'on peut approximer $f'(t)$ par
$$
f'(t)\cong \frac{f(t+\delta t)-f(t)}{\delta t}.
$$
Il vient que le système d'équations ci-dessus peut se réécrire
\begin{align}
S(t+\delta t)&=S(t)-\frac{\delta t\beta I(t)\cdot S(t)}{N},\\
I(t+\delta t)&=I(t)+\delta t\left(\frac{\beta I(t)\cdot S(t)}{N} - \lambda I(t)\right),\\
R(t+\delta t)&=R(t)+\delta t\lambda I(t).
\end{align}
A l'aide de ces équations on peut calculer *itérativement*
la valeur de $S, I, R$ de ces valeurs pour un $t$ donné en partant d'une condition initiale $S(0)$, $I(0)$, et $R(0)$.
STYLES := css/tufte-css/tufte.css \
css/pandoc.css \
css/pandoc-solarized.css \
css/tufte-extra.css
OPTIONS = --toc
OPTIONS += --filter=pandoc-numbering
OPTIONS += --filter=pandoc-crossref
PDFOPTIONS = --highlight-style kate
PDFOPTIONS += --pdf-engine pdflatex
PDFOPTIONS += --number-sections
PDFOPTIONS += --template=../default.latex
HTMLOPTIONS += -t html5
HTMLOPTIONS += -c ../css/tufte-css/tufte.css
HTMLOPTIONS += --self-contained
HTMLOPTIONS += --mathjax=../MathJax.js
all: covid.pdf covid.html
# %.tex: %.md
# pandoc -s $(OPTIONS) $(PDFOPTIONS) -o $@ $<
covid.pdf: 00_macros.md 01_covid.md
pandoc -s $(OPTIONS) $(PDFOPTIONS) -o $@ $^ --metadata-file metadata.yaml
covid.html: 00_macros.md 01_covid.md
pandoc -s $(OPTIONS) $(HTMLOPTIONS) -o $@ $^ --metadata-file metadata.yaml
deploy: all
mkdir -p ../mti
cp covid.html ../mti/index.html
cp covid.pdf ../mti/covid.pdf
clean:
rm -f *.html *.pdf
---
author:
- Orestis Malaspinas
title: Mathématiques en technologie de l'Information
autoSectionLabels: false
autoEqnLabels: true
eqnPrefix:
- "éq."
- "éqs."
chapters: true
numberSections: false
chaptersDepth: 1
sectionsDepth: 3
lang: fr
documentclass: book
papersize: A4
cref: false
urlcolor: blue
---
import numpy as np
import matplotlib.pyplot as plt
swiss = np.array([2.100350058, 3.150525088, 4.900816803, 6.534422404, 10.501750292, 13.302217036, 24.970828471, 31.271878646, 39.323220537, 43.640606768, 57.292882147, 76.079346558, 100.116686114, 131.271878646, 158.576429405, 256.709451575, 256.709451575, 268.378063011, 309.218203034, 353.325554259, 453.675612602])
swiss = np.array([18, 27, 42, 56, 90, 114, 214, 268, 337, 374, 491, 652, 858, 1125, 1359, 2200, 2200, 2300, 2650, 3028, 3888]) / 0.02
days = np.array(range(1,len(swiss)+1))
def F(yx, yy, yz, t):
return sigma * (yy - yz), rho * yx, (mu * yx + yz)
def rk2(yx, yy, yz, t, dt):
yx_tmp, yy_tmp, yz_tmp = F(yx, yy, yz, t)
yx0 = yx + dt / 2 * yx_tmp
yy0 = yy + dt / 2 * yy_tmp
yz0 = yz + dt / 2 * yz_tmp
y1x, y1y, y1z = F(yx0, yy0, yz0, t+dt/2)
return yx + dt * y1x, yy + dt * y1y, yz + dt * y1z
def yx(dt, yx0, yy0, yz0, sig):
return yx0 + dt * sigma * (yy0-yz0)
def s(dt, beta, S0, I0, N):
return S0 - dt * (beta * S0 * I0 / N)
def ii(dt, beta, lamb, S0, I0, N):
return I0 + dt * (beta * S0 * I0 / N - lamb * I0)
def r(dt, lamb, R0, I0, N):
return R0 + dt * lamb * I0
def compute_n(S, R, I):
return S + R + I
def timestep(S0, I0, R0, dt, beta, lamb, N):
S1 = s(dt, beta, S0, I0, N)
I1 = ii(dt, beta, lamb, S0, I0, N)
R1 = r(dt, lamb, R0, I0, N)
return S1, I1, R1
S0 = 8000000
I0 = swiss[0]
R0 = 0
max_t = 3*days[len(swiss)-1]
n_steps = 100000
dt = max_t / n_steps
N = compute_n(S0, I0, R0)
lamb = 1.0 / 14.0
beta_1 = 0.35
beta_2 = beta_1 / 10
beta = beta_1
R0 = beta / lamb
print(R0)
s_list = [S0]
r_list = [R0]
i_list = [I0]
t_list = [1]
for i in range(0, n_steps):
S1, I1, R1 = timestep(s_list[i], i_list[i], r_list[i], dt, beta, lamb, N)
s_list.append(S1)
i_list.append(I1)
r_list.append(R1)
t_list.append(t_list[i]+dt)
# if (R1 >= 0.9 * N):
# print(t_list[i]+dt)
# break
# if (t_list[i+1] < 27) :
# beta = beta_1
# elif (I1 > 0.01*N) :
# beta = beta_2
# else:
# beta = beta_1
s = np.array(s_list)
r = np.array(r_list)
ii = np.array(i_list)
t = np.array(t_list)
s
plt.semilogy(t, s, 'b')
plt.semilogy(t, r, 'r')
plt.semilogy(t, ii, 'k')
plt.semilogy(days, swiss, 'k*')
plt.legend(['S', 'I', 'R', 'swiss'])
plt.show()
2.100350058 18 1
3.150525088 27 2
4.900816803 42 3
6.534422404 56 4
10.501750292 90 5
13.302217036 114 6
24.970828471 214 7
31.271878646 268 8
39.323220537 337 9
43.640606768 374 10
57.292882147 491 11
76.079346558 652 12
100.116686114 858 13
131.271878646 1125 14
158.576429405 1359 15
256.709451575 2200 16
256.709451575 2200 16
268.378063011 2300 17
309.218203034 2650 18
353.325554259 3028 19
453.675612602 3888 20
import numpy as np
import matplotlib.pyplot as plt
import functools
import matplotlib.animation as animation
swiss = np.array([2.100350058, 3.150525088, 4.900816803, 6.534422404, 10.501750292, 13.302217036, 24.970828471, 31.271878646, 39.323220537, 43.640606768, 57.292882147, 76.079346558, 100.116686114, 131.271878646, 158.576429405, 256.709451575, 256.709451575, 268.378063011, 309.218203034, 353.325554259, 453.675612602])
swiss = np.array([18, 27, 42, 56, 90, 114, 214, 268, 337, 374, 491, 652, 858, 1125, 1359, 2200, 2200, 2300, 2650, 3028, 3888])
days = np.array(range(1,len(swiss)+1))
def update(i, lines, t, p):
n_pop, length = p.shape
for j in range(0, n_pop):
lines[j].set_data(t[0:i], p[j][0:i])
return lines
# def policy_r0(R_0, R_target, t, delta_t):
# if (t <= )
def seir(y, t, R_0, Tinf, Tinc):
N = np.sum(y)
y1 = np.zeros(4)
y1[0] = - R_0 / Tinf * y[2] * y[0] / N
y1[1] = R_0 / Tinf * y[2] * y[0] / N - 1.0 / Tinc * y[1]
y1[2] = 1.0 / Tinc * y[1] - 1.0 / Tinf * y[2]
y1[3] = 1.0 / Tinf * y[2]
return y1
def seihse(y, t, R_0, Tinf, Tinc, Thos, Tsev):
N = np.sum(y)
y1 = np.zeros(6)
y1[0] = - R_0 / Tinf * y[2] * y[0] / N # Sane
y1[1] = R_0 / Tinf * y[2] * y[0] / N - 1.0 / Tinc * y[1] # Exposed
y1[2] = 1.0 / Tinc * y[1] - 1.0 / Tinf * y[2] - 1.0 / Tinf * y[2] # Infectious
y1[3] = 1.0 / Tinf * y[2] + 1.0 / Thos * y[4] + 1.0 / Tsev * y[5] # Recovered
y1[4] = - 1.0 / Thos * y[4] + 1.0 / Tinf * y[2] - 1.0 / Tsev * y[4] # Hospitalized
y1[5] = - 1.0 / Tsev * y[5] + 1.0 / Thos * y[4] # Severe
return y1
def rk4(F, y, t, dt):
k1 = dt * F(y, t)
k2 = dt * F(y + k1 / 2, t + dt/2)
k3 = dt * F(y + k2 / 2, t + dt/2)
k4 = dt * F(y + k3, t + dt)
return y + (k1 + 2 * (k2 + k3) + k4) / 6
R_0 = 4.26
R_01 = 4.26
R_02 = 1 - 1/R_01
Tinf = 7.0
Tinc = 5.1
Thos = 14.0
Tsev = 14.0
N = 500000
I0 = 214 / 0.2
E0 = 2000
R0 = 0
S0 = N-E0-I0
H0 = 0
Sev0 = 0
t0 = 24
# max_t = 5*days[len(swiss)-1]
max_t = 200.0
n_steps = 1000
dt = max_t / n_steps
y0 = np.array([S0, E0, I0, R0, H0, Sev0])
y_list = [y0]
t_list = [t0]
for i in range(0, n_steps):
t = t_list[i] + dt
# foo = functools.partial(seir, R_0=R_0, Tinf=Tinf, Tinc=Tinc)
foo = functools.partial(seihse, R_0=R_0, Tinf=Tinf, Tinc=Tinc, Thos=Thos, Tsev=Tsev)
y1 = rk4(foo, y_list[i], t, dt)
y_list.append(y1)
t_list.append(t)
if (y1[1] + y1[2] < 1):
break
t = np.array(t_list)
y = np.array(y_list)
p = np.transpose(y)
fig = plt.figure()
# ax = plt.axes(xlim=(-0.1*np.max(t),np.max(t)*1.1), ylim=(-0.1*np.max(p),np.max(p)*1.1))
ax = plt.axes(xlim=(1,np.max(t)*1.1), ylim=(1,np.max(p)*1.1))
lines = [plt.semilogy([], [], 'r-')[0],
plt.semilogy([], [], 'b-')[0],
plt.semilogy([], [], 'g-')[0],
plt.semilogy([], [], 'k-')[0],
plt.semilogy([], [], 'c-')[0],
plt.semilogy([], [], 'y-')[0] ]
# anim = animation.FuncAnimation(fig, functools.partial(update, lines=lines, t=t, p=p),
# frames=n_steps, interval=10, blit=True)
ax.legend(['Sain', 'Exposé', 'Infectieux', 'Rétablis', 'Hospitalisés', 'Soins intensifs'])
anim = animation.FuncAnimation(fig, functools.partial(update, lines=lines, t=t, p=p),
frames=n_steps, interval=10, blit=True)
# plt.semilogy(t, p[0], 'b')
# plt.semilogy(t, p[1], 'r')
# plt.semilogy(t, p[2], 'k')
# plt.semilogy(t, p[3], 'g')
# # plt.semilogy(days, swiss, 'k*')
# plt.legend(['S', 'E', 'I', 'R', 'swiss'])
plt.show()
.latex-sub, .latex-sup { text-transform: uppercase;
font-size: smaller;
position: relative; }
.latex-sub { top: 0.2rem;
margin-left: -0.1667rem;
margin-right: -0.125rem; }
.latex-sup { top: -0.2rem;
margin-left: -0.36rem;
margin-right: -0.15rem;
text-shadow: none; }
.latex::selection, .latex span:not(.latex-sup)::selection { text-shadow: 0.03em 0 #b4d5fe, -0.03em 0 #b4d5fe, 0 0.03em #b4d5fe, 0 -0.03em #b4d5fe, 0.06em 0 #b4d5fe, -0.06em 0 #b4d5fe, 0.09em 0 #b4d5fe, -0.09em 0 #b4d5fe, 0.12em 0 #b4d5fe, -0.12em 0 #b4d5fe, 0.15em 0 #b4d5fe, -0.15em 0 #b4d5fe;
background: #b4d5fe; }
.latex::-moz-selection, .latex span:not(.latex-sup)::-moz-selection { text-shadow: 0.03em 0 #b4d5fe, -0.03em 0 #b4d5fe, 0 0.03em #b4d5fe, 0 -0.03em #b4d5fe, 0.06em 0 #b4d5fe, -0.06em 0 #b4d5fe, 0.09em 0 #b4d5fe, -0.09em 0 #b4d5fe, 0.12em 0 #b4d5fe, -0.12em 0 #b4d5fe, 0.15em 0 #b4d5fe, -0.15em 0 #b4d5fe;
background: #b4d5fe; }
@import url(//fonts.googleapis.com/css?family=Libre+Baskerville:400,400italic,700);@import url(//fonts.googleapis.com/css?family=Source+Code+Pro:400,400italic,700,700italic);/* normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}body,code,tr.odd,tr.even,figure{background-image:url("data:image/png;base64,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")}body{font-family:"Libre Baskerville",Baskerville,Georgia,serif;background-color:#f8f8f8;color:#111;line-height:1.3;text-align:justify;-moz-hyphens:auto;-ms-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}@media (max-width: 400px){body{font-size:12px;margin-left:10px;margin-right:10px;margin-top:10px;margin-bottom:15px}}@media (min-width: 401px) and (max-width: 600px){body{font-size:14px;margin-left:10px;margin-right:10px;margin-top:10px;margin-bottom:15px}}@media (min-width: 601px) and (max-width: 900px){body{font-size:15px;margin-left:100px;margin-right:100px;margin-top:20px;margin-bottom:25px}}@media (min-width: 901px) and (max-width: 1800px){body{font-size:17px;margin-left:200px;margin-right:200px;margin-top:30px;margin-bottom:25px;max-width:800px}}@media (min-width: 1801px){body{font-size:18px;margin-left:20%;margin-right:20%;margin-top:30px;margin-bottom:25px;max-width:1000px}}p{margin-top:10px;margin-bottom:18px}em{font-style:italic}strong{font-weight:bold}h1,h2,h3,h4,h5,h6{font-weight:bold;padding-top:0.25em;margin-bottom:0.15em}header{line-height:2.475em;padding-bottom:0.7em;border-bottom:1px solid #bbb;margin-bottom:1.2em}header>h1{border:none;padding:0;margin:0;font-size:225%}header>h2{border:none;padding:0;margin:0;font-style:normal;font-size:175%}header>h3{padding:0;margin:0;font-size:125%;font-style:italic}header+h1{border-top:none;padding-top:0px}h1{border-top:1px solid #bbb;padding-top:15px;font-size:150%;margin-bottom:10px}h1:first-of-type{border:none}h2{font-size:125%;font-style:italic}h3{font-size:105%;font-style:italic}hr{border:0px;border-top:1px solid #bbb;width:100%;height:0px}hr+h1{border-top:none;padding-top:0px}ul,ol{font-size:90%;margin-top:10px;margin-bottom:15px;padding-left:30px}ul{list-style:circle}ol{list-style:decimal}ul ul,ol ol,ul ol,ol ul{font-size:inherit}li{margin-top:5px;margin-bottom:7px}q,blockquote,dd{font-style:italic;font-size:90%}blockquote,dd{quotes:none;border-left:0.35em #bbb solid;padding-left:1.15em;margin:0 1.5em 0 0}blockquote blockquote,dd blockquote,blockquote dd,dd dd,ol blockquote,ol dd,ul blockquote,ul dd,blockquote ol,dd ol,blockquote ul,dd ul{font-size:inherit}a,a:link,a:visited,a:hover{color:inherit;text-decoration:none;border-bottom:1px dashed #111}a:hover,a:link:hover,a:visited:hover,a:hover:hover{border-bottom-style:solid}a.footnoteRef,a:link.footnoteRef,a:visited.footnoteRef,a:hover.footnoteRef{border-bottom:none;color:#666}code{font-family:"Source Code Pro","Consolas","Monaco",monospace;font-size:85%;background-color:#ddd;border:1px solid #bbb;padding:0px 0.15em 0px 0.15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}pre{margin-right:1.5em;display:block}pre>code{display:block;font-size:70%;padding:10px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;overflow-x:auto}blockquote pre,dd pre,ul pre,ol pre{margin-left:0;margin-right:0}blockquote pre>code,dd pre>code,ul pre>code,ol pre>code{font-size:77.77778%}caption,figcaption{font-size:80%;font-style:italic;text-align:right;margin-bottom:5px}caption:empty,figcaption:empty{display:none}table{width:100%;margin-top:1em;margin-bottom:1em}table+h1{border-top:none}tr td,tr th{padding:0.2em 0.7em}tr.header{border-top:1px solid #222;border-bottom:1px solid #222;font-weight:700}tr.odd{background-color:#eee}tr.even{background-color:#ccc}tbody:last-child{border-bottom:1px solid #222}dt{font-weight:700}dt:after{font-weight:normal;content:":"}dd{margin-bottom:10px}figure{margin:1.3em 0 1.3em 0;text-align:center;padding:0px;width:100%;background-color:#ddd;border:1px solid #bbb;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;overflow:hidden}img{display:block;margin:0px auto;padding:0px;max-width:100%}figcaption{margin:5px 10px 5px 30px}.footnotes{color:#666;font-size:70%;font-style:italic}.footnotes li p:last-child a:last-child{border-bottom:none}
Subproject commit c414b9117d5b39bdb747a172822333fc1043aee3
......@@ -11,6 +11,7 @@ $if(linestretch)$
\usepackage{setspace}
\setstretch{$linestretch$}
$endif$
\renewcommand{\linethickness}{0.05em}
\usepackage{amssymb,amsmath,bm}
\usepackage{ifxetex,ifluatex}
\usepackage{fixltx2e} % provides \textsubscript
......@@ -233,15 +234,6 @@ $if(institute)$
$endif$
\date{$date$}
\newcommand{\dd}{\mathrm{d}}
\newcommand{\real}{\mathbb{R}}
\newcommand{\integer}{\mathbb{Z}}
\newcommand{\definition}{\textbf{Definition }}
\newcommand{\exemples}{\textbf{Exemples }}
\newcommand{\remarque}{\textbf{Remarque }}
\newcommand{\proprietes}{\textbf{Propriétés }}
\newcommand{\propriete}{\textbf{Propriété }}
\begin{document}
$if(title)$
\maketitle
......
*.md
EXAMEN=intEdo
EXAMEN=intOpt2020
default:
$(EXAMEN).pdf: $(EXAMEN).md
pandoc -s -o $(EXAMEN).pdf $(EXAMEN).md --filter=pandoc-numbering --filter=pandoc-crossref --template=../default.latex --pdf-engine pdflatex
File added
*.svg
*.pdf
*.png
File added
File added
File added
File added