File: anfm06.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 (219 lines) | stat: -rw-r--r-- 7,927 bytes parent folder | download | duplicates (3)
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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
C/MEMBR ADD NAME=ANFM06,SSI=0
      SUBROUTINE ANFM06(Z,IZ,R,IR,W,IPVT,N,M,IND,IO)
C
C***********************************************************************
C                                                                      *
C                                                                      *
C     ORIGEN:           Eduardo Casas Renteria                         *
C                       Cecilia Pola Mendez                            *
C                                                                      *
C       Departamento de Matematicas,estadistica y Computacion          *
C       -----------------------------------------------------          *
C                       UNIVERSIDAD DE CANTABRIA                       *
C                       ------------------------                       *
C                               MAYO  1987                             *
C                                                                      *
C***********************************************************************
C
C     OBJETIVO:
C        Esta subrutina modifica la factorizacion de Cholesky (LL') de
C        una matriz del tipo  PAP' ,(P  es una matriz de permutacion y
C        A es del tipo Z'HZ), cuando a Z se le a|ade una columna.  En Z
C        la columna a|adida es la que ocupa el ultimo lugar.
C
C     LISTA DE LLAMADA:
C     DE ENTRADA:
C
C        Z      Matriz de dimension (IZ,M+1). En sus  N  primeras filas
C               contiene a la matriz  Z,  pero con las columnas en orden
C               inverso; asi, la columna a|adida ocupa el primer lugar.
C
C        IZ     Primera dimension de  Z. IZ >= N.
C
C        R      Matriz de dimension (IR,N+1).   En la  parte  triangular
C               inferior,  (incluyendo la diagonal), tiene  almacenada a
C               la  caja  triangular  inferior de la matriz  NxN  H ; En
C               las  ultimas  columnas  y  en  las  M  primeras filas se
C               encuentra la matriz  L'.
C
C        IR     Primera dimension de la matriz  R. IR >= N.
C
C        W      Vector de trabajo de dimension  N.
C
C        IPVT   Vector entero de trabajo de dimension  M+1. Contiene, en
C               las   M   primeras coordenadas la informacion sobre la
C               permutacion  P  ; asi,
C                     IPVT(I)=J ,  indica que la fila j-esima de  A  se
C               encuentra en el lugar i-esimo de  PAP' (analogamente con
C               las columnas).
C
C        N      Numero de filas de  Z  y de  R.
C
C        M      Numero de filas y columnas de  L'.
C
C        IND    Indicador que toma los valores enteros:
C                 0    : La matriz factorizada es definida positiva o
C                        comienza la factorizacion.
C               (0,M+1): La matriz  A  es semidefinida positiva; La caja
C                        no nula de L' es de dimension M-IND.
C
C     DE SALIDA:
C
C        R     Matriz que contiene , en sus  M+1  ultimas columnas, la
C              matriz triangular superior  L'  modificada o , si no se
C              ha completado la factorizacion, contiene tambien la parte
C              no factorizada. Para conocer el contenido de  R  es util
C              observar el valor de la variable  IND  de salida.
C
C        IPVT  Vector que contiene la informacion sobre la permutacion
C              P  realizada para obtener la factorizacion de salida. Los
C              valores de  IPVT  siguen el convenio antes citado.
C
C        M     Numero de filas y columnas de la matriz  L'  de salida.
C
C        IND   Indicador que toma los valores:
C              (-1,M+1)  : Se ha obtenido la factorizacion completa. La
C                          dimension  de la caja  no nula de   L'  es
C                          M-IND.
C              (M,2*M+1) : No se ha obtenido la factorizacion. La caja
C                          no factorizada tiene la forma :
C                                                          0    V
C
C                                                          V'   b
C
C                          donde  V  es un vector y  b  es un  escalar.
C                          La dimension de esta caja es  IND-M.El vector
C                          (V',b)  esta almacenado en la ultima columna
C                          de  R  , a partir de la fila  2*M-IND+1.
C              IND > 2*M : No se ha obtenido la factorizacion . La caja
C                          no factorizada tiene la forma:
C                                                         -VV',
C                          donde  V  es un vector de dimension  IND-2*M,
C                          almacenado en la fila  3*M-IND de  R  (en las
C                          ultimas columnas).
C
C
C        Esta subrutina trabaja en doble precision via una sentencia
C     "implicit" :
C                 implicit double precision (a-h,o-z)
C
C     SUBPROGRAMAS AUXILIARES: anrs01,dcopy,ddot,dipvtf,dnrm2,dlamch
C     FUNCIONES FORTRAN INTRINSECAS: abs,mod,sqrt
C
C
      implicit double precision (a-h,o-z)
      dimension z(iz,*),r(ir,*),w(*),ipvt(*)
C
C     Se comprueba si los valores de las variables son correctos
C
CX      if(ind.lt.0 .or. ind.gt.m .or. m.ge.n) then
CX         write(io,'(10x,A)') 'INCORRECT LIST OF CALLING IN ANFM06.'
CX         stop
CX      end if
C
C     Se inicializan algunas variables de trabajo
C
      epsmch=dlamch('p')**0.75
      n1=n+1
      m1=m+1
      m2=m1+1
      nm=n1-m
C
C     Se calcula el producto de la matriz H por el ultimo vector anadido
C     a la base del nucleo
C
      do 10 i=1,n
         i1=i+1
         s=ddot(i,r(i,1),ir,z(1,1),1)
         if(i.lt.n) w(i)=s+ddot(n-i,r(i1,i),1,z(i1,1),1)
10    continue
      w(n)=s
C
C     Se calcula el elemento (m+1,m+1) de la matriz a factorizar
C
      s=ddot(n,w,1,z(1,1),1)
C
C     Se coloca adecuadamente la matriz  L' (inicial) en  R  para poder
C     almacenar en las ultimas columnas de  R  la matriz  L'  modificada
C
      k=0
      do 20 i=nm,nm+m-1
         k=k+1
         call dcopy(k,r(1,i+1),1,r(1,i),1)
20    continue
C
C     Se calculan los  m  primeros elementos de la ultima columna de la
C     matriz a factorizar
C
      do 30 i=1,m
30    r(i,n1)=ddot(n,w,1,z(1,m2-i),1)
      do 40 i=1,m
40    w(i)=r(ipvt(i),n1)
      ipvt(m1)=m1
C
C     Se obtiene la nueva columna de la matriz triangular superior de la
C     factorizacion de Cholesky
C
      m3=m-ind
      if(m3.gt.0) then
         call anrs01(r(1,nm),ir,m3,w,r(1,n1),1,io)
         s=s-ddot(m3,r(1,n1),1,r(1,n1),1)
      end if
C
C     Se calcula el vector que proporcionara una caja no factorizada,en
C     caso de que esta exista
C
      k1=0
      if (ind.gt.0) then
          k=n-ind
          if(m3.gt.0) then
             do 50 i=1,ind
                j=m3+i
                r(j,n1)=w(j)-ddot(ind,r(1,k+i),1,r(1,n1),1)
50           continue
          else
             call dcopy(ind,w,1,r(1,n1),1)
          end if
          rnorma=dnrm2(ind,r(m3+1,n1),1)
          if(rnorma.lt.epsmch) k1=1
      end if
C
C     Se distinguen varios casos,segun sea el nuevo elemento diagonal:
C     positivo,negativo o nulo
C
      if(s.gt.epsmch) then
         s=sqrt(s)
         r(m1,n1)=s
         if(ind.gt.0) then
            if(k1.eq.0) then
               do 60 i=m3+1,m
60             r(i,n1)=r(i,n1)/s
               ind=ind+2*m1
            end if
            m2=m3+1
            call dipvtf(r(1,nm),ir,ipvt,m3,m1,m2)
            nm1=n1-m
            r(m2,m2+n-m)=s
            do 70 i=m2,m
70          r(m2,i+nm1)=r(i,n1)
         end if
      else
         r(m1,n1)=s
         if(s.lt.-epsmch) then
            if(ind.eq.0) then
               ind=-m1
            else
               ind=ind+1+m1
            end if
         else
            if(ind.eq.0) then
               ind=1
            else if(k1.eq.1) then
               ind=ind+1
            else
               ind=ind+1+m1
            end if
         end if
      end if
      m=m1
      end