SURFEX v7.3
General documentation of Surfex
 All Classes Files Functions Variables Typedefs
/home/dasprezs/EXPORT_v7_3/src/SURFEX/mode_splines.F90
Go to the documentation of this file.
00001 !     ######spl
00002 MODULE MODE_SPLINES
00003 
00004 USE MODI_ABOR1_SFX
00005 USE MODD_SPLINES
00006 USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK
00007 USE PARKIND1  ,ONLY : JPRB
00008 !
00009 INTERFACE SSCOPY
00010         MODULE PROCEDURE SSCOPY_1
00011         MODULE PROCEDURE SSCOPY_2
00012 END INTERFACE
00013 INTERFACE MXIDML
00014         MODULE PROCEDURE MXIDML
00015 END INTERFACE
00016 INTERFACE MTXAXM
00017         MODULE PROCEDURE MTXAXM
00018 END INTERFACE
00019 INTERFACE MXMSPL
00020         MODULE PROCEDURE MXMSPL_1
00021         MODULE PROCEDURE MXMSPL_2
00022         MODULE PROCEDURE MXMSPL_3
00023 END INTERFACE
00024 INTERFACE SMXINV
00025         MODULE PROCEDURE SMXINV
00026 END INTERFACE
00027 !génération de matrices
00028 INTERFACE SPLIE
00029         MODULE PROCEDURE SPLIE
00030 END INTERFACE
00031 INTERFACE SPLK
00032         MODULE PROCEDURE SPLK_1
00033         MODULE PROCEDURE SPLK_2
00034 END INTERFACE
00035 INTERFACE SPLBFIN
00036         MODULE PROCEDURE SPLBFIN
00037 END INTERFACE
00038 INTERFACE SPLT
00039         MODULE PROCEDURE SPLT_1
00040         MODULE PROCEDURE SPLT_2
00041 END INTERFACE
00042 INTERFACE SPLE
00043         MODULE PROCEDURE SPLE
00044 END INTERFACE
00045 INTERFACE SPLB2E1
00046         MODULE PROCEDURE SPLB2E1
00047 END INTERFACE
00048 INTERFACE SPLB2E
00049         MODULE PROCEDURE SPLB2E
00050 END INTERFACE
00051 INTERFACE TRED2
00052         MODULE PROCEDURE TRED2
00053 END INTERFACE
00054 INTERFACE TQL2_2
00055         MODULE PROCEDURE TQL2_2
00056 END INTERFACE
00057 INTERFACE EISRS1
00058         MODULE PROCEDURE EISRS1
00059 END INTERFACE
00060 INTERFACE SPLV
00061         MODULE PROCEDURE SPLV
00062 END INTERFACE 
00063 INTERFACE SPLS2VI
00064         MODULE PROCEDURE SPLS2VI
00065 END INTERFACE
00066 INTERFACE SPLBVM
00067         MODULE PROCEDURE SPLBVM
00068 END INTERFACE
00069 INTERFACE SPLS2V
00070         MODULE PROCEDURE SPLS2V
00071 END INTERFACE
00072 INTERFACE SPLDS2V
00073         MODULE PROCEDURE SPLDS2V
00074 END INTERFACE
00075 INTERFACE SPLPS2V
00076         MODULE PROCEDURE SPLPS2V
00077 END INTERFACE
00078 INTERFACE SPLRI
00079         MODULE PROCEDURE SPLRI
00080 END INTERFACE
00081 INTERFACE SPLRS
00082         MODULE PROCEDURE SPLRS
00083 END INTERFACE
00084 INTERFACE SPLDRS
00085         MODULE PROCEDURE SPLDRS
00086 END INTERFACE
00087 INTERFACE SPLPR
00088         MODULE PROCEDURE SPLPR
00089 END INTERFACE
00090 INTERFACE SPLDV
00091         MODULE PROCEDURE SPLDV
00092 END INTERFACE
00093 INTERFACE SPLD2V
00094         MODULE PROCEDURE SPLD2V
00095 END INTERFACE
00096 INTERFACE SPLPV
00097         MODULE PROCEDURE SPLPV
00098 END INTERFACE
00099 INTERFACE SPLP
00100         MODULE PROCEDURE SPLP
00101 END INTERFACE
00102 INTERFACE SPLTT
00103         MODULE PROCEDURE SPLTT
00104 END INTERFACE
00105 INTERFACE SPLR
00106         MODULE PROCEDURE SPLR_1
00107         MODULE PROCEDURE SPLR_2
00108 END INTERFACE
00109 INTERFACE SPLU
00110         MODULE PROCEDURE SPLU
00111 END INTERFACE
00112 INTERFACE SPLW
00113         MODULE PROCEDURE SPLW
00114 END INTERFACE
00115 INTERFACE SPLVPQ
00116         MODULE PROCEDURE SPLVPQ
00117 END INTERFACE
00118 INTERFACE SPLC
00119         MODULE PROCEDURE SPLC 
00120 END INTERFACE
00121 INTERFACE SPLM
00122         MODULE PROCEDURE SPLM
00123 END INTERFACE
00124 INTERFACE SP0NOP
00125         MODULE PROCEDURE SP0NOP
00126 END INTERFACE
00127 INTERFACE SP0CVQ
00128         MODULE PROCEDURE SP0CVQ
00129 END INTERFACE
00130 INTERFACE SPLBSD
00131         MODULE PROCEDURE SPLBSD
00132 END INTERFACE
00133 INTERFACE SPLBSEL
00134         MODULE PROCEDURE SPLBSEL
00135 END INTERFACE
00136 INTERFACE SPLB2C
00137         MODULE PROCEDURE SPLB2C
00138 END INTERFACE
00139 
00140 CONTAINS
00141 
00142 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00143 
00144 !COPIE D'UNE MATRICE DANS UNE AUTRE
00145 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00146 !1. copie de matrices potentiellement de tailles différentes
00147 !SPLR
00148 SUBROUTINE SSCOPY_1(A,B,IA,IB)
00149 !
00150 IMPLICIT NONE
00151 
00152 REAL, DIMENSION(:), INTENT(IN) :: A
00153 INTEGER, INTENT(IN) :: IA
00154 INTEGER, INTENT(IN) :: IB
00155 REAL, DIMENSION(:), INTENT(OUT) :: B
00156 
00157 INTEGER :: I, J, K
00158 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00159 
00160 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SSCOPY_1',0,ZHOOK_HANDLE)
00161 J = IB
00162 K = IA
00163 DO I=1,SIZE(A)
00164   B(J) = A(K)
00165   J = J + IB
00166   K = K + IA
00167 ENDDO
00168 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SSCOPY_1',1,ZHOOK_HANDLE)
00169 
00170 END SUBROUTINE SSCOPY_1
00171 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00172 !1. copie de matrices potentiellement de tailles différentes
00173 SUBROUTINE SSCOPY_2(A,B,IA,IB)
00174 !
00175 IMPLICIT NONE
00176 
00177 REAL, DIMENSION(:,:), INTENT(IN) :: A
00178 INTEGER, INTENT(IN) :: IA
00179 INTEGER, INTENT(IN) :: IB
00180 REAL, DIMENSION(:,:), INTENT(OUT) :: B
00181 
00182 REAL,DIMENSION(SIZE(A,1)*SIZE(A,2)) :: A1
00183 REAL,DIMENSION(SIZE(B,1)*SIZE(B,2)) :: B1
00184 
00185 INTEGER :: N
00186 INTEGER :: I, J, K
00187 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00188 
00189 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SSCOPY_2',0,ZHOOK_HANDLE)
00190 N=SIZE(A,1)*SIZE(A,2)
00191 
00192 DO J=1,SIZE(A,2)
00193   A1((J-1)*SIZE(A,1)+1:J*SIZE(A,1))=A(:,J)
00194 ENDDO
00195 
00196 J = IB
00197 K = IA
00198 DO I=1,N-1
00199   B1(J) = A1(K)
00200   J = J + IB
00201   K = K + IA
00202 ENDDO
00203 
00204 DO J=1,SIZE(B,2)
00205   B(:,J)=B1((J-1)*SIZE(B,1)+1:J*SIZE(B,1))
00206 ENDDO
00207 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SSCOPY_2',1,ZHOOK_HANDLE)
00208 
00209 END SUBROUTINE SSCOPY_2
00210 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00211 
00212 !OPERATIONS SUR LES MATRICES
00213 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00214 !2. A(I) B(I*J) R(I*J) R(:,K)=B(:,K)/A(:)
00215 SUBROUTINE MXIDML(A,B,R)
00216 !SPLTT, SPLR
00217 IMPLICIT NONE
00218 
00219 REAL, DIMENSION(:), INTENT(IN) :: A
00220 REAL, DIMENSION(:,:), INTENT(IN) :: B
00221 REAL, DIMENSION(:,:), INTENT(OUT):: R
00222 
00223 INTEGER :: K
00224 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00225 
00226 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:MXIDML',0,ZHOOK_HANDLE)
00227 IF (SIZE(B,1).EQ.0 .OR. SIZE(B,2).EQ.0 .AND. LHOOK) &
00228         CALL DR_HOOK('MODE_SPLINES:MXIDML',1,ZHOOK_HANDLE)
00229 IF (SIZE(B,1).EQ.0 .OR. SIZE(B,2).EQ.0) RETURN
00230 
00231 DO K=1,SIZE(B,2)
00232   R(:,K)=B(:,K)/A(:)
00233 ENDDO
00234 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:MXIDML',1,ZHOOK_HANDLE)
00235 
00236 END SUBROUTINE MXIDML
00237 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00238 !3. produit bizarre de matrices
00239 SUBROUTINE MTXAXM(A,B,R)
00240 !SPLR,SPLU,SPLVPQ
00241 IMPLICIT NONE
00242 
00243 REAL, DIMENSION(:,:),INTENT(IN) :: A
00244 REAL, DIMENSION(:,:),INTENT(IN) :: B
00245 REAL, DIMENSION(:,:),INTENT(OUT)::R
00246 
00247 INTEGER :: I,J,K, L
00248 REAL :: RIJ
00249 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00250 
00251 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:MTXAXM',0,ZHOOK_HANDLE)
00252 R(:,:)=0.
00253 DO I=1,SIZE(A,2)
00254   DO J=1,SIZE(A,1)
00255     RIJ=0.
00256     DO K=1,SIZE(A,1)
00257         RIJ=RIJ+B(J,K)*A(K,I)
00258     ENDDO
00259     DO L=1,I
00260         R(L,I)=R(L,I)+RIJ*A(J,L)
00261         R(I,L)=R(L,I)
00262     ENDDO
00263   ENDDO
00264 ENDDO
00265 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:MTXAXM',1,ZHOOK_HANDLE)
00266 
00267 END SUBROUTINE MTXAXM
00268 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00269 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00270 !4. produit simple de matrices (mettre les deux dans la même interface)
00271 SUBROUTINE MXMSPL_1(A,B,R)
00272 !SPLE, SPLC, SPLTT, SPLR, SPLW, SPLVPQ
00273 IMPLICIT NONE
00274 
00275 REAL, DIMENSION(:,:),INTENT(IN) :: A
00276 REAL, DIMENSION(:,:),INTENT(IN) :: B
00277 REAL, DIMENSION(:,:),INTENT(OUT)::R
00278 
00279 INTEGER :: I,J,K
00280 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00281 
00282 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:MXMSPL_1',0,ZHOOK_HANDLE)
00283 R(:,:)=0.
00284 
00285 DO I=1,SIZE(A,1)
00286   DO J=1,SIZE(B,2)
00287     DO K=1,SIZE(A,2)
00288       R(I,J)=R(I,J)+A(I,K)*B(K,J)
00289     ENDDO
00290   ENDDO
00291 ENDDO
00292 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:MXMSPL_1',1,ZHOOK_HANDLE)
00293 
00294 END SUBROUTINE MXMSPL_1
00295 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00296 !4. produit simple de matrices 2
00297 SUBROUTINE MXMSPL_2(A,B,R)
00298 !
00299 IMPLICIT NONE
00300 
00301 REAL, DIMENSION(:,:),INTENT(IN) :: A
00302 REAL, DIMENSION(:),INTENT(IN) :: B
00303 REAL, DIMENSION(:),INTENT(OUT)::R
00304 
00305 INTEGER :: I,J
00306 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00307 
00308 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:MXMSPL_2',0,ZHOOK_HANDLE)
00309 R(:)=0.
00310 
00311 DO I=1,SIZE(A,1)
00312   DO J=1,SIZE(A,2)
00313     R(I)=R(I)+A(I,J)*B(J)
00314   ENDDO
00315 ENDDO
00316 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:MXMSPL_2',1,ZHOOK_HANDLE)
00317 
00318 END SUBROUTINE MXMSPL_2    
00319 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00320 !4. produit simple de matrices 3
00321 SUBROUTINE MXMSPL_3(A,B,RES)
00322 !
00323 IMPLICIT NONE
00324 
00325 REAL, DIMENSION(:),INTENT(IN) :: A
00326 REAL, DIMENSION(:),INTENT(IN) :: B
00327 REAL,INTENT(OUT)::RES
00328 
00329 INTEGER :: I
00330 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00331 
00332 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:MXMSPL_3',0,ZHOOK_HANDLE)
00333 RES=0.
00334 
00335 DO I=1,SIZE(A)
00336   RES=RES+A(I)*B(I)
00337 ENDDO
00338 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:MXMSPL_3',1,ZHOOK_HANDLE)
00339 
00340 END SUBROUTINE MXMSPL_3
00341 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00342 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00343 !5. inversion de la matrice A.
00344 SUBROUTINE SMXINV(A,IREP)
00345 !SPLTT
00346 IMPLICIT NONE
00347 
00348 REAL, DIMENSION(:,:), INTENT(INOUT) :: A
00349 INTEGER, INTENT(OUT) :: IREP
00350 
00351 REAL, DIMENSION(SIZE(A,1)*SIZE(A,2)) :: A2
00352 INTEGER, DIMENSION(SIZE(A,1)) :: INDEX
00353 REAL, DIMENSION(SIZE(A,1)) :: RI
00354 INTEGER :: N, NP, NP1, I, J, JJ, K, L, KK, KJ, JL
00355 INTEGER :: IJ0, JI0, IJ, JI
00356 REAL :: PIVOT, ELM
00357 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00358 
00359 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SMXINV',0,ZHOOK_HANDLE)
00360 IREP=0
00361 N=SIZE(A,1)
00362 NP1=N+1
00363 
00364 INDEX(:)=1
00365 
00366 DO J=1,N
00367  !les colonnes sont à la suite
00368   A2((J-1)*N+1:J*N)=A(:,J)
00369 ENDDO
00370 
00371 DO I=1,N
00372   !find pivot
00373   PIVOT=0.
00374   JJ=1
00375   !dans la diagonale, on retient le plus grand élément
00376   DO J=1,N
00377     IF(INDEX(J).NE.0) THEN   
00378       ELM=ABS(A2(JJ))
00379       IF (ELM.GT.PIVOT) THEN
00380         PIVOT=ELM
00381         K=J !numéro de la ligne / colonne
00382         !numéro de l'élément dans A2
00383         KK=JJ
00384       ENDIF
00385     ENDIF
00386     JJ=JJ+NP1
00387   ENDDO
00388   INDEX(K)=0
00389   IF (PIVOT.EQ.0.) THEN 
00390     IREP=-1
00391     IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SMXINV',1,ZHOOK_HANDLE)
00392     RETURN 
00393   ENDIF
00394   PIVOT=-A2(KK)
00395   !elimination
00396   KJ=K
00397   NP=N
00398   DO J=1,N
00399     !KJ=K, KJ=K+N, KJ=K+2N ... : avant l'élément pivot, 
00400     !on se déplace sur les colonnes
00401     !J=K=3: KJ=K+2N+1, KJ=K+2N+2....!une fois qu'on a passé
00402     !le pivot, on se déplace sur la ligne, à droite de l'élément pivot
00403     !si on est sur le premier élément de la colonne pivot
00404     IF (J==K) THEN
00405       !KJ réfère à l'élément diagonal du pivot
00406       A2(KJ)=1./PIVOT
00407       RI(J)=0.
00408       NP=1
00409     ELSE
00410       !si on est sur un autre élément de du pivot
00411       ELM=-A2(KJ)
00412       RI(J)=ELM/PIVOT
00413       IF (ELM.NE.0.) THEN
00414         JL=J
00415         !JL prend pour valeur les élements de la colonne 
00416         !du premier en haut au diagonal -1
00417         DO L=1,J
00418           !à chaque fois A2 de cet élément est incrémenté
00419           A2(JL)=A2(JL)+ELM*RI(L)
00420           JL=JL+N
00421         ENDDO
00422       ENDIF
00423       !élement véritablement en cours
00424       A2(KJ)=RI(J)
00425     ENDIF
00426     !KJ=K+JN si on n'a pas encore passé l'élément de la colonne pivot
00427     !KJ=K+J0N+J si on l'a passé
00428     KJ=KJ+NP
00429   ENDDO
00430 ENDDO
00431 
00432 !change the sign and provisional fill-up
00433 DO J=1,N
00434   A(:,J)= A2((J-1)*N+1:J*N)
00435 ENDDO
00436 
00437 DO I=1,N
00438   DO J=1,I
00439     A(I,J)=-A(I,J)
00440     A(J,I)=A(I,J)
00441   ENDDO
00442 ENDDO
00443 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SMXINV',1,ZHOOK_HANDLE)
00444 
00445 END SUBROUTINE SMXINV
00446 
00447 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00448 ! CALCULS PLUS SPECIFIQUES
00449 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00450 !6. IE(ND,M): calcul de la matrice IE en fonction de NDEG.
00451 SUBROUTINE SPLIE(NDEG,IE)
00452 !SPLE, SPLR
00453 IMPLICIT NONE
00454 
00455 INTEGER, INTENT(IN) :: NDEG
00456 INTEGER, DIMENSION(:,:), INTENT(OUT) :: IE
00457 
00458 INTEGER, DIMENSION(SIZE(IE,1)) :: NV
00459 INTEGER :: I, J, K, T, N, N0, NC
00460 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00461 
00462 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLIE',0,ZHOOK_HANDLE)
00463 NV(:)=1
00464 IE(:,1)=0
00465 N=1
00466 N0=1
00467 
00468 !boucle d'itération
00469 DO T=1,NDEG
00470 !boucle sur les indices
00471   DO I=1,SIZE(IE,1)
00472     NC=0
00473     !NV(I) varie d'itération T en itération
00474     DO K=NV(I),N0
00475       N=N+1
00476       NC=NC+1
00477       !boucle sur les indices
00478       DO J=1,SIZE(IE,1)
00479         IE(J,N)=IE(J,K)
00480         IF (J.EQ.I) IE(J,N)=IE(J,N)+1
00481       ENDDO
00482     ENDDO
00483     NV(I)=N-NC+1
00484   ENDDO
00485   N0=N
00486 ENDDO
00487 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLIE',1,ZHOOK_HANDLE)
00488 
00489 END SUBROUTINE SPLIE
00490 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00491 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00492 !7. calcul de RK en fonction des autres RK(N1,N2)
00493 SUBROUTINE SPLK_1(NORD,X1,X2,G,RK)
00494 !SPLE,SPLU,
00495 IMPLICIT NONE
00496 
00497 INTEGER, INTENT(IN) :: NORD
00498 REAL, DIMENSION(:), INTENT(IN) :: X1
00499 REAL, DIMENSION(:,:), INTENT(IN) :: X2
00500 REAL, DIMENSION(:,:), INTENT(IN) :: G
00501 REAL, DIMENSION(:), INTENT(OUT):: RK
00502 
00503 INTEGER :: I, ID, JD, EXP, ISIGNE
00504 INTEGER :: ND, N, DI, DJ
00505 REAL :: D2
00506 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00507 
00508 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLK_1',0,ZHOOK_HANDLE)
00509 ND=SIZE(X1)
00510 N=SIZE(X2,2)
00511 
00512 !Exposant du noyau
00513 EXP=(2*NORD-ND)/2.
00514 
00515 IF (MOD(ND,2).EQ.0) THEN
00516   !Calcul de K dans le cas d'un espace de dimension paire
00517   ISIGNE=(-1)**(1+NORD+ND/2)
00518 ELSE
00519   !Calcul de K dans le cas d'un espace de dimension impair 
00520   ISIGNE=(-1)**(NORD+ND/2)
00521 ENDIF
00522 
00523 RK(:)=0.
00524 
00525 DO I=1,N
00526   D2=0.
00527   DO ID=1,ND
00528     DO JD=1,ND
00529       DI=X1(ID)-X2(ID,I)
00530       DJ=X1(JD)-X2(JD,I)
00531       D2=D2+G(ID,JD)*DI*DJ
00532     ENDDO
00533   ENDDO
00534   IF (D2.NE.0.) THEN
00535     RK(I) = ISIGNE*D2**EXP
00536     IF (MOD(ND,2).EQ.0) RK(I)=RK(I)*0.5*LOG(D2)
00537   ENDIF
00538 ENDDO
00539 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLK_1',1,ZHOOK_HANDLE)
00540 
00541 END SUBROUTINE SPLK_1
00542 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00543 !7. calcul de RK en fonction des autres RK(N1,N2)
00544 SUBROUTINE SPLK_2(NORD,X1,X2,G,RK)
00545 
00546 IMPLICIT NONE
00547 
00548 INTEGER, INTENT(IN) :: NORD
00549 REAL, DIMENSION(:,:), INTENT(IN) :: X1
00550 REAL, DIMENSION(:,:), INTENT(IN) :: X2
00551 REAL, DIMENSION(:,:), INTENT(IN) :: G
00552 REAL, DIMENSION(:,:), INTENT(OUT):: RK
00553 
00554 INTEGER :: I1, I2, ID, JD, ISIGNE
00555 INTEGER :: ND, N1, N2
00556 REAL :: EXP, D2, DI, DJ
00557 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00558 
00559 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLK_2',0,ZHOOK_HANDLE)
00560 ND=SIZE(X1,1)
00561 N1=SIZE(X1,2)
00562 N2=SIZE(X2,2)
00563 
00564 !Exposant du noyau
00565 EXP=(2*NORD-ND)/2.
00566 
00567 IF (MOD(ND,2).EQ.0) THEN
00568   !Calcul de K dans le cas d'un espace de dimension paire
00569   ISIGNE=(-1)**(1+NORD+ND/2)
00570 ELSE
00571   !Calcul de K dans le cas d'un espace de dimension impair 
00572   ISIGNE=(-1)**(NORD+ND/2)
00573 ENDIF
00574 
00575 RK(:,:)=0.
00576 
00577 DO I1=1,N1
00578   DO I2=1,N2
00579     D2=0.
00580     DO ID=1,ND
00581       DO JD=1,ND
00582         DI=X1(ID,I1)-X2(ID,I2)
00583         DJ=X1(JD,I1)-X2(JD,I2)
00584         D2=D2+G(ID,JD)*DI*DJ
00585       ENDDO
00586     ENDDO
00587     IF (D2.NE.0.) THEN
00588       RK(I1,I2) = ISIGNE*D2**EXP
00589       IF (MOD(ND,2).EQ.0) RK(I1,I2)=RK(I1,I2)*0.5*LOG(D2)
00590     ENDIF
00591   ENDDO
00592 ENDDO
00593 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLK_2',1,ZHOOK_HANDLE)
00594 
00595 END SUBROUTINE SPLK_2
00596 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00597 !8. on cherche l'indice I de la 3ème dimension de AI tel que XE(ID) soit compris 
00598 !entre AI(ID,1,I) et AI(ID,2,I+1). Il est compris entre 1 et NSD(ID), 
00599 !par défaut il est égal à NDSD(ID)
00600 SUBROUTINE SPLBFIN(ID,NSD,XE,AI,IDX,IDX1)
00601 !SPLB2E
00602 IMPLICIT NONE
00603 
00604 INTEGER, INTENT(IN) :: ID
00605 INTEGER, DIMENSION(:), INTENT(IN) :: NSD
00606 REAL, DIMENSION(:), INTENT(IN) :: XE
00607 REAL, DIMENSION(:,:,:), INTENT(IN) :: AI
00608 INTEGER, INTENT(OUT) :: IDX
00609 INTEGER, INTENT(OUT) :: IDX1
00610 
00611 !INTEGER, PARAMETER: NSDMAX=20
00612 INTEGER :: I, I1
00613 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00614 
00615 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLBFIN',0,ZHOOK_HANDLE)
00616 IDX1=0
00617 DO I=1,NSD(ID)-1
00618   IF (XE(ID).LE.AI(ID,2,I)) THEN
00619     IDX=I
00620     I1=I+1
00621     IF (XE(ID).GT.AI(ID,1,I1)) IDX1=I1
00622     IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLBFIN',1,ZHOOK_HANDLE)
00623     RETURN
00624   ENDIF
00625 ENDDO
00626 IDX=NSD(ID)
00627 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLBFIN',1,ZHOOK_HANDLE)
00628      
00629 END SUBROUTINE SPLBFIN
00630 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00631 !9. X(ND,N) IE(ND,M) : T(N,M) T=produit(X**IE) quand IE est non nul
00632 SUBROUTINE SPLT_1(X,IE,T)
00633 !SPLE, SPLTT
00634 IMPLICIT NONE
00635 
00636 REAL, DIMENSION(:), INTENT(IN) :: X
00637 INTEGER, DIMENSION(:,:), INTENT(IN) :: IE
00638 REAL, DIMENSION(:), INTENT(OUT) :: T
00639 !
00640 INTEGER :: J,K
00641 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00642 
00643 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLT_1',0,ZHOOK_HANDLE)
00644 T(:)=1.
00645 
00646 DO J=1,SIZE(IE,2)
00647     DO K=1,SIZE(X,1)
00648       IF (IE(K,J).NE.0) T(J)=T(J)*X(K)**IE(K,J)
00649     ENDDO
00650 ENDDO
00651 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLT_1',1,ZHOOK_HANDLE)
00652 
00653 END SUBROUTINE SPLT_1
00654 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00655 !9. X(ND,N) IE(ND,M) : T(N,M) T=produit(X**IE) quand IE est non nul
00656 SUBROUTINE SPLT_2(X,IE,T)
00657 !
00658 IMPLICIT NONE
00659 
00660 REAL, DIMENSION(:,:), INTENT(IN) :: X
00661 INTEGER, DIMENSION(:,:), INTENT(IN) :: IE
00662 REAL, DIMENSION(:,:), INTENT(OUT) :: T
00663 !
00664 INTEGER :: I,J,K
00665 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00666 
00667 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLT_2',0,ZHOOK_HANDLE)
00668 T(:,:)=1.
00669 
00670 DO J=1,SIZE(IE,2)
00671   DO I=1,SIZE(X,2)
00672     DO K=1,SIZE(X,1)
00673       IF (IE(K,J).NE.0) T(I,J)=T(I,J)*X(K,I)**IE(K,J)
00674     ENDDO
00675   ENDDO
00676 ENDDO
00677 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLT_2',1,ZHOOK_HANDLE)
00678 
00679 END SUBROUTINE SPLT_2
00680 
00681 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00682 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00683 ! PARTIE "E"
00684 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00685 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00686 !10.
00687 SUBROUTINE SPLE(NORD,X,G,C,XE,ZE)
00688 !SPLB2E1
00689 IMPLICIT NONE
00690 
00691 INTEGER, INTENT(IN) :: NORD
00692 REAL, DIMENSION(:,:),INTENT(IN) :: X !ND,N
00693 REAL, DIMENSION(:,:), INTENT(IN) :: G !ND,ND
00694 REAL, DIMENSION(:),INTENT(IN) :: C ! N+M
00695 REAL, DIMENSION(:),INTENT(IN) :: XE !ND
00696 REAL, INTENT(OUT) :: ZE
00697 
00698 INTEGER, DIMENSION(SIZE(X,1),SIZE(C)-SIZE(X,2)) :: IW !ND,M
00699 REAL, DIMENSION(SIZE(X,2)) :: WE1
00700 REAL, DIMENSION(SIZE(IW,2)) :: WE2
00701 REAL :: ZOUT1,ZOUT2
00702 INTEGER :: M, N, NE, M1, M2, M3
00703 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00704 
00705 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLE',0,ZHOOK_HANDLE)
00706 N=SIZE(X,2)
00707 M=SIZE(C)-N
00708 
00709 ! Calcul de la matrice Kxe
00710  CALL SPLK(NORD,XE,X,G,WE1)
00711 ! Calcul de Kxe.c
00712  CALL MXMSPL(WE1,C(1:N),ZOUT1)
00713 
00714 IF (M.NE.0) THEN
00715   ! Generation des exposants des monomes
00716   CALL SPLIE(NORD-1,IW) !IW(ND,M)
00717   ! Calcul de la matrice Txe
00718   CALL SPLT(XE,IW,WE2)
00719   ! Calcul Txe.d
00720   CALL MXMSPL(WE2,C(N+1:N+M),ZOUT2)
00721   ! Calcul de Txe.d + Kxe.c
00722   ZE = ZOUT1+ZOUT2
00723 ENDIF
00724 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLE',1,ZHOOK_HANDLE)
00725 
00726 END SUBROUTINE SPLE
00727 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00728 !11.
00729 SUBROUTINE SPLB2E1(NORD,M,G,C,XE,IDX,IDX1,IDY,IDY1,ZE)
00730 !SPLB2E
00731 
00732 IMPLICIT NONE
00733 
00734 INTEGER, INTENT(IN) :: NORD
00735 INTEGER, INTENT(IN) :: M
00736 REAL, DIMENSION(:,:),INTENT(IN) :: G
00737 REAL, DIMENSION(:,:,:), INTENT(IN) :: C
00738 REAL, DIMENSION(:), INTENT(IN) :: XE
00739 INTEGER, INTENT(IN) :: IDX,IDX1,IDY,IDY1
00740 REAL, INTENT(OUT) :: ZE
00741 
00742 INTEGER :: NN,NM
00743 REAL :: RX,RY,ALPHAX,ALPHAY,SUM_AX,SUM_AY,SUM_A
00744 REAL :: ZXY, ZX1Y, ZXY1, ZX1Y1
00745 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00746 
00747 
00748 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLB2E1',0,ZHOOK_HANDLE)
00749 
00750 RX=0
00751 RY=0
00752 IF (IDX1.NE.0) RX=(XE(1)-AI(1,1,IDX1))/(AI(1,2,IDX)-AI(1,1,IDX1))
00753 IF (IDY1.NE.0) RY=(XE(2)-AI(2,1,IDY1))/(AI(2,2,IDY)-AI(2,1,IDY1))
00754 ALPHAX=(RX-1.)*(RX-1.)*(2*RX+1.)
00755 ALPHAY=(RY-1.)*(RY-1.)*(2*RY+1.)
00756 SUM_AX=0.
00757 SUM_AY=0.
00758 SUM_A=0.
00759 ZXY=0.
00760 ZX1Y=0.
00761 ZXY1=0.
00762 ZX1Y1=0.
00763 
00764 NM=0
00765 
00766 IF (NS(IDX,IDY).GE.M) THEN
00767   NM=1
00768   SUM_AX=SUM_AX+ALPHAX
00769   SUM_AY=SUM_AY+ALPHAY
00770   SUM_A=SUM_A+ALPHAX*ALPHAY
00771   NN=NS(IDX,IDY)
00772   !N=NN
00773   CALL SPLE(NORD,XS(:,1:NN,IDX,IDY),G,C(1:NN+M,IDX,IDY),XE,ZXY)
00774 ENDIF
00775 
00776 IF (IDX1.NE.0) THEN
00777   IF (NS(IDX1,IDY).GE.M) THEN
00778     NM=1
00779     SUM_AX=SUM_AX+1.-ALPHAX
00780     SUM_A=SUM_A+(1-ALPHAX)*ALPHAY
00781     NN=NS(IDX1,IDY)
00782     CALL SPLE(NORD,XS(:,1:NN,IDX1,IDY),G,C(1:NN+M,IDX1,IDY),XE,ZX1Y)
00783   ENDIF
00784 ENDIF
00785 
00786 IF (IDY1.NE.0) THEN
00787   IF (NS(IDX,IDY1).GE.M) THEN
00788     NM=1
00789     SUM_AY=SUM_AY+1.-ALPHAY
00790     SUM_A=SUM_A+ALPHAX*(1-ALPHAY)
00791     NN=NS(IDX,IDY1)
00792     CALL SPLE(NORD,XS(:,1:NN,IDX,IDY1),G,C(1:NN+M,IDX,IDY1),XE,ZXY1)
00793   ENDIF
00794 ENDIF
00795 
00796 IF (IDX1.NE.0 .AND. IDY1.NE.0) THEN
00797   IF (NS(IDX1,IDY1).GE.M) THEN
00798     NM=1
00799     SUM_A=SUM_A+(1-ALPHAX)*(1-ALPHAY)
00800     NN=NS(IDX1,IDY1)
00801     CALL SPLE(NORD,XS(:,1:NN,IDX1,IDY1),G,C(1:NN+M,IDX1,IDY1),XE,ZX1Y1)
00802   ENDIF
00803 ENDIF
00804 
00805 IF (NM==1) THEN
00806   IF (IDX1.NE.0 .AND. IDY1.EQ.0) THEN
00807     ZE=(ALPHAX*ZXY+(1-ALPHAX)*ZX1Y)/SUM_AX
00808   ELSEIF (IDX1.EQ.0 .AND. IDY1.NE.0) THEN
00809     ZE=(ALPHAY*ZXY+(1-ALPHAY)*ZXY1)/SUM_AY
00810   ELSEIF (IDX1.NE.0 .AND. IDY1.NE.0) THEN
00811     ZE=(ALPHAX*ALPHAY    *ZXY  + (1-ALPHAX)*    ALPHAY*ZX1Y + &
00812          ALPHAX*(1-ALPHAY)*ZXY1 + (1-ALPHAX)*(1-ALPHAY)*ZX1Y1) / SUM_A 
00813   ELSE
00814     ZE=ZXY
00815   ENDIF
00816 ENDIF
00817 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLB2E1',1,ZHOOK_HANDLE)
00818 
00819 END SUBROUTINE SPLB2E1
00820 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00821 !  APPELEE PAR INTERPOL_SPLINES.F90
00822 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00823 !12. 
00824 SUBROUTINE SPLB2E(NORD,M,NSDI,NSDJ,G,C,XE,ZE)
00825 
00826 IMPLICIT NONE
00827 
00828 INTEGER, INTENT(IN) :: NORD
00829 INTEGER, INTENT(IN) :: M
00830 INTEGER, INTENT(IN) :: NSDI,NSDJ
00831 REAL, DIMENSION(:,:), INTENT(IN) :: G
00832 REAL,DIMENSION(:,:,:), INTENT(IN) :: C
00833 REAL, DIMENSION(:,:), INTENT(IN) :: XE
00834 REAL, DIMENSION(:), INTENT(OUT) :: ZE
00835 
00836 INTEGER, DIMENSION(2) :: NSD
00837 INTEGER :: J, ID, NE
00838 INTEGER :: IDX, IDX1, IDY, IDY1
00839 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00840 
00841 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLB2E',0,ZHOOK_HANDLE)
00842 NE=SIZE(XE,2)
00843 
00844 NSD(1)=NSDI
00845 NSD(2)=NSDJ
00846 
00847 DO J=1,NE
00848   ID=1
00849   CALL SPLBFIN(ID,NSD,XE(:,J),AI,IDX,IDX1)
00850   ID=2
00851   CALL SPLBFIN(ID,NSD,XE(:,J),AI,IDY,IDY1)
00852   CALL SPLB2E1(NORD,M,G,C,XE(:,J),IDX,IDX1,IDY,IDY1,ZE(J))
00853 ENDDO
00854 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLB2E',1,ZHOOK_HANDLE)
00855 
00856 END SUBROUTINE SPLB2E
00857 
00858 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00859 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00860 !         PARTIE "C"
00861 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00862 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00863 
00864 ! Calculs EISRS1
00865 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00866 !13. 
00867 SUBROUTINE TRED2(A,D,E,Z)
00868 !EISRS1
00869 IMPLICIT NONE
00870 
00871 REAL, DIMENSION(:,:), INTENT(IN) :: A
00872 REAL, DIMENSION(:), INTENT(OUT)   :: D
00873 REAL, DIMENSION(:), INTENT(OUT)  :: E
00874 REAL, DIMENSION(:,:), INTENT(OUT):: Z
00875 
00876 INTEGER :: N, I, II, J, K, L, JP1
00877 REAL :: F, G, H, SCALE, HH
00878 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00879 
00880 
00881 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:TRED2',0,ZHOOK_HANDLE)
00882 N=SIZE(A,1)
00883 
00884 !Z=A sur la partie gauceh jusqu'à la diagonale
00885 DO I=1,N
00886   DO J=1,I
00887     Z(I,J)=A(I,J)
00888   ENDDO
00889 ENDDO
00890 
00891 IF (N.NE.1) THEN
00892   DO II=2,N
00893     !I varie de N à 2
00894     I=N+2-II
00895     !L varie de N-1 à 1
00896     L=I-1
00897     H=0.0
00898     SCALE=0.0
00899     IF (L.GE.2) THEN
00900       !scale = somme des éléments de la ligne à l'exclusion du diagonal
00901       DO K=1,L
00902         SCALE=SCALE+ABS(Z(I,K))
00903       ENDDO
00904       IF (SCALE.NE.0.0) THEN
00905         !normalisation de Z par la valeur de la ligne
00906         DO K=1,L
00907           Z(I,K)=Z(I,K)/SCALE
00908           !H = somme des carrés de Z / (somme des ABS(Z)) au carré
00909           H=H+Z(I,K)**2
00910         ENDDO
00911         F=Z(I,L) 
00912         !SQRT(H) signé par lélément diagonal-1 de la ligne
00913         G=-SIGN(SQRT(H),F)
00914         !moyenne des éléments au carrés de la ligne, signée
00915         E(I)=SCALE*G
00916         H=H-F*G
00917         Z(I,L)=F-G
00918         F=0.0
00919         DO J=1,L
00920           Z(J,I)=Z(I,J)/(SCALE*H)
00921           G=0.0
00922           DO K=1,J
00923             G=G+Z(J,K)*Z(I,K)
00924           ENDDO
00925           JP1=J+1
00926           IF (L.GE.JP1) THEN
00927             DO K=JP1,L
00928               G=G+Z(K,J)*Z(I,K)
00929             ENDDO
00930           ENDIF
00931           E(J)=G/H
00932           F=F+E(J)*Z(I,J)
00933         ENDDO
00934         HH=F/(H+H)
00935         DO J=1,L
00936           F=Z(I,J)
00937           G=E(J)-HH*F
00938           E(J)=G
00939           DO K=1,J
00940             Z(J,K)=Z(J,K)-F*E(K)-G*Z(I,K)
00941           ENDDO
00942         ENDDO
00943         DO K=1,L
00944           Z(I,K)=SCALE*Z(I,K)
00945         ENDDO
00946       ELSE
00947         E(I)=Z(I,L)
00948       ENDIF
00949     ELSE
00950       E(I)=Z(I,L)
00951     ENDIF
00952     D(I)=H
00953   ENDDO
00954 ENDIF
00955 
00956 D(1)=0.0
00957 E(1)=0.0
00958 DO I=1,N
00959   L=I-1
00960   IF (D(I).NE.0.0) THEN
00961     DO J=1,L
00962       G=0.0
00963       DO K=1,L
00964         G=G+Z(I,K)*Z(K,J)
00965       ENDDO
00966       DO K=1,L
00967         Z(K,J)=Z(K,J)-G*Z(K,I)
00968       ENDDO
00969     ENDDO
00970   ENDIF
00971   D(I)=Z(I,I)
00972   Z(I,I)=1.0
00973   IF (L.GE.1) THEN
00974     DO J=1,L
00975       Z(I,J)=0.0
00976       Z(J,I)=0.0
00977     ENDDO
00978   ENDIF
00979 ENDDO
00980 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:TRED2',1,ZHOOK_HANDLE)
00981 
00982 END SUBROUTINE TRED2
00983 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
00984 !14. 
00985 SUBROUTINE TQL2_2(D,E,Z,IERR)
00986 !EISRS1
00987 IMPLICIT NONE
00988 
00989 REAL, DIMENSION(:), INTENT(INOUT) :: D
00990 REAL, DIMENSION(:), INTENT(INOUT) :: E
00991 REAL, DIMENSION(:,:), INTENT(OUT) :: Z
00992 INTEGER, INTENT(OUT) :: IERR
00993 
00994 INTEGER :: I, II, J, K, L, M, N, MML
00995 REAL :: B, C, F, G, H, P, R, S
00996 REAL :: MACHEP
00997 REAL(KIND=JPRB) :: ZHOOK_HANDLE
00998 
00999 
01000 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:TQL2_2',0,ZHOOK_HANDLE)
01001 MACHEP=2.**(-52)
01002 IERR=0
01003 N=SIZE(D)
01004 
01005 IF (N.NE.1) THEN
01006   DO I=2,N
01007     E(I-1)=E(I)
01008   ENDDO
01009   F=0.0
01010   B=0.0
01011   E(N)=0.0
01012   DO L=1,N
01013     J=0
01014     H=MACHEP*(ABS(D(L))+ABS(E(L)))
01015     IF (B.LT.H) B=H
01016     DO M=L,N
01017       IF (ABS(E(M)).LE.B) EXIT
01018     ENDDO
01019     IF (M.NE.L) THEN
01020       DO WHILE (ABS(E(L)).GT.B) 
01021         IF (J.EQ.30) THEN
01022           IERR=L
01023           IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:TQL2_2',1,ZHOOK_HANDLE)
01024           RETURN
01025         ENDIF
01026         J=J+1
01027         P=(D(L+1)-D(L)) / (2.0 * E(L))
01028         R=SQRT(P*P+1.0)
01029         H=D(L)-E(L) / (P+SIGN(R,P))
01030         DO I=L,N
01031           D(I)=D(I)-H
01032         ENDDO
01033         F=F+H
01034         P=D(M)
01035         C=1.0
01036         S=0.0
01037         MML=M-L
01038         DO II=1,MML
01039           I=M-II
01040           G=C*E(I)
01041           H=C*P
01042           IF (ABS(P).GE.ABS(E(I))) THEN
01043             C=E(I)/P
01044             R=SQRT(C*C+1.0)
01045             E(I+1)=S*P*R
01046             S=C/R
01047             C=1.0/R
01048           ELSE
01049             C=P/E(I)
01050             R=SQRT(C*C+1.0)
01051             E(I+1)=S*E(I)*R
01052             S=1.0/R
01053             C=C*S
01054           ENDIF
01055           P=C*D(I)-S*G
01056           D(I+1)=H+S*(C*G+S*D(I))
01057           DO K=1,N
01058             H=Z(K,I+1)
01059             Z(K,I+1)=S*Z(K,I)+C*H
01060             Z(K,I)=C*Z(K,I)-S*H
01061           ENDDO
01062         ENDDO
01063         E(L)=S*P
01064         D(L)=C*P
01065       ENDDO
01066     ENDIF
01067     D(L)=D(L)+F
01068   ENDDO
01069   DO II=2,N
01070     I=II-1
01071     K=I
01072     P=D(I)
01073     DO J=II,N
01074       IF (D(J).LT.P) THEN
01075         K=J
01076         P=D(J)
01077       ENDIF
01078     ENDDO
01079     IF (K.NE.I) THEN
01080       D(K)=D(I)
01081       D(I)=P
01082       DO J=1,N
01083         P=Z(J,I)
01084         Z(J,I)=Z(J,K)
01085         Z(J,K)=P
01086       ENDDO
01087     ENDIF
01088   ENDDO
01089 ENDIF
01090 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:TQL2_2',1,ZHOOK_HANDLE)
01091 
01092 END SUBROUTINE TQL2_2
01093 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01094 !15. SPLR,SPLU
01095 SUBROUTINE EISRS1(AR,WR,ZR,WORK,IERR)
01096 !
01097 !     all eigenvalues and corresponding eigenvectors of a real
01098 !     symmetric matrix
01099 !
01100 IMPLICIT NONE
01101 !toutes les dimensions sont N: ok
01102 REAL, DIMENSION(:,:), INTENT(IN) :: AR
01103 REAL, DIMENSION(:), INTENT(OUT) :: WR
01104 REAL, DIMENSION(:,:), INTENT(OUT) :: ZR
01105 REAL, DIMENSION(:), INTENT(OUT) :: WORK
01106 INTEGER, INTENT(OUT) :: IERR
01107 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01108 
01109 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:EISRS1',0,ZHOOK_HANDLE)
01110  CALL TRED2(AR,WR,WORK,ZR)
01111  CALL TQL2_2(WR,WORK,ZR,IERR)
01112 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:EISRS1',1,ZHOOK_HANDLE)
01113 
01114 END SUBROUTINE EISRS1
01115 
01116 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01117 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01118 !        GROUPES DES PROCEDURES V
01119 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01120 !16.
01121 SUBROUTINE SPLV(B,W,N,P,RES)
01122 !SP0NOP
01123 IMPLICIT NONE
01124 
01125 REAL,DIMENSION(:),INTENT(IN) :: B
01126 REAL,DIMENSION(:), INTENT(IN) :: W
01127 INTEGER, INTENT(IN) :: N
01128 REAL, INTENT(IN) :: P
01129 REAL, INTENT(OUT) :: RES
01130 !
01131 INTEGER :: A, D, I
01132 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01133 
01134 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLV',0,ZHOOK_HANDLE)
01135 A=0.
01136 RES=0.
01137 DO I=1,SIZE(B)
01138   D=B(I)+N*P
01139   A=A+1./D
01140   RES=RES+W(I)**2 / D**2
01141 ENDDO
01142 RES=N*RES/A**2
01143 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLV',1,ZHOOK_HANDLE)
01144 
01145 END SUBROUTINE SPLV
01146 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01147 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01148 !              GROUPE DES PROCEDURES P
01149 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01150 !PROCEDURES INTERMEDIAIRES POUR SPLPS2V
01151 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01152 !17. S2VI=somme(W(i)**2)/size(W)
01153 SUBROUTINE SPLS2VI(W,RES)
01154 !
01155 IMPLICIT NONE
01156 
01157 REAL, DIMENSION(:), INTENT(IN) :: W
01158 REAL, INTENT(OUT) :: RES
01159 
01160 INTEGER :: I
01161 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01162 
01163 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLS2VI',0,ZHOOK_HANDLE)
01164 RES = 0.
01165 DO I=1,SIZE(W)
01166   RES = RES + W(I)**2
01167 ENDDO
01168 RES=RES/SIZE(W)
01169 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLS2VI',1,ZHOOK_HANDLE)
01170 
01171 END SUBROUTINE SPLS2VI
01172 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01173 !18. calcul de BN en fonction de W, B, N et P
01174 SUBROUTINE SPLBVM(B,W,N,P,RES)
01175 !SPLS2V, SP0VPQ
01176 IMPLICIT NONE
01177 
01178 REAL, DIMENSION(:), INTENT(IN) :: B, W
01179 INTEGER, INTENT(IN) :: N
01180 REAL, INTENT(IN) :: P
01181 REAL, INTENT(OUT) :: RES
01182 !
01183 REAL :: A
01184 INTEGER :: I
01185 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01186 
01187 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLBVM',0,ZHOOK_HANDLE)
01188 RES=0.
01189 A=0.
01190 DO I=1,SIZE(B)
01191   RES=RES+(W(I)**2)/(B(I)+N*P)**2
01192   A=A+1./(B(I)+N*P)
01193 ENDDO
01194 RES=RES/A
01195 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLBVM',1,ZHOOK_HANDLE)
01196 
01197 END SUBROUTINE SPLBVM
01198 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01199 !19. 
01200 SUBROUTINE SPLS2V(BI,WI,N,P,RES)
01201 !SPLPS2V, SPLP
01202 IMPLICIT NONE
01203 
01204 REAL, DIMENSION(:), INTENT(IN) :: BI !dimension N-M
01205 REAL, DIMENSION(:), INTENT(IN) :: WI !dimension N-M
01206 INTEGER, INTENT(IN) :: N
01207 REAL, INTENT(IN) :: P
01208 REAL, INTENT(OUT) :: RES
01209 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01210 
01211 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLS2V',0,ZHOOK_HANDLE)
01212  CALL SPLBVM(BI,WI,N,P,RES)
01213 RES=N*P*RES
01214 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLS2V',1,ZHOOK_HANDLE)
01215 
01216 END SUBROUTINE SPLS2V
01217 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01218 !20.
01219 SUBROUTINE SPLDS2V(B,W,N,P,RES)
01220 !SPLPS2V
01221 IMPLICIT NONE
01222 
01223 REAL, DIMENSION(:), INTENT(IN) :: B
01224 REAL, DIMENSION(:), INTENT(IN) :: W
01225 INTEGER, INTENT(IN) :: N
01226 REAL, INTENT(IN) :: P
01227 REAL, INTENT(OUT) :: RES
01228 
01229 REAL :: DA, DB, A1, A2, A3, B2, C1, C2
01230 INTEGER :: J, I
01231 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01232 
01233 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLDS2V',0,ZHOOK_HANDLE)
01234 DA=0.
01235 DB=0.
01236 DO I=1,SIZE(B)
01237   A1=1./(B(I)+N*P)
01238   A2=A1**2
01239   A3=A1**3
01240   DA=DA+A1
01241   B2=W(J)**2
01242   DO J=1,SIZE(B)
01243     C1=1./(B(J)+N*P)
01244     C2=C1**2
01245     DB=DB+B2*(A2*C1+N*P*(-2*A3*C1+A2*C2))
01246   ENDDO
01247 ENDDO
01248 RES=(N/(DA**2))*DB
01249 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLDS2V',1,ZHOOK_HANDLE)
01250 
01251 END SUBROUTINE SPLDS2V
01252 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01253 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01254 !21. SPLPS2V procedure 
01255 SUBROUTINE SPLPS2V(B,W,N,P0,S2,P,IREP)
01256 !SPLP
01257 IMPLICIT NONE
01258 
01259 REAL, DIMENSION(:), INTENT(IN) :: B
01260 REAL, DIMENSION(:), INTENT(IN) :: W
01261 INTEGER, INTENT(IN) :: N
01262 REAL, INTENT(INOUT) :: P0
01263 REAL, INTENT(IN) :: S2
01264 REAL, INTENT(OUT) :: P
01265 INTEGER, INTENT(OUT) :: IREP
01266 
01267 INTEGER, PARAMETER :: EPS=1.E-2
01268 REAL :: P1, RINF, RS, DRS
01269 INTEGER :: NITER
01270 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01271 
01272 ! Calcul de la valeur du s2 de Wahba pour p=infini
01273 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPS2V',0,ZHOOK_HANDLE)
01274  CALL SPLS2VI(W,RINF)
01275 IF (RINF.LE.S2) THEN
01276   IREP=-6
01277   P0=0.
01278   WRITE(*,FMT='(A53,G15.5)') &
01279     "SPLPS2V : S2 > VALEUR DE LA FONCTION POUR P INFINI = ",RINF
01280   P=(B(SIZE(B))**2)/B(1)
01281   IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPS2V',1,ZHOOK_HANDLE)
01282   RETURN
01283 ENDIF
01284 
01285 P1=0.
01286 ! Iterations de Newton
01287 DO NITER=1,NMAX
01288   P0=P1
01289   CALL SPLS2V(B,W,N,P0,RS)
01290   CALL SPLDS2V(B,W,N,P0,DRS)
01291 
01292   P1=P0+(S2-RS)/DRS
01293 
01294   IF (ABS(P1-P0)/P0.LT.EPS) THEN
01295     IF (P1.GE.0.) THEN
01296       IREP=0
01297       P=P1
01298       P0=P1
01299     ELSE
01300       IREP=-3
01301       P=0.
01302       P0=0.
01303       WRITE(*,FMT='(A34,G15.5)') &
01304         "SPLPS2V : SOLUTION NEGATIVE : P = ",P
01305     ENDIF
01306     IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPS2V',1,ZHOOK_HANDLE)
01307     RETURN
01308   ENDIF
01309 ENDDO
01310 
01311 IREP=-5
01312 P=P1
01313 P0=0.
01314 WRITE(*,FMT='(A48,A23,G15.5)') &
01315   "SPLPS2V : NOMBRE MAXIMAL D ITERATIONS ATTEINT : ",&
01316   "VALEUR DE P ATTEINTE : ",P1
01317 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPS2V',1,ZHOOK_HANDLE)
01318 
01319 END SUBROUTINE SPLPS2V
01320 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01321 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01322 !PROCEDURES INTERMEDIAIRES POUR SPLPR
01323 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01324 !22. Comme SPLS2VI mais on ne divise pas par SIZE(W) mais par N
01325 SUBROUTINE SPLRI(W,N,RES)
01326 !SPLPR
01327 IMPLICIT NONE
01328 
01329 REAL, DIMENSION(:), INTENT(IN) :: W
01330 INTEGER, INTENT(IN) :: N
01331 REAL, INTENT(OUT) :: RES
01332 
01333 INTEGER :: I
01334 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01335 
01336 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLRI',0,ZHOOK_HANDLE)
01337 RES=0.
01338 DO I=1,SIZE(W)
01339   RES = RES + W(I)**2
01340 ENDDO
01341 RES=RES/N
01342 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLRI',1,ZHOOK_HANDLE)
01343 
01344 END SUBROUTINE SPLRI
01345 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01346 !23. RS=SQRT(S2/(SOMME((W(I)/B(I))**2)*N)
01347 SUBROUTINE SPLPR0(B,W,N,S2,P)
01348 !SPLPR
01349 IMPLICIT NONE
01350 
01351 REAL, DIMENSION(:), INTENT(IN) :: B
01352 REAL, DIMENSION(:), INTENT(IN) :: W
01353 INTEGER, INTENT(IN) :: N
01354 REAL, INTENT(IN) :: S2
01355 REAL, INTENT(OUT) :: P
01356 
01357 REAL :: RES
01358 INTEGER :: I
01359 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01360 
01361 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPR0',0,ZHOOK_HANDLE)
01362 RES=0.
01363 DO I=1,SIZE(W)
01364   RES=RES+(W(I)/B(I))**2
01365 ENDDO
01366 P=SQRT(S2/(RES*N))
01367 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPR0',1,ZHOOK_HANDLE)
01368 
01369 END SUBROUTINE SPLPR0   
01370 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01371 !24. RS=N*SOMME((W(I)/(B(I)+N*P))**2)*P**2
01372 SUBROUTINE SPLRS(B,W,N,P,RES)
01373 !SPLP, SPLPR, SP0CVQ 
01374 IMPLICIT NONE
01375 
01376 REAL, DIMENSION(:), INTENT(IN) :: B
01377 REAL, DIMENSION(:), INTENT(IN) :: W
01378 INTEGER, INTENT(IN) :: N
01379 REAL, INTENT(IN) :: P
01380 REAL, INTENT(OUT):: RES
01381 
01382 INTEGER :: I
01383 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01384 
01385 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLRS',0,ZHOOK_HANDLE)
01386 RES=0.
01387 DO I=1,SIZE(B)
01388   RES=RES+(W(I)/(B(I)+N*P))**2
01389 ENDDO
01390 RES=N*RES*P**2
01391 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLRS',1,ZHOOK_HANDLE)
01392 
01393 END SUBROUTINE SPLRS
01394 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01395 !25. DRS=2*N*P*(SOMME(W(I)**2*B(I)/(B(I)+N*P)**3)
01396 SUBROUTINE SPLDRS(B,W,N,P,RES)
01397 !SPLPR
01398 IMPLICIT NONE
01399 
01400 REAL, DIMENSION(:), INTENT(IN) :: B
01401 REAL, DIMENSION(:), INTENT(IN) :: W
01402 INTEGER, INTENT(IN) :: N
01403 REAL, INTENT(IN) :: P
01404 REAL, INTENT(OUT) :: RES
01405 !
01406 INTEGER :: J
01407 REAL :: D
01408 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01409 
01410 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLDRS',0,ZHOOK_HANDLE)
01411 RES=0.
01412 DO J=1,SIZE(B)
01413   D=B(J)+N*P
01414   RES=RES+W(J)**2*B(J)/(D**3)
01415 ENDDO
01416 RES=2.*N*P*RES
01417 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLDRS',1,ZHOOK_HANDLE)
01418 
01419 END SUBROUTINE SPLDRS   
01420 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01421 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01422 !26. SPLPR procedure: parallèle de splps2v
01423 SUBROUTINE SPLPR(N,W,B,P0,S2,P,IREP)
01424 !SPLP
01425 IMPLICIT NONE
01426 
01427 INTEGER, INTENT(IN) :: N
01428 REAL, DIMENSION(:), INTENT(IN) :: W !N-M
01429 REAL, DIMENSION(:), INTENT(IN) :: B !N-M
01430 REAL, INTENT(INOUT) :: P0
01431 REAL, INTENT(INOUT) :: S2
01432 REAL, INTENT(INOUT) :: P
01433 INTEGER, INTENT(OUT) :: IREP
01434 
01435 INTEGER, PARAMETER :: EPS=1.E-2
01436 REAL :: RS, DRS, P1, RINF
01437 INTEGER :: NITER
01438 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01439 
01440 ! Calcul de la valeur de la fonction de Reinsch pour p=infini
01441 
01442 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPR',0,ZHOOK_HANDLE)
01443  CALL SPLRI(W,N,RINF)
01444 IF (RINF.LE.S2) THEN
01445   IREP=-6
01446   P0=0.
01447   WRITE(*,FMT='(A51,G15.5)') &
01448     "SPLPR : S2 > VALEUR DE LA FONCTION POUR P INFINI = ",RINF
01449   P=(B(SIZE(B))**2)/B(1)
01450   IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPR',1,ZHOOK_HANDLE)
01451   RETURN
01452 ENDIF
01453 
01454 ! Recherche du point de depart de l'iteration
01455 IF (P0.EQ.0.) CALL SPLPR0(B,W,N,S2,P0)
01456 P1=P0
01457 
01458 ! Iterations de Newton
01459 DO NITER=1,NSDMAX
01460   P0=P1
01461   CALL SPLRS(B,W,N,P0,RS)
01462   CALL SPLDRS(B,W,N,P0,DRS)
01463 
01464   P1=P0+(S2-RS)/DRS
01465 
01466   IF (ABS(P1-P0)/P0.LT.EPS) THEN
01467     IF (P1.GE.0.) THEN
01468       IREP=0
01469       P=P1
01470       P0=P1
01471     ELSE
01472       IREP=-3
01473       P=0.
01474       P0=0.
01475       WRITE(*,FMT='(A32,G15.5)') &
01476         "SPLPR : SOLUTION NEGATIVE : P = ",P
01477     ENDIF
01478     IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPR',1,ZHOOK_HANDLE)
01479     RETURN
01480   ENDIF
01481 ENDDO
01482 
01483 IREP=-5
01484 P=0.
01485 P0=0.
01486 WRITE(*,FMT='(A45,A23,G15.5)') &
01487   "SPLPR : NOMBRE MAXIMAL D ITERATIONS ATTEINT: ",&
01488   "VALEUR DE P ATTEINTE : ",P1
01489 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPR',1,ZHOOK_HANDLE)
01490 
01491 END SUBROUTINE SPLPR
01492 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01493 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01494 !PROCEDURES INTERMEDIAIRES POUR SPLPV
01495 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01496 !27.
01497 SUBROUTINE SPLDV(B,W,N,P,RES)
01498 !SPLPV
01499 IMPLICIT NONE
01500 
01501 REAL, DIMENSION(:), INTENT(IN) :: B
01502 REAL, DIMENSION(:), INTENT(IN) :: W
01503 INTEGER, INTENT(IN) :: N
01504 REAL, INTENT(IN) :: P
01505 REAL, INTENT(OUT) :: RES
01506 !
01507 REAL :: S1, S2, SB2, SB3, A1, A2, B2
01508 INTEGER :: I
01509 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01510 
01511 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLDV',0,ZHOOK_HANDLE)
01512 S1=0.
01513 S2=0.
01514 SB2=0.
01515 SB3=0.
01516 DO I=1,SIZE(B)
01517   A1=1./(B(I)+N*P)
01518   A2=A1**2
01519   B2=A2*W(I)**2
01520   S1=S1+A1
01521   S2=S2+A2
01522   SB2=SB2+B2
01523   SB3=SB3+B2*A1
01524 ENDDO
01525 RES=S2*SB2-S1*SB3
01526 RES=2.*N**2*RES/(S1**3)
01527 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLDV',1,ZHOOK_HANDLE)
01528 
01529 END SUBROUTINE SPLDV
01530 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01531 !28.
01532 SUBROUTINE SPLD2V(B,W,N,P,RES)
01533 !SPLPV
01534 IMPLICIT NONE
01535 
01536 REAL, DIMENSION(:), INTENT(IN) :: B
01537 REAL, DIMENSION(:), INTENT(IN) :: W
01538 INTEGER, INTENT(IN) :: N
01539 REAL, INTENT(IN) :: P
01540 REAL, INTENT(OUT) :: RES
01541 
01542 REAL :: S1, S2, S3, SB2, SB3, SB4
01543 REAL :: A1, A2, B2
01544 INTEGER :: I
01545 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01546 
01547 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLD2V',0,ZHOOK_HANDLE)
01548 S1=0.
01549 S2=0.
01550 S3=0.
01551 SB2=0.
01552 SB3=0.
01553 SB4=0.
01554 DO I=1,SIZE(B)
01555   A1=1./(B(I)+N*P)
01556   A2=A1**2
01557   B2=A2*W(I)**2
01558   S1=S1+A1
01559   S2=S2+A2
01560   S3=S3+A2*A1
01561   SB2=SB2+B2
01562   SB3=SB3+B2*A1
01563   SB4=SB4+B2*A2
01564 ENDDO
01565 RES=3.*S2**2*SB2-4.*S2*S1*SB3+3.*S1**2*SB4-2.*S3*S1*SB2
01566 RES=RES/(S1**4)
01567 RES=RES*2.*N**3
01568 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLD2V',1,ZHOOK_HANDLE)
01569 
01570 END SUBROUTINE SPLD2V
01571 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01572 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01573 !29.
01574 SUBROUTINE SPLPV(N,B,W,P0,P,IREP)
01575 !SPLP
01576 IMPLICIT NONE
01577 
01578 INTEGER, INTENT(IN) :: N
01579 REAL, DIMENSION(:), INTENT(IN):: B, W !N-M
01580 REAL, INTENT(INOUT) :: P0
01581 REAL, INTENT(OUT) :: P
01582 INTEGER, INTENT(OUT) :: IREP
01583 
01584 INTEGER, PARAMETER:: EPS=1.E-100, EPSR=1.E-2
01585 REAL :: DVM, D2VM, P1
01586 INTEGER :: IFLAG, NITER
01587 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01588 
01589 
01590 ! Calcul de Vm'(0) . Si Vm'(0) > 0 alors popt = 0.
01591 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPV',0,ZHOOK_HANDLE)
01592  CALL SPLDV(B,W,N,0.,DVM)
01593 
01594 IF (DVM.GT.0.) THEN
01595   IREP=0.
01596   P=0.
01597   IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPV',1,ZHOOK_HANDLE)
01598   RETURN
01599 ENDIF
01600 
01601 ! Recherche du point de depart p0 de l'iteration de Newton
01602 IFLAG=0
01603 
01604 DO WHILE(IFLAG==0)
01605 
01606   IF (P0.EQ.0.) THEN
01607 
01608     IFLAG=1
01609     P0=B(1)/N
01610 
01611     !on augmente P0 et on calcul D2VM; quand D2VM est supérieur à 0, 
01612     !on passe à la suite
01613     DO NITER=1,NSDMAX
01614       CALL SPLD2V(B,W,N,P0,D2VM)
01615       IF (D2VM.GT.0.) EXIT
01616       P0=P0*10.
01617     ENDDO
01618 
01619     IF (D2VM.LE.0.) THEN
01620       IREP=-1
01621       P0=0.
01622       P=0.
01623       WRITE(*,FMT='(A41)') &
01624         "SPLPV : PAS DE MINIMUM: D2VM < 0 PARTOUT "
01625       IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPV',1,ZHOOK_HANDLE)
01626       RETURN
01627     ENDIF
01628 
01629   ENDIF
01630 
01631   P1=P0
01632 
01633   DO NITER=1,NSDMAX
01634 
01635     P0=P1
01636     CALL SPLDV(B,W,N,P0,DVM)
01637     CALL SPLD2V(B,W,N,P0,D2VM)
01638 
01639     !Si D2Vm est très proche de 0, on sort et P=P0
01640     IF (ABS(D2VM).LT.EPS) THEN
01641       P0=0.
01642       IF (IFLAG.EQ.0) EXIT
01643       IREP=-2
01644       P=P0
01645       WRITE(*,FMT='(A28)') "SPLPV : PASSAGE PAR D2VM = 0"
01646       IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPV',1,ZHOOK_HANDLE)
01647       RETURN
01648     ENDIF
01649 
01650     P1=P0-DVM/D2VM
01651 
01652      !si l'écart entre P0 et P1 est suffisamment petit
01653     IF (ABS(P1-P0)/P0.LT.EPSR) THEN
01654        !Si P1 est négatif, on repart dans la boucle
01655       IF (P1.LT.0.) THEN
01656         P0=0.
01657         IF (IFLAG.EQ.0) EXIT
01658         IREP=-3
01659         P=0.
01660         WRITE(*,FMT='(A33,G15.5)') &
01661           "SPLPV : SOLUTION NEGATIVE : P = ",P1
01662       ELSE
01663         !si P1 et positif et D2VM positif, on garde P1
01664         IF (D2VM.GE.0.) THEN
01665           IREP=0
01666           P=P1
01667           P0=P1
01668         ELSE
01669           !si P1 est négatif, on repart dans la boucle
01670           P0=0.
01671           IF (IFLAG.EQ.0) EXIT
01672           IREP=-4
01673           P=0.
01674           WRITE(*,FMT='(A28,G15.5)') &
01675             "SPLPV : MAXIMUM DE VM : P = ",P1
01676         ENDIF
01677       ENDIF
01678       IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPV',1,ZHOOK_HANDLE)
01679       RETURN
01680     ENDIF
01681   ENDDO
01682 
01683   P0=0.
01684   IF (IFLAG.NE.0) THEN
01685     IREP=-5
01686     P=P1
01687     WRITE(*,FMT='(A46,A23,G15.5)') &
01688       "SPLPV : NOMBRE MAXIMAL D ITERATIONS ATTEINT : ",&
01689       "VALEUR DE P ATTEINTE : ",P1
01690     IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPV',1,ZHOOK_HANDLE)
01691     RETURN
01692   ENDIF
01693 
01694 ENDDO
01695 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLPV',1,ZHOOK_HANDLE)
01696 
01697 END SUBROUTINE SPLPV
01698 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01699 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01700 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01701 !30.
01702 SUBROUTINE SPLP(LISSAGE,N,B,W,P,S2,IREP)
01703 !SP0NOP
01704 IMPLICIT NONE
01705 
01706 INTEGER, INTENT(IN) :: LISSAGE
01707 INTEGER, INTENT(IN) :: N
01708 REAL, DIMENSION(:), INTENT(IN) :: B
01709 REAL, DIMENSION(:), INTENT(IN) :: W
01710 REAL, INTENT(INOUT) :: P
01711 REAL, INTENT(INOUT) :: S2
01712 INTEGER, INTENT(OUT) :: IREP
01713 
01714 REAL :: P0
01715 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01716 
01717 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLP',0,ZHOOK_HANDLE)
01718 IF (LISSAGE.EQ.1) THEN
01719 !  Recherche de la valeur de P pour S2 connu, par la methode de Wahba
01720   P0=0.
01721   CALL SPLPS2V(B,W,N,P0,S2,P,IREP)
01722   IF (IREP.NE.0) THEN
01723     IREP=-2
01724     IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLP',1,ZHOOK_HANDLE)
01725     RETURN
01726   ENDIF
01727 ELSEIF (LISSAGE.EQ.10) THEN
01728 !  Recherche de la valeur de P pour S2 connu, par la methode de Reinsch
01729   P0=0.
01730   CALL SPLPR(N,W,B,P0,S2,P,IREP)
01731   IF (IREP.NE.0) THEN
01732     IREP=-2
01733     IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLP',1,ZHOOK_HANDLE)
01734     RETURN
01735   ENDIF
01736 ELSEIF (LISSAGE.EQ.2) THEN
01737 !  Recherche de la valeur de P par la methode de G.C.V
01738   P0=0.
01739   CALL SPLPV(N,B,W,P0,P,IREP)
01740   IF (IREP.NE.0) IREP=-3
01741 !  Calcul de la variance d'erreur de mesure correspondante
01742   CALL SPLS2V(B,W,N,P,S2)
01743 ELSEIF (LISSAGE.EQ.3) THEN
01744 !  Calcul de l'ajustement correspondant a une valeur de P donnee
01745   CALL SPLRS(B,W,N,P,S2)
01746 ENDIF
01747 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLP',1,ZHOOK_HANDLE)
01748 
01749 END SUBROUTINE SPLP
01750 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01751 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01752 !          GROUPE DES PROCEDURES T et R
01753 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01754 !31. TT procedure
01755 SUBROUTINE SPLTT(X,DS,IW,TM,TT,IREP)
01756 !SPLR
01757 IMPLICIT NONE
01758 
01759 REAL,DIMENSION(:,:),INTENT(IN) :: X !ND,N
01760 REAL,DIMENSION(:),INTENT(IN) :: DS !N
01761 INTEGER,DIMENSION(:,:),INTENT(IN) :: IW !ND,M
01762 REAL,DIMENSION(:,:),INTENT(OUT) :: TM !N,M
01763 REAL,DIMENSION(:,:),INTENT(OUT) :: TT !M,M
01764 INTEGER, INTENT(OUT) :: IREP
01765 
01766 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01767 
01768 ! Calcul de la matrice T des monomes
01769 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLTT',0,ZHOOK_HANDLE)
01770  CALL SPLT(X,IW,TM)
01771 ! Calcul de Tm=(Ds-1)*T
01772  CALL MXIDML(DS,TM,TM)
01773 ! Calcul de Tm'*Tm
01774  CALL MXMSPL(TRANSPOSE(TM),TM,TT)
01775 ! Calcul de (Tm'*Tm)-1
01776  CALL SMXINV(TT,IREP)
01777 ! Test du compte-rendu de smxinv
01778 IF (IREP.NE.0) WRITE(*,FMT='(A27)') "SPLTT: MATRICE TT NON INVERSIBLE"
01779 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLTT',1,ZHOOK_HANDLE)
01780 
01781 END SUBROUTINE SPLTT
01782 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01783 !32. r procedure
01784 SUBROUTINE SPLR_1(NORD,X,DS,IW,TTT,R,IREP)
01785 !SP0NOP, SP0CVQ
01786 IMPLICIT NONE
01787 
01788 INTEGER,INTENT(IN) :: NORD
01789 REAL,DIMENSION(:,:), INTENT(IN) :: X !ND,N
01790 REAL,DIMENSION(:),INTENT(IN) :: DS !N
01791 INTEGER,DIMENSION(:),INTENT(OUT) :: IW !ND
01792 REAL,DIMENSION(:),INTENT(OUT) :: TTT !N
01793 REAL,DIMENSION(:,:),INTENT(OUT) :: R !N,N
01794 INTEGER, INTENT(OUT)::IREP
01795 
01796 INTEGER :: N, I, J
01797 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01798 
01799 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLR_1',0,ZHOOK_HANDLE)
01800 N=SIZE(X,2)
01801 
01802 ! R = I
01803 DO I=1,N
01804   DO J=1,N
01805     IF (I.EQ.J) THEN
01806       R(I,I)=1.
01807     ELSE
01808       R(I,J)=0.
01809     ENDIF
01810   ENDDO
01811 ENDDO
01812 
01813 IREP=0
01814 
01815 !  Calcul de (Ds-1)*R
01816  CALL MXIDML(DS,R,R)
01817 
01818 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLR_1',1,ZHOOK_HANDLE)
01819 
01820 END SUBROUTINE SPLR_1
01821 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01822 !32.
01823 SUBROUTINE SPLR_2(NORD,X,DS,IW,TTT,R,IREP)
01824 
01825 IMPLICIT NONE
01826 
01827 INTEGER,INTENT(IN) :: NORD
01828 REAL,DIMENSION(:,:), INTENT(IN) :: X !ND,N
01829 REAL,DIMENSION(:),INTENT(IN) :: DS !N
01830 INTEGER,DIMENSION(:,:),INTENT(OUT) :: IW !ND,M
01831 REAL,DIMENSION(:,:),INTENT(OUT) :: TTT !M,N
01832 REAL,DIMENSION(:,:),INTENT(OUT) :: R !N,N-M
01833 INTEGER, INTENT(OUT)::IREP
01834 
01835 REAL,DIMENSION(SIZE(X,2),SIZE(X,2)) :: C !N,N
01836 REAL,DIMENSION(SIZE(X,2),SIZE(IW,2))  :: TM !N,M
01837 REAL,DIMENSION(SIZE(IW,2),SIZE(IW,2)) :: TT !M,M
01838 REAL, DIMENSION(SIZE(X,2),SIZE(X,2)) :: R1
01839 REAL,DIMENSION(SIZE(X,2)) :: VP !N
01840 REAL,DIMENSION(SIZE(X,2)) :: WORK !N
01841 INTEGER :: M, N, J
01842 INTEGER, DIMENSION(1) :: IMIN
01843 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01844 
01845 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLR_2',0,ZHOOK_HANDLE)
01846 N=SIZE(X,2)
01847 M=SIZE(IW,2)
01848 
01849 !     Recherche des monomes de degre inferieur ou egal a nord-1
01850  CALL SPLIE(NORD-1,IW)
01851 !----------------------------------------------------------
01852 !     Calcul de la matrice (Tm'*Tm)-1
01853  CALL SPLTT(X,DS,IW,TM,TT,IREP)
01854 !     Calcul de (T'm*Tm)-1 Tm'
01855  CALL MXMSPL(TT,TRANSPOSE(TM),TTT)
01856 !R1(:,1:M)=TRANSPOSE(TTT)
01857 !------------------------------------------------------------
01858 !     Calcul de Tm ((Tm'*Tm)-1) Tm'
01859  CALL MTXAXM(TRANSPOSE(TM),TT,C)
01860 DO J=1,N
01861   C(J,J)=C(J,J)-1.
01862 ENDDO
01863 C(:,:)=-C(:,:)
01864 !-----------------------------------------------------------
01865 !     Calcul des vecteurs propres de I - Tm c ((Tm'*Tm)-1) c Tm'
01866  CALL EISRS1(C,VP,R1,WORK,IREP)
01867 
01868 !     Test du signe des valeurs propres de C
01869 IMIN=MINLOC(VP(M+1:N))
01870 IF(VP(M+IMIN(1)).LE.0) THEN
01871   IREP=-1
01872   WRITE(*,FMT='(A31)') "SPLR: VALEUR PROPRE < 0 DE PROJ"
01873   IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLR_2',1,ZHOOK_HANDLE)
01874   RETURN
01875 ENDIF
01876 !     Compte-rendu OK
01877 IREP=0
01878 !  Calcul de (Ds-1)*R
01879 R=R1(:,M+1:N)
01880  CALL MXIDML(DS,R,R)
01881 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLR_2',1,ZHOOK_HANDLE)
01882 
01883 END SUBROUTINE SPLR_2
01884 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01885 !             GROUPE DES PROCEDURES U
01886 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01887 !33. U procedure
01888 SUBROUTINE SPLU(NORD,X,G,R,RK,U,DB)
01889 !SP0NOP, SP0CVQ
01890 IMPLICIT NONE
01891 
01892 INTEGER, INTENT(IN) :: NORD
01893 REAL,DIMENSION(:,:), INTENT(IN) :: X !ND,N
01894 REAL,DIMENSION(:,:), INTENT(IN) :: G ! ND,ND
01895 REAL,DIMENSION(:,:), INTENT(IN) :: R !N,N-M
01896 REAL,DIMENSION(:,:), INTENT(OUT) :: RK !N,N
01897 REAL,DIMENSION(:,:), INTENT(OUT) :: U !N-M,N-M
01898 REAL,DIMENSION(:), INTENT(OUT) :: DB !N-M
01899 
01900 REAL,DIMENSION(SIZE(R,2),SIZE(R,2)) :: RKR !N-M,N-M
01901 REAL,DIMENSION(SIZE(R,2)) :: WORK !N-M
01902 
01903 INTEGER :: M, N, IREP
01904 INTEGER, DIMENSION(1) :: IMIN
01905 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01906 
01907 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLU',0,ZHOOK_HANDLE)
01908 N=SIZE(X,2)
01909 M=SIZE(X,2)-SIZE(R,2)
01910 
01911 ! Calcul de la matrice K des noyaux
01912  CALL SPLK(NORD,X,X,G,RK)
01913 ! Calcul de R'*K*R
01914  CALL MTXAXM(R,RK,RKR)
01915 ! Calcul de la matrice U des vecteurs propres de R'*K*R
01916  CALL EISRS1(RKR,DB,U,WORK,IREP)
01917 ! Test du signe des valeurs propres de R'KR
01918 IMIN=MINLOC(DB)
01919 IF (DB(IMIN(1)).LE.0)  &
01920    WRITE(*,FMT='(A31)') "SPLU : VALEUR PROPRE < 0 DE RKR"
01921 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLU',1,ZHOOK_HANDLE)
01922 
01923 END SUBROUTINE SPLU     
01924 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01925 !               GROUPE DES PROCEDURES W
01926 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01927 !34. w procedure
01928 SUBROUTINE SPLW(Z,R,U,W,RZ)
01929 !SP0NOP, SP0CVQ
01930 IMPLICIT NONE
01931 
01932 REAL,DIMENSION(:), INTENT(IN) :: Z !N
01933 REAL, DIMENSION(:,:),INTENT(IN) :: R !N,N-M
01934 REAL,DIMENSION(:,:),INTENT(IN) :: U !N-M,N-M
01935 REAL, DIMENSION(:),INTENT(OUT) :: W !N-M
01936 REAL,DIMENSION(:),INTENT(OUT) :: RZ !N-M
01937 
01938 INTEGER :: N, M
01939 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01940 
01941 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLW',0,ZHOOK_HANDLE)
01942 N=SIZE(Z)
01943 M=SIZE(Z)-SIZE(R,2)
01944 
01945 ! Calcul de R'*Z
01946  CALL MXMSPL(TRANSPOSE(R),Z,RZ)
01947 ! Calcul de U'R'Z
01948  CALL MXMSPL(TRANSPOSE(U),RZ,W)
01949 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLW',1,ZHOOK_HANDLE)
01950 
01951 END SUBROUTINE SPLW
01952 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01953 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01954 !              GROUPE DES PROCEDURES Q
01955 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01956 !35. splvpQ procedure
01957 SUBROUTINE SPLVPQ(P,R,RK,U,DB,Q)
01958 !SP0CVQ
01959 IMPLICIT NONE
01960 
01961 REAL, INTENT(IN) :: P
01962 REAL, DIMENSION(:,:), INTENT(IN) :: R !N,N-M
01963 REAL, DIMENSION(:,:), INTENT(IN) :: RK ! N,N
01964 REAL, DIMENSION(:,:), INTENT(IN) :: U !N-M,N-M
01965 REAL, DIMENSION(:), INTENT(IN) :: DB !N-M
01966 REAL, DIMENSION(:,:), INTENT(OUT) :: Q ! N,N
01967 
01968 REAL, DIMENSION(SIZE(R,1),SIZE(R,1)):: Q1 !N,N
01969 REAL, DIMENSION(SIZE(U,1),SIZE(U,2))::QW1,QW2 !N-M,N-M
01970 INTEGER :: N, J
01971 REAL(KIND=JPRB) :: ZHOOK_HANDLE
01972 
01973 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLVPQ',0,ZHOOK_HANDLE)
01974 N=SIZE(R,1)
01975 
01976 ! Calcul de (DB+n*p*I)-1
01977 QW1(:,:)=0.
01978 DO J=1,SIZE(DB)
01979   QW1(J,J)=1./(DB(J)+N*P)
01980 ENDDO
01981 
01982 ! Calcul de U((DB+n*p*I)-1)U'
01983  CALL MTXAXM(TRANSPOSE(U),QW1,QW2)
01984 ! Calcul de RU((DB+n*p*I)-1))UR'
01985  CALL MTXAXM(TRANSPOSE(R),QW2,Q)
01986 ! Calcul de QK
01987  CALL MXMSPL(Q,RK,Q1)
01988 
01989 ! Calcul de I - QK
01990 Q1(:,:)=-Q1(:,:)
01991 DO J=1,N
01992   Q1(J,J)=Q1(J,J)+1
01993 ENDDO
01994 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLVPQ',1,ZHOOK_HANDLE)
01995 
01996 END SUBROUTINE SPLVPQ
01997 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
01998 !              GROUPE DES PROCEDURES C
01999 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
02000 !36. 
02001 SUBROUTINE SPLC(Q,Z,RK,DS,TTT,RKC,C)
02002 !SP0NOP, SP0CVQ
02003 IMPLICIT NONE
02004 
02005 REAL, DIMENSION(:,:), INTENT(IN) :: Q !Q(N,N)
02006 REAL, DIMENSION(:), INTENT(IN) :: Z !Z(N)
02007 REAL, DIMENSION(:,:), INTENT(IN) :: RK !RK(N,n)  
02008 REAL, DIMENSION(:), INTENT(IN) :: DS !DS(N)
02009 REAL, DIMENSION(:,:), INTENT(IN) :: TTT !TTT(M,N)
02010 REAL, DIMENSION(:), INTENT(OUT)  :: RKC !RKC(N)
02011 REAL, DIMENSION(:), INTENT(OUT) :: C !C(N+M)
02012 REAL(KIND=JPRB) :: ZHOOK_HANDLE
02013 
02014 INTEGER :: N, M
02015 
02016 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLC',0,ZHOOK_HANDLE)
02017 N=SIZE(Z)
02018 M=SIZE(TTT,1)
02019 
02020 !     Calcul de c
02021 !     -----------
02022 !     Calcul de c = Qz = R((R'KR+n*p*I)-1)R'z
02023  CALL MXMSPL(Q,Z,C(1:N))
02024 
02025 !     Calcul de d
02026 !     -----------
02027 IF (M.NE.0) THEN
02028 ! Calcul de K*c
02029   CALL MXMSPL(RK,C(1:N),RKC)
02030 ! Calcul de z - K*c
02031   RKC(:)=Z(:)-RKC(:)   
02032 ! Calcul de (Ds-1) * (z-K*c)
02033   RKC(:)=RKC(:)/DS(:)
02034 ! Calcul de d = (Tm'*Tm)-1 * Tm' * (Ds-1) * (z-K*c)
02035   CALL MXMSPL(TTT,RKC,C(N+1:N+M))
02036 ENDIF
02037 
02038 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLC',1,ZHOOK_HANDLE)
02039 
02040 END SUBROUTINE SPLC
02041 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
02042 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
02043 !                  PROCEDURES GLOBALES
02044 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
02045 !37. Calcul de M en fonction de NORD et ND (qu'est-ce que c'est que ce ND?)
02046 SUBROUTINE SPLM(ND,NORD,M)
02047 !SP0NOP
02048 IMPLICIT NONE
02049 
02050 INTEGER, INTENT(IN) :: ND
02051 INTEGER, INTENT(IN) :: NORD
02052 INTEGER, INTENT(OUT):: M
02053 REAL(KIND=JPRB) :: ZHOOK_HANDLE
02054 
02055 
02056 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLM',0,ZHOOK_HANDLE)
02057 IF (ND==1) THEN
02058   M=NORD
02059 ELSEIF (ND==2) THEN
02060   M=NORD*(NORD+1)/2.
02061 ELSEIF (ND==3) THEN
02062   M=NORD*(NORD+1)*(NORD+2)/6.
02063 ELSEIF (ND==4) THEN
02064   M=NORD*(NORD+1)*(NORD+2)*(NORD+3)/24.
02065 ENDIF
02066 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLM',1,ZHOOK_HANDLE)
02067 
02068 END SUBROUTINE SPLM
02069 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc  
02070 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
02071 !38. 
02072 SUBROUTINE SP0NOP(X,G,Z,DS,LISSAGE,LORDRE,IOPT,NORDOPT,M,S2,P,&
02073          IW,TTT,R,RK,U,DB,W,RZ,IREP) 
02074 !SP0CVQ
02075 IMPLICIT NONE
02076 
02077 REAL, DIMENSION(:,:), INTENT(IN) :: X !ND,N
02078 REAL, DIMENSION(:,:), INTENT(IN) :: G ! ND,ND
02079 REAL, DIMENSION(:), INTENT(IN) :: Z ! N
02080 REAL, DIMENSION(:), INTENT(IN) :: DS ! N
02081 INTEGER, INTENT(IN) :: LISSAGE
02082 INTEGER, INTENT(IN) :: LORDRE
02083 INTEGER, INTENT(IN) :: IOPT
02084 INTEGER, INTENT(INOUT) :: NORDOPT
02085 INTEGER, INTENT(INOUT) :: M
02086 REAL, INTENT(INOUT) :: S2
02087 REAL, INTENT(INOUT) :: P
02088 INTEGER, DIMENSION(:,:), INTENT(OUT):: IW !ND,M
02089 REAL, DIMENSION(:,:), INTENT(OUT) :: TTT ! M,N
02090 REAL, DIMENSION(:,:), INTENT(OUT) :: R ! N,N-M
02091 REAL,DIMENSION(:,:), INTENT(OUT) :: RK !N,N
02092 REAL,DIMENSION(:,:), INTENT(OUT) :: U !N-M,N-M
02093 REAL,DIMENSION(:), INTENT(OUT) :: DB !N-M
02094 REAL, DIMENSION(:),INTENT(OUT) :: W !N-M
02095 REAL,DIMENSION(:),INTENT(OUT) :: RZ !N-M
02096 INTEGER, INTENT (OUT) :: IREP
02097 
02098 
02099 REAL, DIMENSION(NORDMAX) :: VM, S2SAVE, PSAVE, MSAVE
02100 INTEGER :: N, ND
02101 INTEGER :: NORDMI, NORDMA, NORDM, NORD
02102 REAL :: VMMIN
02103 REAL(KIND=JPRB) :: ZHOOK_HANDLE
02104 
02105 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SP0NOP',0,ZHOOK_HANDLE)
02106 N=SIZE(X,2)
02107 ND=SIZE(X,1)
02108 
02109 IF (LORDRE.EQ.0) THEN
02110 !
02111 !  Recherche de p seulement avec nord fixe
02112 !  ---------------------------------------
02113   IF (IOPT.EQ.0) THEN
02114 !   Calcul de IW, TTT, R
02115     CALL SPLR(NORDOPT,X,DS,IW,TTT,R,IREP)  
02116 !   Calcul de RK, U, DB    
02117     CALL SPLU(NORDOPT,X,G,R,RK,U,DB)
02118   ENDIF
02119    !calcul de W, RZ
02120   CALL SPLW(Z,R,U,W,RZ)
02121   !calcul de P
02122   CALL SPLP(LISSAGE,N,DB,W,P,S2,IREP)
02123 
02124 ELSE
02125 
02126 !  Recherche de nordopt et popt
02127 !  ----------------------------
02128 
02129   NORDMI=ND/2+1
02130 
02131 !  Calcul de l'ordre maximal pour le nombre de points n
02132   CALL SPLM(ND,NORD,M)
02133   DO WHILE(N.GT.M) 
02134     NORD=NORD+1
02135     CALL SPLM(ND,NORD,M)
02136   ENDDO
02137   NORDMA=MIN(NORD,NORDMAX)
02138   NORDM=NORDMA
02139 
02140 !  Calcul de Vm pour les differents ordre
02141   DO NORD=NORDMI,NORDMA
02142     !calcul de M
02143     CALL SPLM(ND,NORD,M)
02144     CALL SPLR(NORD,X,DS,IW,TTT,R,IREP)
02145     CALL SPLU(NORD,X,G,R,RK,U,DB)    
02146     CALL SPLW(Z,R,U,W,RZ)
02147     CALL SPLP(LISSAGE,N,DB,W,P,S2,IREP)
02148     MSAVE(NORD)=M
02149     S2SAVE(NORD)=S2
02150     PSAVE(NORD)=P
02151     IF (IREP.EQ.0) THEN
02152       !calcul de VM(NORD)
02153       CALL SPLV(DB,W,N,P,VM(NORD))
02154       WRITE(*,FMT='(A15,I5,A5,G15.5,A6,G15.5)')&
02155         "CNORD : NORD = ",NORD," P = ",P," VM = ",VM(NORD)
02156     ELSE
02157       IF (NORD.EQ.NORDMI) THEN
02158         NORDOPT=NORD
02159         IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SP0NOP',1,ZHOOK_HANDLE)
02160         RETURN
02161       ELSE
02162         NORDM=NORD-1
02163         IREP=0
02164         EXIT
02165       ENDIF
02166     ENDIF
02167   ENDDO
02168 
02169 !  Recherche de l'ordre optimal
02170   VMMIN=1.E200
02171   DO NORD=NORDMI,NORDM
02172     IF(VM(NORD).LT.VMMIN) THEN
02173       VMMIN=VM(NORD)
02174       NORDOPT=NORD
02175       M=MSAVE(NORD)
02176       S2=S2SAVE(NORD)
02177       P=PSAVE(NORD)
02178     ENDIF
02179   ENDDO
02180   WRITE(*,FMT='(A24,I5)') "CNORD : ORDRE OPTIMAL = ",NORDOPT
02181 ENDIF
02182 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SP0NOP',1,ZHOOK_HANDLE)
02183 
02184 END SUBROUTINE SP0NOP
02185 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
02186 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
02187 !39. 
02188 SUBROUTINE SP0CVQ(NORD,M,X,G,Z,DS,S2,P,LISSAGE,LORDRE,IOPT,C,IREP)
02189 !SPLB2C
02190 IMPLICIT NONE
02191 
02192 INTEGER, INTENT(INOUT) :: NORD
02193 INTEGER, INTENT(INOUT) :: M
02194 REAL,DIMENSION(:,:), INTENT(IN) :: X !ND,N
02195 REAL, DIMENSION(:,:), INTENT(IN) :: G !ND,ND
02196 REAL,DIMENSION(:), INTENT(IN) :: Z ! N
02197 REAL, DIMENSION(:), INTENT(IN) :: DS !N
02198 REAL, INTENT(INOUT) :: S2
02199 REAL, INTENT(INOUT) :: P
02200 INTEGER, INTENT(IN) :: LISSAGE
02201 INTEGER, INTENT(IN) :: LORDRE
02202 INTEGER, INTENT(IN) :: IOPT
02203 REAL, DIMENSION(:), INTENT(OUT) :: C !N+M
02204 INTEGER, INTENT(OUT) :: IREP
02205 
02206 INTEGER, DIMENSION(SIZE(X,1),SIZE(C)-SIZE(X,2)) :: IW
02207 REAL, DIMENSION(SIZE(C)-SIZE(X,2),SIZE(X,2)) :: TTT ! M,N
02208 REAL, DIMENSION(SIZE(X,2),2*SIZE(X,2)-SIZE(C)) :: R ! N,N-M
02209 REAL,DIMENSION(SIZE(X,2),SIZE(X,2)) :: RK !N,N
02210 REAL,DIMENSION(2*SIZE(X,2)-SIZE(C),2*SIZE(X,2)-SIZE(C)) :: U !N-M,N-M
02211 REAL,DIMENSION(2*SIZE(X,2)-SIZE(C)):: DB !N-M
02212 REAL, DIMENSION(2*SIZE(X,2)-SIZE(C)) :: W !N-M
02213 REAL,DIMENSION(SIZE(R,2)) :: RZ !N-M
02214 REAL, DIMENSION(SIZE(X,2),SIZE(X,2)) :: Q ! N,N
02215 REAL :: RN
02216 REAL, DIMENSION(SIZE(X,2)) :: RKC !RKC(N)
02217 
02218 
02219 INTEGER :: N
02220 REAL(KIND=JPRB) :: ZHOOK_HANDLE
02221 
02222 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SP0CVQ',0,ZHOOK_HANDLE)
02223 N=SIZE(X,2)
02224 
02225 ! Test des differents parametres
02226 IF (NORD.LT.1) THEN
02227   WRITE(*,FMT='(A17)') "SP0CVQ : NORD < 1"
02228 ELSEIF (M.LT.0) THEN
02229   WRITE(*,'(A14)') "SP0CVQ : M < 0"
02230 ELSEIF (N.LT.M) THEN
02231   WRITE(*,'(A14)') "SP0CVQ : N < M"
02232 ELSEIF (S2.LT.0.) THEN
02233   WRITE(*,'(A15)') "SP0CVQ : S2 < 0"
02234 ELSEIF (P.LT.0.) THEN
02235   WRITE(*,'(A14)') "SP0CVQ : P < 0"
02236 ELSEIF ((LISSAGE.LT.0.OR.LISSAGE.GT.3).AND.LISSAGE.NE.10) THEN
02237   WRITE(*,'(A27)') "SP0CVQ : LISSAGE < 0 OU > 3"
02238 ELSEIF (LORDRE.LT.0.OR.LORDRE.GT.1) THEN
02239   WRITE(*,'(A26)') "SP0CVQ : LORDRE < 0 OU > 1"
02240 ELSEIF (IOPT.LT.0.OR.IOPT.GT.1) THEN
02241   WRITE(*,'(A24)') "SP0CVQ : IOPT < 0 OU > 1"
02242 ELSE
02243 
02244 !     Determination de nord opt ou de p pot
02245 !   -----------------------------------------
02246   IF (LORDRE.EQ.1 .OR. &
02247        LISSAGE.EQ.1 .OR. LISSAGE.EQ.2 .OR. LISSAGE.EQ.10)  THEN 
02248        !calcul de P en passant par SPLR, SPLU, SPLW, si LORDRE = 0
02249        !calcul de NORD, M, S2, P si LORDRE=1
02250     CALL SP0NOP(X,G,Z,DS,LISSAGE,LORDRE,IOPT,NORD,M,S2,P,&
02251          IW,TTT,R,RK,U,DB,W,RZ,IREP) 
02252   ELSEIF (LISSAGE.EQ.0) THEN
02253     P=0.
02254   ENDIF
02255 !---------------------------------------------------------------------
02256 !---------------------------------------------------------------------
02257 
02258   IF (LORDRE.EQ.1 .OR. LISSAGE.EQ.0 .OR. LISSAGE.EQ.3) THEN
02259     IF (IOPT.EQ.0) THEN
02260 !     Calcul de IW, TTT, R
02261       CALL SPLR(NORD,X,DS,IW,TTT,R,IREP)
02262       IF (IREP.NE.0 .AND. LHOOK) CALL DR_HOOK('MODE_SPLINES:SP0CVQ',1,ZHOOK_HANDLE)
02263       IF (IREP.NE.0) RETURN
02264 !     Calcul de  RK, U, DB
02265       CALL SPLU(NORD,X,G,R,RK,U,DB)  
02266     ENDIF
02267 !---------------------------------------------------------------------
02268 !   Calcul de W,RZ
02269     CALL SPLW(Z,R,U,W,RZ)
02270 !   Calcul de S2 pour lissage=3
02271     IF (LISSAGE.EQ.3) CALL SPLRS(DB,W,N,P,S2)
02272   ENDIF
02273 
02274 !---------------------------------------------------------------------
02275 !---------------------------------------------------------------------
02276 ! Calcul de Q
02277   CALL SPLVPQ(P,R,RK,U,DB,Q)
02278 ! Calcul de RN
02279   CALL SPLBVM(DB,W,N,P,RN)
02280 ! Calcul des coefficients C et RKC
02281   CALL SPLC(Q,Z,RK,DS,TTT,RKC,C)
02282   IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SP0CVQ',1,ZHOOK_HANDLE)
02283   RETURN
02284 
02285 ENDIF
02286 
02287 IREP=-1
02288 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SP0CVQ',1,ZHOOK_HANDLE)
02289 
02290 END SUBROUTINE SP0CVQ
02291 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
02292 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
02293 !40. AI(ND,ND,NSDMAX): calcul de AI en fonction de XD, NSD, INTER; 
02294 !remarque: on dirait que la deuxième dimension de AI est plutôt 2 que ND
02295 SUBROUTINE SPLBSD(NSD,INTER,XD,AI)
02296 !SPLB2C
02297 IMPLICIT NONE
02298 
02299 INTEGER, DIMENSION(:), INTENT(IN) :: NSD
02300 INTEGER, INTENT(IN) :: INTER
02301 REAL, DIMENSION(:,:), INTENT(IN) :: XD
02302 REAL, DIMENSION(:,:,:), INTENT(OUT) :: AI
02303 REAL(KIND=JPRB) :: ZHOOK_HANDLE
02304 
02305 REAL, DIMENSION(SIZE(NSD)) :: DXI, DXR
02306 INTEGER :: J, I
02307 
02308 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLBSD',0,ZHOOK_HANDLE)
02309 DO J=1,SIZE(NSD)
02310   DXI(J)=(XD(2,J)-XD(1,J))/NSD(J)
02311   DXR(J)=DXI(J)/(2*INTER-2)
02312 ENDDO
02313 
02314 DO J=1,SIZE(NSD)
02315   AI(J,1,1)=XD(1,J)
02316   DO I=2,NSD(J)
02317     AI(J,1,I)=XD(1,J)+(I-1)*DXI(J)-DXR(J)
02318   ENDDO
02319   AI(J,2,NSD(J))=XD(2,J)
02320   DO I=1,NSD(J)-1
02321     AI(J,2,I)=XD(2,J)-(NSD(J)-I)*DXI(J)+DXR(J)
02322   ENDDO
02323 ENDDO
02324 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLBSD',1,ZHOOK_HANDLE)
02325 
02326 END SUBROUTINE SPLBSD
02327 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
02328 !41. récupère les X et Z tels que les valeurs soient toutes comprises entre 
02329 !A et B, dans XS et ZS. NS est la taille finale des tableaux. 
02330 SUBROUTINE SPLBSEL(X,Z,AI,BI,NS,XS,ZS,IREP)
02331 !SPLB2C
02332 IMPLICIT NONE
02333 
02334 REAL, DIMENSION(:,:), INTENT(IN) :: X !ND,N
02335 REAL, DIMENSION(:), INTENT(IN) :: Z !N
02336 REAL, DIMENSION(:), INTENT(IN) :: AI !ND
02337 REAL, DIMENSION(:), INTENT(IN) :: BI !ND
02338 INTEGER, INTENT(OUT) :: NS
02339 REAL, DIMENSION(:,:), INTENT(OUT) :: XS !ND,NMAX
02340 REAL, DIMENSION(:), INTENT(OUT) :: ZS !NMAX
02341 INTEGER, INTENT(OUT) :: IREP
02342 
02343 INTEGER :: I, J, I0
02344 REAL(KIND=JPRB) :: ZHOOK_HANDLE
02345 
02346 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLBSEL',0,ZHOOK_HANDLE)
02347 IREP=0
02348 NS=0
02349 DO J=1,SIZE(X,2)
02350   I0=0
02351   DO I=1,SIZE(X,1)
02352    !il faut que tous les X(I,J) soient compris entre AI et BI
02353     IF (X(I,J).LT.AI(I).OR.X(I,J).GT.BI(I)) THEN 
02354       I0=1
02355       EXIT
02356     ENDIF
02357   ENDDO
02358   IF (I0.NE.1) THEN
02359     NS=NS+1
02360     IF (NS.GT.SIZE(ZS)) THEN
02361       IREP=-1
02362       IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLBSEL',1,ZHOOK_HANDLE)
02363       RETURN
02364     ENDIF
02365     DO I=1,SIZE(X,1)
02366       XS(I,NS)=X(I,J)
02367     ENDDO
02368     ZS(NS)=Z(J)
02369   ENDIF
02370 ENDDO
02371 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLBSEL',1,ZHOOK_HANDLE)
02372 
02373 END SUBROUTINE SPLBSEL
02374 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
02375 !42. appelée par INTERPOL_SPLINES
02376 SUBROUTINE SPLB2C(NORD,M,X,G,Z,S2,P,LISSAGE,IOPT,NSDI,NSDJ,&
02377                         INTER,XD,C,IREP)
02378 !INTERPOL_SPLINES
02379 IMPLICIT NONE
02380 
02381 INTEGER, INTENT(INOUT) :: NORD 
02382 INTEGER, INTENT(INOUT) :: M
02383 REAL, DIMENSION(:,:), INTENT(IN) :: X !ND,N
02384 REAL, DIMENSION(:,:), INTENT(IN) :: G ! ND,ND
02385 REAL, DIMENSION(:), INTENT(IN) :: Z !N
02386 REAL, INTENT(INOUT) :: S2
02387 REAL, INTENT(INOUT) :: P
02388 INTEGER, INTENT(IN) :: LISSAGE
02389 INTEGER, INTENT(IN) :: IOPT
02390 INTEGER, INTENT(IN) :: NSDI
02391 INTEGER, INTENT(IN) :: NSDJ
02392 INTEGER, INTENT(IN) :: INTER
02393 REAL, DIMENSION(:,:), INTENT(IN) :: XD !2,ND
02394 REAL, DIMENSION(:,:,:), INTENT(OUT) :: C !nmax+mmax,nsdi,nsdj
02395 INTEGER, INTENT(OUT) :: IREP
02396 !
02397 INTEGER :: NN, ND
02398 INTEGER :: LORDRE, I, J
02399 INTEGER, DIMENSION(2) :: NSD
02400 REAL, DIMENSION(NMAX) :: DS
02401 REAL, DIMENSION(2,2) :: CI
02402 
02403 REAL(KIND=JPRB) :: ZHOOK_HANDLE
02404 
02405 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLB2C',0,ZHOOK_HANDLE)
02406 ND=SIZE(X,1)
02407 IF (.NOT.ALLOCATED(AI)) ALLOCATE(AI(ND,2,NSDMAX))
02408 IF (.NOT.ALLOCATED(NS)) ALLOCATE(NS(NSDMAX,NSDMAX))
02409 IF (.NOT.ALLOCATED(ZS)) ALLOCATE(ZS(NMAX,NSDMAX,NSDMAX))
02410 IF (.NOT.ALLOCATED(XS)) ALLOCATE(XS(ND,NMAX,NSDMAX,NSDMAX))
02411 
02412 ! Initialisation de Ds
02413 DS(:)=1.
02414 
02415 ! Generation des sous-domaines: matrice AI de MODD_SPLINES
02416 NSD(1)=NSDI
02417 NSD(2)=NSDJ
02418  CALL SPLBSD(NSD,INTER,XD,AI)
02419 
02420 LORDRE=0
02421 
02422 ! Calcul des splines par sous-domaines
02423 DO I=1,NSDI
02424   DO J=1,NSDJ
02425     CI(1,1)=AI(1,1,I)
02426     CI(1,2)=AI(1,2,I)
02427     CI(2,1)=AI(2,1,J)
02428     CI(2,2)=AI(2,2,J)
02429     !selection des points
02430     CALL SPLBSEL(X,Z,CI(:,1),CI(:,2),NS(I,J),XS(:,:,I,J),ZS(:,I,J),IREP)
02431     IF (IREP.NE.0) THEN
02432       WRITE(*,FMT='(A35)') "SPLB2C: NOMBRE DE POINTS TROP GRAND"
02433       IREP=-4
02434       CALL ABOR1_SFX('SPLINES: SPLB2C: NOMBRE DE POINTS TROP GRAND')
02435     ELSEIF (NS(I,J).LE.M) THEN
02436       WRITE(*,FMT='(A42)') &
02437         "SPB2C : NB DE PTS <= M : COEF NON CALCULES"
02438     ENDIF
02439     !calcul de la spline
02440     IF (NS(I,J).GT.M) THEN
02441        NN=NS(I,J) 
02442       !X(ND,NN) ZS(NN) C(NN+M) IW(ND,M) W(7*NN*NN)
02443       CALL SP0CVQ(NORD,M,XS(:,1:NN,I,J),G,ZS(1:NN,I,J),DS(1:NN),S2,P,&
02444         LISSAGE,LORDRE,IOPT,C(1:NN+M,I,J),IREP)   
02445     ENDIF 
02446   ENDDO
02447 ENDDO
02448 IF (LHOOK) CALL DR_HOOK('MODE_SPLINES:SPLB2C',1,ZHOOK_HANDLE)
02449 
02450 END SUBROUTINE SPLB2C
02451 
02452 
02453 END MODULE MODE_SPLINES