6
C. Caire 2015 CCP MP SI - Infotmatique - Corrigé 1/6 Ce fichier est issu du site http://sites.google.com/site/concourscpgecorrections/home Toute copie sur un autre site est illégale et s’est faite sans l’aval de l’auteur. CCP – SI Proposition de corrigé de la partie IPT Ce corrigé ne s’intéresse qu’à la partie « Python » du sujet posé aux CCP à l’épreuve de SI (MP 2015) Question 11 : La méthode d’Euler est une méthode de premier ordre, on remplace la dérivée par l’accroissement de la tangente entre deux échantillons successifs : lim ሺ௧ାሻሺ௧ሻ ቁൎ ାଵ . L’erreur commise est d’ordre deux, elle n’est guère recommandée si les phénomènes sont du même ordre (c’est le cas ici sauf si l’amortissement est dominant). On obtient l’équation aux différences : ାଵ ܨ ݐ , Question 12 : La fonction ܨݐሻ൯ est donnée par l’énoncé : On évitera bien sur l’implémentation directe de cette « formule », introduisons des paramètres de réduction. On pose : 2 ݖ et ߙ 5 ி ሺோሻ On a alors : ܨݐሻ൯ ൌ ൬ ߠ ߙ sinሺ ݐሻ cosሺߠሻെ2 ݖ ߠ sinሺߠLes constantes seront passées en paramètres, l’autre solution consiste à les déclarer en variable globale (allergie personnelle) ou à les déclarer à l’intérieur de la fonction fi (mais l’énoncé n’en fait pas mention). Il suffit d’implémenter le code correspondant : # constantes réduites w0=np.sqrt(5/7*g/(R-r)) z=5/14*fv/m/w0 a=5/7*F0/m/(R-r)/w0**2 # Tuple de transfert cTuple=(wbob,w0,z,a) def fi(t,Y,cT=cTuple): """Données : t et Y les valeurs discrètes d'indice i le vecteur Y est un ndarray numpy cT est un Tuple passant les constantes utilisées """ # onrenvoie directement le vecteur F(ti,Y(ti)) wbob,w0,z,a=cT return np.array([Y[1],a*w0**2*np.sin(wbob*t)*cos(Y[0])-2*z*w0*Y[1]-w0**2*Y[0]]) Question 13 : On prend soin d’identifier les variables d’entrée et de sortie. On crée ces dernières et on itère sur l’équation aux différences. On utilise le slicing pour transférer, affecter les éléments du tableau. Si SY est la base de travail, on remarque que la forme de fin n’est pas optimale en termes de paramètres d’entrée. Pour afficher la variable de retour on utilisera la fonction affichage suivante : def affichage(SY): plt.clf() # Efface le graphique précédent plt.plot(SY[:,0],SY[:,1],"b") # trace la courbe plt.title("Réponse temporelle") # Titre plt.xlabel("Temps (s)") # légende de l'abscisse plt.ylabel("Theta (rad)") # légende de l'ordonnée plt.show()

2015 CCP SI - informatique - corrigé .pdf

Embed Size (px)

Citation preview

Page 1: 2015 CCP SI - informatique - corrigé .pdf

C. Caire 2015 CCP MP SI - Infotmatique - Corrigé 1/6 Ce fichier est issu du site http://sites.google.com/site/concourscpgecorrections/home Toute copie sur un autre site est illégale et s’est faite sans l’aval de l’auteur.

CCP – SI Proposition de corrigé de la partie IPT

Ce corrigé ne s’intéresse qu’à la partie « Python » du sujet posé aux CCP à l’épreuve de SI (MP 2015) Question 11 : La méthode d’Euler est une méthode de premier ordre, on remplace la dérivée par l’accroissement de la tangente entre deux échantillons successifs : lim

→.

L’erreur commise est d’ordre deux, elle n’est guère recommandée si les phénomènes sont du même ordre (c’est le cas ici sauf si l’amortissement est dominant). On obtient l’équation aux différences : , Question 12 : La fonction , est donnée par l’énoncé :

