hsim/doc/remarques.typ

348 lines
16 KiB
Typst

#set par(justify: true)
= Version 1.
La phrase "it is less computationally intensive... the compiler". est mal dite;
tu peux dire que c'est la methode classique, par exemple, implementee pour
simulink et aussi Zelus.
Rmq:
- Les methodes numeriques (centralisees) les premieres ont ete faites
pour resoudre un probleme initial. dx/dt = f (x(t)) t et x(0) = x0 ou x est un
vecteur.
- La "simulation distribuee" (cad faisant intervenir plusieurs solveurs)
existe aussi mais pose d'autres problemes: efficacite, convergence. Elle est
plus difficile a implementer.
- Sundials CVODE a une methode centralisee mais avec une implementation de
manipulation des vecteurs qui peut etre parallele, cad que tous les calculs de
vecteur/matrice peuvent se faire en parallele. On ne l'utilise pas dans Zelus.
p2.
"we cannot necessarily use "pre"...": a mon avis, le lecteur ne peut pas
comprendre ce que tu ecris ici. A mon avis, tu peux dire ce qui marche (si je ne
me trompe pas, pouvoir internaliser le solveur au modele et donc le composer
avec un observateur qui contient son propre solveur) et ce qui est a faire (si
je comprends, pouvoir ecrire directement assert dans le code et la compilation
pour pouvoir co-simuler le modele et ses differents observateurs/assertions.
Pour le "pre", c'est un point que tu peux mentionner plus loin dans le rapport
lorsque le lecteur a plus de contexte et de matiere sur ce que tu as fait.
Il n'y a pas de numero en bas des pages dans ton texte. Il en faut. Impossible
de savoir ou on est sinon.
section 2. Tu parles de streams (Nat -> V) alors que tu donnes une semantique
avec des etats. C'est bizarre. Tu ecris pre(s) alors que l'on ne sait pas ce que
c'est. le
```ocaml
let rec (o, s) = M.f_step(i, M.s0 -> pre(s))
```
n'est pas du caml valide.
Que veux-tu dire ? Quel est le type de Simulate(M) ? Je pensais (cf. page
d'apres) que tu voudrais ecrire:
```ocaml
simulate(M): list(I) -> list(O)
```
Le listing 1 ne correspond pas a la page precedente (ou l'inverse). Pourquoi ?
Page d'apres (5 ?).
Je ne suis pas fan de l'exemple sincos_discrete() tel que tu l'as ecrit car il
diverge. Il laisse soupconner que l'on ne peut pas ecrire de schemas numeriques
avec des streams. C'est faux, en general.
En somme, le code listing 2 est un mauvais programme. Il y a une raison
mathematique liee a l'analyse des poles; je te montrerai a mon retour. Si tu
veux garder cet exemple de sin/cos, il faut mettre deux integrateurs differents,
un forward et un backward.
Ou alors, il faut faire un discours (plus long) pour expliquer pourquoi c'est
mieux d'ecrire la forme a temps continu, que justement, elle permet de ne pas se
casser la tete pour savoir ou et quand mettre un pre. Mais c'est un peu
orthogonal a ce que tu veux raconter.
Discrete models -> Discrete-time models.
Continuous models -> Continuous-time models.
Tu pourras ensuite dire que tu confonds les deux.
2.2 la raison de la divergence n'est pas la. Si tu prends un schema backward +
forward, ca ne diverge pas. Par contre, si tu prends Van der Pol en discret, pas
fixe, avec un pas trop petit ou trop petit, tu tombes sur nan. Regarde. J'avais
fait l'exemple (regarde sur le depot; ou refais le).
Rmq: sin/cos n'est pas un super exemple pour justifier l'interet de Zelus (ou du
temps continu en general) car ce systeme est lineaire. Un schema numerique pas
fixe (donc programmable directement en synchrone) marche bien. C'est plutot
quand la dynamique est compliquee, non lineaire, qu'il te faut un schema
numerique plus elabore et que l'expression directe d'un modele a temps continu
se justifie. La modelisation d'evenement en etat (zero-crossing) le justifie
aussi. Le cas classique, c'est le modele bang-bang. Tu veux detecter les
instants ou la temperature passe un seuil. Avec un modele de temps pas fixe, tu
ne peux pas.
avant de donner CNode(...), dit ce qu'est le probleme.
Qu'est ce qu'un modele M ?
```ocaml
model (i) = o where
der s = f_der i s
der o = f_out i s
```
2.3. Tu n'as pas dit/defini ce qu'etait un "initial value problem". Le faire
(sinon, on ne comprends pas).
"the integr node from Listing 2 is another example of a numerical solver
(albeit not a very good one)"
A mon avis, inutile. Que veux-tu dire que tu n'as pas deja dit (on peut calculer
une approximation de `(der(x)/dt)(t)` a des instants `n * h` (`n in Nat`) par
`(x - pre(x))/h`?
"Of particular interest is the fact that numerical ODE solvers compute
approximations sequentially. "
Ca depend. Les solveurs a memoire (dits "multi-pas"). Les solveurs sans memoire
tels que RK, non. A mon avis, tu peux commencer par exempliquer ce que calcule
un solveur: etant donne le IVP, l'objectif est de calculer une solution
[0, tmax] -> V. En pratique, il ne calcule pas toute la solution. Il calcule une
suite de solution pour [0, h0][h0, h1][h1, h2], etc. Relis l'article de
Chapoutot et al., de memoire, c'est tres bien explique. Sinon, il y a les livres
jaunes dans l'etagere de mon bureau.
"This sequential process gives way to a synchronous interpretation of an ODE
solver as a discrete node."
Qu'est-ce qu'un "discrete node" ?
IVP(Y, Y'). Aurait du arriver bien plus tot.
dy /dt (t) = f t (y(t))
y(0) = y0
donner l'horizon de temps (par defaut, +infty ?).
Je prendrais une autre lettre que "s". (on note s pour "state" en general). "o",
pour "output" ?
La notation pointee est un peu troublante (en math, on la confond avec la
multiplication. Utiliser une police ad-hoc pour h et u de sorte que s_0.u ne
soit pas ambigu.
mets des numeros de ligne dans ton texte stp. Il y a un style latex pour ca. Ou
au moins des no. de page.
"The ODE solver does not itself introduce discontinuities; the only
discontinuities in the system are those introduced by the input signal."
Avant de dire cela, tu ne parles par d'entrees. Pour le moment, ton systeme
n'est pas "hybride". C'est une ODE. Tu ne donnes pas d'hypotheses sur f. En
faut-il ? Lesquelles ?
"The simulation of a continuous-time system with an ODE solver is now itself a
synchronous node:"
c'est un point de vue. Puisque la simulation d'un modele a temps continu calcule
une suite de solutions approchees, ne pourrait-on pas la voir elle meme comme
une machine synchrone qui...
page suivante.
Plutot que Signal(V), j'utiliserais un autre nom. Tu as deja un langage qui
manipule des signaux, non ?
Superdense(V) ? En reference aux travaux de Pnueli et al. Puis Edward Lee et al.
Puis Caspi et al.
Superdence(V) = R+ -> Nat -> V avec, a cote, une fonction qui pour chaque t in
R+, donne le nombre de sauts (relire les articles; j'ai oublie le nom de cette
fonction). step(t) in Nat.
est-ce tres different de
Nat -> R+ -> V avec a cote, une fonction qui indique le temps qui s'ecoule pour
chaque n in Nat ?
Dans un des articles de Edward Lee, il explique le type des signaux pour le
temps continu. Regarde son livre (vert) sur mon etagere.
Le texte de cette page (8 ?) est un peu confus.
est-ce que les bouts de fonctions sont collees les uns aux autres ?
none a le sens de "not yet" ? Comment recolles-tu les morceaux ?
(h0, u0) (h1, u1) ... (hn, un)
est-ce equivalent a :
(h0, u0) none (h1, u1) none none (hn, un) ?
A ce stade, tu n'as pas dit ce qu'etait $italic("CNode")(I, O, S_M, S'_M)$. A
quoi ca ressemble ?
Les elements du listing 4 doivent etre donnes dans le texte en maths. Le code
caml doit etre mis aussi dans le listing 4. Je comprends bien mieux le code que
les explications ! Sois plus precis dans le texte, ca aidera a comprendre.
utiliser hmax plutot que h pour ivp. Eviter les surcharges de noms autant que
possible.
Plutot que "discrete node", utiliser "synchronous machine" ? Le terme "machine"
est un terme technique des annees 60/70. Cf. articles historiques sur les
automates et les "sequential machines". Tu peux dire, qui se caraterise par un
etat initial, une fonction step lisant une entree et produisant une sortie,
(plus une fonction reset) si tu veux.
"Since time is logical in discrete nodes". Un peu trop pedant (et obscur) a mon
avis. On manipule des suites de valeurs; il n'y a donc pas de temps reel ou
physique. Le temps est juste la succession des valeurs.
Le paragraphe "The question of discrete events..." est un peu confus. Donne un
exemple. E.g., un timer: un controleur ouvre un robinet pendant 4s; une lumiere
doit clignoter en alternant allume/eteint 1s/2s. ce sont des cas ou il y a des
evenements en temps, cad en reference a la variable t (der t = 1 init 0).
D'autres evenements ne sont pas des evenements en temps. E.g., une roue qui
tourne (e.g. volant moteur). Compter le nombre de tours de roue par seconde avec
un capteur. Le schema general est dit de "Zero-crossing". Etc. La balle qui
rebondit, etc. Tu en trouveras d'autres !
La suite est pas mal. Il faut expliquer (et possiblement donner le code, au
moins en annexe) pour 2.5, 2.6, 2.7.
Ca prend forme. Tu peux donner l'intuition de la compilation. Dans le source, on
melange les der, present, up, etc. et le compilo., apres une analyse statique
(qui va verifier des proprietes et donc rejeter certains programmes), va
produire les differentes fonctions necessaires a la simulation qui alterne des
phases d'integration (le temps ronronne) et des pas discrets (reactions
instantanees).
Super. Continue ! --Marc
#pagebreak()
= Version 2.
*L.230 - 235*. Le discours peut donner l'impression de confondre simuation et
modèle mathématique. Tu écris un modèle mathématique idéalisé, c.à.d. avec un
choc élastique la vitesse change instantanément de direction. Pour cela, la
manière de simuler doit changer. La, tu peux garder le discours.
"_Since time is logical in discrete nodes_". Tu veux dire plutôt que l'on
choisit de décrire des réactions en temps zéro (ou instantanées), c'est bien
ça ? "_Since time is logical in discrete nodes, nothing tells us when, in
continuous time, we should perform discrete steps._" Je ne comprends pas cette
phrase !
*L. 242-245*. Si tu veux définir le zéro-crossing, ne faudrait-il pas plutôt le
faire avec une définition d'analyse d'abord et décrire ensuite, si besoin
l'algorithme (mais informellement) ? L'intuition, c'est qu'il y a un
zéro-crossing de $z$ en $t_0$, entre $t_"left"$ et $t_"right"$ lorsque il existe
une boule d'épaisseur non nulle autour de $t_0$ (d'épaisseur $epsilon$) telle
que pour tous les points a gauche de t0 (notons
$t_0^- = { t | t <= t_0 and |t_0 - t| <= epsilon }$), $z(t_0^-) <= 0$ et tous
les points a droite, $z(t_0^+) > 0$. Tim t'as donné l'article qui décrit l'algo.
Illinois. Je ne l'ai pas sur moi. Le signal $z: [t_"left", t_"right"]$ a un
zéro-crossing en t0 lorsque il existe un $epsilon > 0$ tq pour tout
$alpha < epsilon$: ... . Qu'en penses-tu ?
*Listing 5*. Tu n'expliques pas `last y'`.
*P.10*. Tu devrais d'abord expliquer le modele mathématique, ce dont tu as
besoin, puis l'exemple; ou bien l'inverse, expliquer d'abord intuitivement
l'exemple, les ingrédients dont tu as besoin et que tu introduits, plus le
modèle mathématique. Et ensuite, les choses dont tu as besoin pour simuler.
E.g., connaitre $f_"der"$, $f_"zero"$, l'état initial continu, l'état discret,
etc.
*L.302*.
Je trouve l'écriture $h in [0, v.h]$ un peu troublante. Est-ce qu'une notation
$v\#h$ ou autre ne serait pas mieux ? Ou alors, utiliser plutôt un champ
"horizon" que h, dans la notation en point. Ou "right" ?
"_Multiple methods exist (Zélus uses the Illinois method [Sny53])_". La méthode
Illinois est la plus connue et utilisée. C'est mal formulé. Multiple methods
exist; one of the oldest and most-used method is the Illinois method. It is
used, for example, in the Sundials CVODE suite (donner la référence; regarde
le manuel). Simulink also used this method by default. Zelus also implements
this method.
*L.305-309*.
C'est un peu confus. Dis simplement ce que fait une méthode de zéro-crossing et
des ingrédients dont elle a besoin, avant d'expliquer, plus tard, comment on
s'en sert dans la simulation.
Tu as besoin de $g: T i m e -> X -> Z_o$; de $x_0: X$; de $t_"left"$, de
$t_"right"$ et de $d e n s e: T i m e -> X$, défini sur cet intervalle. La
fonction de zéro-crossing indique qui, sur le vecteur $Z_o$, traverse zéro. Tu
peux signaler les difficultés éventuelles (on peut rater un événement, c'est
sensible a la largeur de l'intervalle de détection, au fait que le nombre de
traversées peut être paire et on rate l'événement, etc.). Et dire que on ne fait
rien dessus (pas plus que Simulink, Modelica, et les autres d'ailleurs).
*L. 322-324*. Je ne comprends pas la définition entre la ligne 322 et 324 et pas
bien le paragraphe précédent.
*L. 418*. Tu veux plutôt dire que tu voudrais pouvoir agréger les solutions
denses successives ($d k y$). Les solveurs classiques sont impératifs,
c'est-à-dire qu'ils ont un état interne et que chaque appel à "step" le modifie
physiquement. Pour pouvoir agréger plusieurs solutions successives, il faut
qu'il fournisse un moyen de le faire. (Rmq: ce n'est pas forcément une "copie
d'état" dont on a besoin. Pour RK, je l'ai fait en fournissant un moyen d'avoir
une copie de $d k y$. Ça suffit.)
*L. 459*. Si tu parles d'assertions dans les programmes, cite/lis les articles
classiques car c'est une construction très ancienne des langages de
programmation. Je ne suis pas spécialiste mais j'en ai lu deux vieux (de
mémoire, un de Hoare; un de Dijsktra). Je suis sûr qu'il doit y avoir un article
de survey que tout le monde cite la dessus. Je regarderai en rentrant. En somme,
dis aussi pourquoi c'est intéressant/utile de pouvoir écrire des assertions et
les difficultés que cela pose dans le cas présent.
"_An important property of assertions is that they are transparent: their
presence does not affect the result of the computation._" An expected feature of
run-time assertions is that they should not affect the rest of the computation
(except stopping execution when they are not fulfilled). We call them
"transparent", in the sense that, running the program with or without, if no
error is raised, should produce the same result.
*Figure 9*. Je ne comprends pas la figure 9. Tu veux dire que, en Lustre, cela
correspond à avoir un seul noeud qui calcule les deux en parallèle ? On n'écrira
jamais le code de la partie droite. Relis l'article sur les assertions de Lustre
(de memoire, AMAST 93). En Lustre, les assertions ont un role qui consiste à
contraindre l'environnement, avant tout. C'est utile quand on veut vérifier des
propriétes. En fait, une assertion se decompose en deux parties, une hypothèse
(qui parle des entrées, incontrolâbles), et une conclusion (assume/guarantee).
Dans notre cas, comme on veut s'en servir d'abord comme on le fait dans un
langage généraliste et, pour le moment, pas pour faire de la vérification, on ne
distingue pas les deux. Le programme de gauche est equivalent à
```
let node f (x) =
let v = ... in
let assertion = (let p = integr(0.0, v) in p >= 0.0) in
(v, assertion)
```
c.à.d. que assertion est un flot comme les autres. Est-ce autre chose que cela
que tu veux dire ?
*L. 477*.
Pas vraiment. Un noeud Lustre avec une assertion a vérifier dynamiquement,
s'implémente en calculant un flot supplementaire et en vérifiant qu'il est vrai
à chaque instant. On le calcule donc avec le reste du code, comme on le fait
habituellement pour les assertions dans les langages classiques. Attention: je
ne parle pas ici de vérification formelle. On traite de manière particulière les
assertions quand on cherche a vérifier une propriété. En Lustre, on considère
que les assertions sont vraies et on vérifie qu'elles ne dépendent pas des
sorties; sinon, elle ne sont pas causales. C'est pour cela, qu'il faut
distinguer les hypothèses (assume) des résultats attendus (guarantee).
Il n'y a aucun exemple ?