File: rpem.f

package info (click to toggle)
scilab 2.4-1
  • links: PTS
  • area: non-free
  • in suites: potato, slink
  • size: 55,196 kB
  • ctags: 38,019
  • sloc: ansic: 231,970; fortran: 148,976; tcl: 7,099; makefile: 4,585; sh: 2,978; csh: 154; cpp: 101; asm: 39; sed: 5
file content (202 lines) | stat: -rw-r--r-- 6,539 bytes parent folder | download | duplicates (14)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
C/MEMBR ADD NAME=RPEM,SSI=0
      subroutine rpem(theta,p,n,u,y,lambda,k,c,istab2,v,eps,
     &  eps1,idim,fi,psi,tstab,work,f,g,l)
c!but
c        -1           -1           -1
c     a(q  )y(t) = b(q  )u(t) + c(q  )e(t)
c
c!parametres
c
c     ***description des parametres***
c
c     theta - vecteur d'ordre (3*n) qui contienne les parametres
c             de estimation
c             theta=(a(1) ...a(n),b(1) ...b(n), c(1) ...c(n)
c             theta est changee dans la subroutine
c     p     - matrice symetrique d'ordre (3*n)
c             p est employee dans la forme u-d
c             p=u*d*u(transposee)
c             avec d diagonale et u triangulaire superieure
c             les elements de d sont conserves dans la diagonale de d
c             les elements de u sont gardes dans la partie diagonale
c             superieure de p. p est changee dans la subroutine.
c     n     - modele d'ordre (min 1, max 10)
c     u     - derniere valeur d'entree
c     y     - derniere valeur de sortie
c     lambda- facteur d'oubli (a fournir)
c     k     - facteur de contraction employe pour le filtrage
c             des donnees (a fournir)
c             commentaire:
c             pour des resultats raisonnables
c             0.lt.lambda.le.1
c             lambda proche de 1 apres plusieurs appels a rpem
c             0.lt.k.lt.1
c             k proche de 1 apres plusieurs appels a rpem
c     c     - parametre employe pour la regularisation
c             c doit etre choisi plutot grand
c     istab1- flag (a fournir) pour les tests d'estabilite de c(z).
c             si istab1=0 on n'execute pas des controles (test
c             d'estabilite et reductions de pas)
c             si istab1.ne.0 on execute des controles (test
c             d'estabilite et eventuelles reductions de pas)
c     istab2- entier donne en sortie qu'indique le nombre des
c             reductions de pas executees. si istab1=0,
c             alors la valeur de istab2 n'est pas significative
c     v     - fonction de perte- addition des carres des erreurs
c             predis. une modification due a des incertitudes dans
c             la phase transiente est inclue
c             v est changee par la subroutine
c     eps   - erreur de prediction (retourne)
c     eps1  - residu(retourne)
c     init  - flag employe pour commencer la prediction
c             si init=0 tous les parametres sont mis a jour
c             si init.ne.0 des valeurs initiaux adequats sont
c             mis en premier et apres les parametres sont mis
c             en employant les donnees disponibles u et y
c     po    - parametre scalaire employe pour donner a p une
c             valeur initiale (a etre fourni quand init.ne.0)
c             if init.ne.0 p=po*matrice unitaire
c     idim  - parametre de dimension
c
c!subroutines necessaires
c     nstabl
c!
      double precision theta(*),p(idim,*),u,y,c,eps,eps1,po
      double precision fi(*),psi(*),tstab(*),work(*),f(*),g(*)
      double precision lambda,k,l(*)
      double precision amy,y1,u1,e1,ci,alfa,gamma,beta,dd,al,s,v
c
      nn=n*3
c     ========================================
c     test pour initialisation
c     ========================================
      init=0
      istab1=1
      po=1
      if (init.eq.0) goto 100
c
      v=0.0d+0
      do 10 i=1,nn
      do 10 j=1,nn
10    p(i,j)=0.0d+0
      do 20 i=1,nn
      p(i,i)=po
      theta(i)=0.0d+0
      l(i)=0.0d+0
      fi(i)=0.0d+0
20    psi(i)=0.0d+0
c     ========================================
c     calcul de l'erreur de prediction
c     ========================================
100   eps=y
      do 110 i=1,nn
110   eps=eps-fi(i)*theta(i)
c     ========================================
c     calcul des nouvelles estimations de parametres
c     ========================================
      amy=1.0d+0
c     ========================================
c     test pour determiner si on fait des controles
c     ========================================
      if(istab1.eq.0) goto 200
      istab2=0
120   do 130 i=1,n
      ni=2*n+i
130   tstab(i+1)=theta(ni)+l(ni)*eps*amy
      tstab(1)=1.0d+0
c     ========================================
c     test pour stabilite de c(z)
c     ========================================
      call nstabl(tstab,n,work,ist)
      if (ist.eq.0) goto 200
      amy=amy/2.0d+0
      if(1.0d+0+amy.le.1.0d+0) goto 200
      istab2=istab2+1
      goto 120
c     ========================================
c     mise a jour de parametres d'estimation
c     ========================================
200   do 210 i=1,nn
210   theta(i)=theta(i)+l(i)*eps*amy
c     ========================================
c     calcul residus
c     ========================================
      eps1=y
      do 220 i=1,nn
220   eps1=eps1-fi(i)*theta(i)
c     ========================================
c     calcul des signaux filtrees y1, u1, e1
c     ========================================
      y1=y
      u1=u
      e1=eps1
c
      do 620 i=1,n
      ci=theta(2*n+i)*k**i
      y1=y1+ci*psi(i)
      u1=u1-ci*psi(n+i)
620   e1=e1-ci*psi(n*2+i)
c     ========================================
c     mise a jour des vecteurs fi et psi
c     ========================================
      if(n.eq.1) goto 720
      do 700 j=2,n
      i=n+2-j
      fi(i)=fi(i-1)
      psi(i)=psi(i-1)
      i=2*n+2-j
      fi(i)=fi(i-1)
      psi(i)=psi(i-1)
      i=3*n+2-j
      fi(i)=fi(i-1)
700   psi(i)=psi(i-1)
720   fi(1)=-y
      psi(1)=-y1
      fi(n+1)=u
      psi(n+1)=u1
      fi(2*n+1)=eps1
      psi(2*n+1)=e1
c     ========================================
c     calcul du vecteur de gain l, mise a jour de p et v
c     ========================================
      do 810 i=2,nn
      j=nn+2-i
      alfa=psi(j)
      j1=j-1
      do 800 kk=1,j1
800   alfa=alfa+p(kk,j)*psi(kk)
      f(j)=alfa
810   g(j)=p(j,j)*alfa
      g(1)=p(1,1)*psi(1)
      f(1)=psi(1)
c
      alfa=lambda+f(1)*g(1)
      gamma=0.0d+0
      if (alfa.gt.0.0d+0) gamma=1.0d+0/alfa
      if(g(1).ne.0.0d+0) p(1,1)=gamma*p(1,1)
c
      do 830 j=2,nn
      beta=alfa
      dd=g(j)
      alfa=alfa+dd*f(j)
      if(alfa.eq.0.0d+0) goto 830
      al=-f(j)*gamma
c
      j1=j-1
      do 820 i=1,j1
      s=p(i,j)
      p(i,j)=s+al*g(i)
820   g(i)=g(i)+dd*s
      gamma=1.0d+0/alfa
      p(j,j)=beta*gamma*p(j,j)/lambda
      p(j,j)=min(p(j,j),c)
830   continue
c
      v=v+eps**2/alfa
      do 840 i=1,nn
840   l(i)=g(i)/alfa
c     ========================================
c     fin des calculs
c     ========================================
      return
      end