On évitera bien sur l’implémentation directe de cette « formule », introduisons des paramètres de réduction. On pose : 2 et 5

On a alors : , sin cos 2 sin

Les constantes seront passées en paramètres, l’autre solution consiste à les déclarer en variable globale (allergie personnelle) ou à les déclarer à l’intérieur de la fonction fi (mais l’énoncé n’en fait pas mention). Il suffit d’implémenter le code correspondant : # constantes réduites w0=np.sqrt(5/7*g/(R-r)) z=5/14*fv/m/w0 a=5/7*F0/m/(R-r)/w0**2 # Tuple de transfert cTuple=(wbob,w0,z,a) def fi(t,Y,cT=cTuple): """Données : t et Y les valeurs discrètes d'indice i le vecteur Y est un ndarray numpy cT est un Tuple passant les constantes utilisées """ # onrenvoie directement le vecteur F(ti,Y(ti)) wbob,w0,z,a=cT return np.array([Y[1],a*w0**2*np.sin(wbob*t)*cos(Y[0])-2*z*w0*Y[1]-w0**2*Y[0]]) Question 13 : On prend soin d’identifier les variables d’entrée et de sortie. On crée ces dernières et on itère sur l’équation aux différences. On utilise le slicing pour transférer, affecter les éléments du tableau. Si SY est la base de travail, on remarque que la forme de fin n’est pas optimale en termes de paramètres d’entrée. Pour afficher la variable de retour on utilisera la fonction affichage suivante : def affichage(SY): plt.clf() # Efface le graphique précédent plt.plot(SY[:,0],SY[:,1],"b‐") # trace la courbe plt.title("Réponse temporelle") # Titre plt.xlabel("Temps (s)") # légende de l'abscisse plt.ylabel("Theta (rad)") # légende de l'ordonnée plt.show()

Page 2: 2015 CCP SI - informatique - corrigé .pdf

C. Caire 2015 CCP MP SI - Infotmatique - Corrigé 2/6 Ce fichier est issu du site http://sites.google.com/site/concourscpgecorrections/home Toute copie sur un autre site est illégale et s’est faite sans l’aval de l’auteur.

Le code de la fonction Euler peut avoir l’allure suivante : def Euler(Yini,h,Tmaxi,F): """ Données : Yini conditions initiales ndarray dim 2 h,Tmaxi scalaires F fonction (ici la fi précédente) le retour est censé être un ndarray à 2 dimensions SY""" # création d'un ndarray comportant les ti # utilisation de la fonction ceil pour éviter la plaisanterie d'un Tmaxi non multiple de h t=np.arange(np.ceil(Tmaxi/h))*h # nombre d'éléments du tableau Nb=len(t) # Initialisation de SY et première affectation SY=np.empty((Nb,3)) # déclaration du tableau SY[:,0]=t # remplissage de la première colonne avec t SY[0,1:]=Yini # Utilisation des conditions initiales for i in range(1,Nb): # Boucle sur le nombre d'élements moins l'initial SY[i,1:]=SY[i-1,1:]+h*F(t[i-1],SY[i-1,1:]) # Equation aux différences return SY Voici deux courbes de réponse obtenues avec les mêmes paramètres à l’exception de h :

On remarque sans peine que si la première réponse peut paraitre crédible il n’en est rien de la seconde qui diverge joyeusement. La « robustesse » de la méthode est modeste ! h a été sur la deuxième figure multipliée par 10.

Page 3: 2015 CCP SI - informatique - corrigé .pdf

C. Caire 2015 CCP MP SI - Infotmatique - Corrigé 3/6 Ce fichier est issu du site http://sites.google.com/site/concourscpgecorrections/home Toute copie sur un autre site est illégale et s’est faite sans l’aval de l’auteur.

