import numpy as np import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec import pandas as pd from scipy.integrate import odeint,quad from scipy.stats import kde,beta import seaborn as sns #%matplotlib from importlib import reload pi=np.pi from scipy.optimize import brentq #pour matplotlib font = {'family' : 'normal', 'weight' : 'bold', 'size' : 22} plt.rc('font', **font) #plt.rc('text', usetex=True) #rend plus rapide les sorties graphiques plt.rc('xtick',labelsize=22) plt.rc('ytick',labelsize=22) #mardi 31 mars 2020 #essayons tout d'abord d'écrire des fonctions qui calculent le rayon spectral #et l'abcisse de convergence d'une matrice from numpy import linalg as LA from scipy.linalg import expm def spectralabc(m): """m is a matrix""" return(LA.eigvals(m).real.max()) def spectralrad(M): """M is a matrix : returns the spectral radius""" return(np.absolute(LA.eigvals(M)).max()) #et on teste A=np.array([[1, -1], [4, 2]]) B=np.diag((1, 2, 3)) ei=LA.eigvals(A) z=ei[0] rei=ei.real np.exp(spectralabc(A)) spectralrad(expm(A)) #doit donner la même chose #un premier modele de covid avec deux classes Asymptomatique et Infectieux def tauxcontacper(beta,p,cbeta,T): """renvoie une fonction de contact de periode T qui vaut beta pendant une fraction p de laperiode et beta(1-cbeta) pendant le reste de la periode""" def f(t): if (t <= T*p): return(beta) else: return(beta*(1-cbeta)) return(f) def periodise(f,T=1): #retourne la fonction qui etait definie sur [0,T] periodisee sur R def g(t): return(f(t-T*np.floor(t/T))) return(g) T=7 p=0.3 tt=np.linspace(0,T,100) f=tauxcontacper(0.25,p,0.8,T) #plt.plot(tt,[f(s) for s in tt]) dtt=np.linspace(-2*T,3*T,400) g=periodise(f,T) #plt.plot(dtt,[g(s) for s in dtt]) def lamat(betaA,betaS,piS,gammaA,gammaS): return np.array([[piS*betaS-gammaS,piS*betaS],[(1-piS)*betaA,(1-piS)*betaA-gammaA]]) def lesabcissesspec(betaA,betaS,piS,gammaA,gammaS,cbeta): azero=lamat(betaA,betaS,piS,gammaA,gammaS) azcbeta=lamat(betaA*(1-cbeta),betaS*(1-cbeta),piS,gammaA,gammaS) return(spectralabc(azero),spectralabc(azcbeta)) def matcroissance(betaa,betai,pii,gammai,gammaa): def a(t): return np.array([[pii*betai(t) -gammai,pii*betaa(t)], [(1-pii)*betai(t),(1-pii)*betaa(t)-gammaa]]) return(a) betaamax=0.25 betaimax=0.25 cbeta=0.8 pii=0.15 p=0.3 gammaa=0.1 gammai=0.05 betaa=tauxcontacper(betaamax,p,cbeta,T) betai=tauxcontacper(betaimax,p,cbeta,T) #plt.plot(tt,[betaa(s) for s in tt]) a=matcroissance(betaa,betai,pii,gammai,gammaa) spectralabc(a(1)),spectralabc(a(5)) #puis la on calcule la composee des exponentielles de matrices phiT=np.dot(expm(a(5)*(1-p)),expm(a(1)*p)) np.log(spectralrad(phiT)),p*spectralabc(a(1))+(1-p)*spectralabc(a(5)) #l'approximation du rayonspectral par l'integrale de l'abcisse spectrale #n'est pas si mauvaise que cela. #verifions que si gammai=gammaa, alors il n'y a qu'une classe d'infecte, et le rzero c'est beta/gamma b=matcroissance(betaa,betaa,pii,gammaa,gammaa) spectralabc(b(1)),spectralabc(b(5)) #on obtient les beta -gamma pour les deux périodes de temps phiT=np.dot(expm(b(5)*(1-p)),expm(b(1)*p)) np.log(spectralrad(phiT)),p*spectralabc(b(1))+(1-p)*spectralabc(b(5)) #tracons la courbe de Uri Alon sns.set(style="whitegrid") def ualon(cbeta,rzero=2.5): return( (1-rzero*(1-cbeta))/(rzero*cbeta)) #rzero=2.5 #utt=np.linspace(1-1/rzero,1,100) #plt.xlabel(r"$c_\beta$ : efficiency of social distancing") #plt.ylabel("p : proportion of freedom (no social distancing)") #plt.plot(utt,[ualon(i,rzero) for i in utt]) #mercredi premier avril 2020 #tracons le rayon spectral pour une periode en fonction de p, avec cbeta donne def lrsp(p,T=1): betaa=tauxcontacper(betaamax,p,cbeta,T) betai=tauxcontacper(betaimax,p,cbeta,T) #plt.plot(tt,[betaa(s) for s in tt]) a=matcroissance(betaa,betai,pii,gammai,gammaa) phiT=np.dot(expm(a(0.01*T)*p*T),expm(a(0.99*T)*(1-p)*T)) return((np.log(spectralrad(phiT)))/T) #ptt=np.linspace(0,1,100) #plt.plot(ptt,[lrsp(p,1) for p in ptt]) #on voit que cela ne depend presque pas de la periode #plt.plot(ptt,[lrsp(p,7) for p in ptt]) #lancons maintenant la recherche du point d'annulation brentq(lambda a: lrsp(a,T=7),0,1) #puis faisons le trace de la courbe p fonction de cbeta def siraipcbeta(T=1,nbpts=50): ctt=np.linspace(0,1,nbpts) l=[] for cbeta in ctt: def lrsp(p): betaa=tauxcontacper(betaamax,p,cbeta,T) betai=tauxcontacper(betaimax,p,cbeta,T) a=matcroissance(betaa,betai,pii,gammai,gammaa) phiT=np.dot(expm(a(0.01*T)*p*T),expm(a(0.99*T)*(1-p)*T)) return((np.log(spectralrad(phiT)))/T) if (lrsp(0)*lrsp(1)<0): p=brentq(lrsp,0,1) l.append([cbeta,p]) return(l) # l=np.array(siraipcbeta(T=7)) # f,ax=plt.subplots(2,1) # axc=ax[0] # axc.set_xlabel(r"$c_\beta$ : efficiency of social distancing") # axc.set_ylabel("p : proportion of freedom (no social distancing)") # axc.plot(utt,[ualon(i,rzero) for i in utt]) # axc.plot(l[:,0],l[:,1]) # axc=ax[1] # axc.plot(l[:,0],l[:,1]) #ecrivns une fonction que nous rendrons interactive def siraicov(betaA=0.25, betaS=0.25, piS=0.15,gammaA=0.1,gammaS=0.05,T=7,nbpts=50): ctt=np.linspace(0,1,nbpts) l=[] for cbeta in ctt: def lrsp(p): fbetaA=tauxcontacper(betaA,p,cbeta,T) fbetaS=tauxcontacper(betaS,p,cbeta,T) a=matcroissance(fbetaA,fbetaS,piS,gammaS,gammaA) phiT=np.dot(expm(a(0.99*T)*(1-p)*T),expm(a(0.01*T)*p*T)) return((np.log(spectralrad(phiT)))/T) if (lrsp(0)*lrsp(1)<0): p=brentq(lrsp,0,1) l.append([cbeta,p]) l=np.array(l) f,ax=plt.subplots(1,1) axc=ax axc.set_xlabel(r"$c_\beta$ : efficiency of social distancing") axc.set_ylabel("p : proportion of freedom (no social distancing)") axc.plot(utt,[ualon(i,rzero) for i in utt]) axc.plot(l[:,0],l[:,1]) def bsiraicov(betaA=0.25, betaS=0.25, piS=0.15,gammaA=0.1,gammaS=0.05,T=7,nbpts=50): ctt=np.linspace(0,1,nbpts) l=[] la=[] for cbeta in ctt: def lrsp(p): fbetaA=tauxcontacper(betaA,p,cbeta,T) fbetaS=tauxcontacper(betaS,p,cbeta,T) a=matcroissance(fbetaA,fbetaS,piS,gammaS,gammaA) phiT=np.dot(expm(a(0.99*T)*(1-p)*T),expm(a(0.01*T)*p*T)) return((np.log(spectralrad(phiT)))/T) if (lrsp(0)*lrsp(1)<0): p=brentq(lrsp,0,1) l.append([cbeta,p]) saz,sazcb=lesabcissesspec(betaA,betaS,piS,gammaA,gammaS,cbeta) #print("saz,sazcb",saz,sazcb) if (sazcb<0.0): #print("\t :saz,sazcb",saz,sazcb) la.append([cbeta,sazcb/(sazcb-saz)]) l=np.array(l) la=np.array(la) #print("l-la",l-la) f,ax=plt.subplots(1,1) axc=ax axc.set_xlabel(r"$c_\beta$ : efficiency of social distancing") axc.set_ylabel("p : proportion of freedom (no social distancing)") axc.plot(utt,[ualon(i,rzero) for i in utt],label="Ualon") axc.plot(l[:,0],l[:,1],label="true critical line") axc.plot(la[:,0],la[:,1],label="approximate critical line") axc.legend(loc='upper left') axc.set_title("T="+str(T)) #jeudi 2 avril 2020 : il faut que je verifie mon theoreme sur les abcisses spectrales A=lamat(betaamax,betaimax,pii,gammaa,gammai) B=lamat(betaamax*(1-cbeta),betaimax*(1-cbeta),pii,gammaa,gammai) [np.log(spectralrad(np.dot(expm(B*(1-p)*T),expm(A*p*T))))/T for T in 10*np.arange(1,40)] spectralabc(A)*p + spectralabc(B)*(1-p)#pas la meme quantite spectralabc(A)-np.log(spectralrad(expm(A)))#la cela coincide #il faut prendre T del 'orde de 400 pour que cela se rapproche!!! #on trace maintenant avec deux périodes pour en voir l'influence def bipersiraicov(betaA=0.25, betaS=0.25, piS=0.15,gammaA=0.1,gammaS=0.05,T1=7,T2=100,nbpts=50): #modif du 3 avril : il faut calculer le rzero pour ualon rzero=(piS*betaS/gammaS)+ ((1-piS)*betaA/gammaA) ctt=np.linspace(0,1,nbpts) l=[[],[]] for i, T in enumerate((T1,T2)): for cbeta in ctt: def lrsp(p): fbetaA=tauxcontacper(betaA,p,cbeta,T) fbetaS=tauxcontacper(betaS,p,cbeta,T) a=matcroissance(fbetaA,fbetaS,piS,gammaS,gammaA) phiT=np.dot(expm(a(0.99*T)*(1-p)*T),expm(a(0.01*T)*p*T)) return((np.log(spectralrad(phiT)))/T) if (lrsp(0)*lrsp(1)<0): p=brentq(lrsp,0,1) l[i].append([cbeta,p]) l=np.array(l) utt=np.linspace(1-1/rzero,1,20)#pour ualon f,ax=plt.subplots(1,1) axc=ax axc.set_xlabel(r"$c_\beta$ : efficiency of social distancing") axc.set_ylabel("p : proportion of freedom (no social distancing)") axc.plot(utt,[ualon(i,rzero) for i in utt],'bo',label="U Alon") axc.plot(l[0][:,0],l[0][:,1],label="T="+str(T1)) axc.plot(l[1][:,0],l[1][:,1],label="T="+str(T2)) axc.legend(loc='upper left') axc.set_title(r"critical curves : $p(c_\beta)$")