Question 14 : La méthode d’Euler s’incarne dans l’équation aux différences : , Elle consiste à calculer les N éléments du tableau alors que , est en 1 La détermination des sera donc en ou . Si on divise h par 10 on multiplie d’autant N, le temps de calcul sera donc dix fois plus important mais on divisera l’erreur de l’algorithme par 100 (en ). Question 15 : Hors singularité nous avons : sin sin cos On fait le quotient et on exploite les variables réduites : sin sin sin On utilise le slicing qui se fera sur les valeurs indexées de 0 à N-2 car on a besoin de calculer les valeurs aux temps i et i+1. La recherche du non-respect de la condition se fait en utilisant une technique de masquage. Le code est le suivant : def VerifRSG(SY,f,cT=cTuple): """Données : SY contient temps, angle et vitesse angulaire f est le coefficient de frottement cT est un Tuple passant les constantes utilisées """ # on récupère les constantes Nb=SY.shape[0] #nombre de points wbob,w0,z,a=cT # constantes réduites du système h=SY[1,0] # valeur de h # On créée le tableau |Ti/Ni| indexé de 0 à Nb-2 et non Nb-1 # car on a besoin d'un terme en i+1 FY=np.abs(2/7*(SY[1:,2]-SY[:-1,2])/h/(a*w0**2*np.sin(wbob*SY[:-1,0])*np.sin(SY[:-1,1])+5/7*(SY[:-1,2])**2+w0**2*np.cos(SY[:-1,1]))) # Utilisation d'un masque binaire FY>f # FY>f n'est vrai que pour les valeurs qui correspondent à un glissement # FY[mask] ne renvoie que les valeurs qui ne respectent pas la condition FY=FY[FY>f] # un size non nul renvoie un faux # car il existe alors au moins une valeur qui glisse return not(bool(FY.size)) Question 16 : On exploite les graphes pour notre analyse… Les courbes suivantes apparaissent comme « stables » (faibles valeurs des angles, caractère borné des fluctuations).

Page 4: 2015 CCP SI - informatique - corrigé .pdf

C. Caire 2015 CCP MP SI - Infotmatique - Corrigé 4/6 Ce fichier est issu du site http://sites.google.com/site/concourscpgecorrections/home Toute copie sur un autre site est illégale et s’est faite sans l’aval de l’auteur.

A l’inverse les deux courbes ci-après ont une amplitude crête qui ne cesse de croitre, elles sont associées à des phénomènes qui paraissent divergents.

Les 14a et 14c correspondent à des courbes qui valident les conditions de linéarisation. C’est d’ailleurs confirmé par les solutions qui sont voisinent de la somme de la réponse libre d’un oscillateur linéaire et de sa réponse commandée (une simple sinusoïde à la pulsation de contrainte). Question 17 : Le tableau de mesures nommé comporte éléments. Pour réponde aux besoins de l’énoncé nous devons construire un estimateur de pertinence, c’est la fonction déterminée sur une sous partie du tableau et qui ne comportera que éléments avec

. La valeur efficace définie se confond avec la racine de la variance (écart type) si le signal étudié est alternatif, elle s’en distinguera si la moyenne du signal est non nulle. La complexité est en . Il faut multiplications (élévations au carré), additions (la somme), une division par N (une opération) et une extraction de racine (1 opération mais plus complexe) On code la fonction en utilisant le slicing classique de numpy et en suppose qu’il n’y a pas de débordement d’indice possible (ouille !) def Valeur_efficace(T,a,b): """T est le tableau de mesures numpy a indice de départ b nombre d'élements de la porte à prendre en compte""" # simple, on extrait la partition de T utile # on multiplie avec le produit matriciel => produit scalaire # on divise par b et on prend la racine return np.sqrt(T[a:a+b].dot(T[a:a+b])/b) Question 18 : Voici le code de l’algorithme proposé et codé en Python brutalement def Temps_coagulation(M,Te,N): Nmaxi=len(M) # taille du tableau en O(1) en python Xeff0=Valeur_efficace(M,0,N) # fonction en O(N) i=0 # temps constant en O(1) Xeff=Xeff0 # temps constant en O(1) while Xeff>0.7*Xeff0 and i<Nmaxi-N: # pire des cas en Nmaxi-N Xeff=Valeur_efficace(M,i,N) # fonction en O(N) i+=1 # temps constant en O(1) if i==Nmaxi-N: # temps constant en O(1) raise NameError("Devine qui a raté sa mesure ?") # temps constant en O(1) return i*Te/1000 # temps constant en O(1)

Page 5: 2015 CCP SI - informatique - corrigé .pdf

C. Caire 2015 CCP MP SI - Infotmatique - Corrigé 5/6 Ce fichier est issu du site http://sites.google.com/site/concourscpgecorrections/home Toute copie sur un autre site est illégale et s’est faite sans l’aval de l’auteur.

Les différentes opérations sont identifiées par leur complexité. On peut remarquer que certaines de ces complexités dépendent du langage et du type de variable, la détermination de la taille d’une liste chainée (mauvais choix pour un tableau) est en et non en temps constant. La complexité du code proposé est en C’est en effet la boucle while opérée dans le pire des cas fois qui va multiplier la complexité de la fonction valeur_efficace. Si on modifie la ligne 7 la complexité dans la boucle n’est plus en mais en

3 ce qui est équivalent à . La complexité globale est alors en max , Remarque : le code proposé est alors faux, le concepteur du sujet a oublié que la valeur efficace est une moyenne pondérée sur N éléments, il aurait dû proposer :

Question 19 : Une pile n’est pas adéquate car le premier élément rentré dans la structure doit être le premier sorti, il nous faut du FIFO (file) et non du LIFO (last in first out = stack = pile). Question 20 : Le code demandé est du type ci-après : def Init_tampon(N,Te): fifo=creer_file() # creer une file vide fifo for i in range(N): # Boucler N fois enfiler(fifo,Mesure(T)) # Insérer N fois les résultats de mesure dans fifo return fifo def Temps_coagulation(Te,N,Nmaxi): """Erreur probable de l'énoncé qui donne M en paramètre M ne sert plus à rien car on travaille en temps réel N ne peut être deviné il faut donc l'importer""" T=Init_tampon(N,Te) # crée et initialise le tampon Xeff0=Valeur_efficace(T) # fonction en O(N) i=0 # temps constant en O(1) Xeff=Xeff0 # temps constant en O(1) while Xeff>0.7*Xeff0 and i<Nmaxi-N: # pire des cas en Nmaxi-N a=Mesure(Te) # faire une nouvelle mesure O(1) enfiler(T,a) # stocker l'élément dans la file O(1) b=defiler(T) # enlever un élément de la file O(1) Xeff=np.Sqrt(Xeff**2+(a**2-b**2)/N) # modification de Xeff en O(1) i+=1 # temps constant en O(1) if i==Nmaxi-N: # temps constant en O(1) raise NameError("Devine qui a raté sa mesure ?") # temps constant en O(1) return i*Te/1000 # temps constant en O(1) def Valeur_efficace(fifo): """fifo est une file il faut "caster" cette file sur un tableau numpy""" T=np.array(fifo) return np.sqrt(T.dot(T)/len(T)) la première fonction crée une file fifo et la remplit de N mesures issue de Mesure(Te).

Page 6: 2015 CCP SI - informatique - corrigé .pdf

C. Caire 2015 CCP MP SI - Infotmatique - Corrigé 6/6 Ce fichier est issu du site http://sites.google.com/site/concourscpgecorrections/home Toute copie sur un autre site est illégale et s’est faite sans l’aval de l’auteur.

La deuxième fonction proposée dans l’énoncé est « bugguée » dans son initialisation (erreur Nmaxi , N). On procède à l’identique jusqu’à la boucle while, point ou on utilisera la structure « file » proposée. Le calcul de l’itération suivante de Xeff est fait en modifiant la formule de l’énoncé qui a »oublié » de prendre en compte le poids en 1/N de chaque élément dans la somme. Enfin valeur_efficace doit être modifié pour accepter une « file » et non un ndarray (numpy)… On pourra remarquer qu’ici la « file » ne sert à rien car elle duplique les données de M en cours d’utilisation et que l’opérateur/codeur dispose de tous les éléments pour déterminer ces données. C’est donc juste un exercice de style !

Fin