summaryrefslogtreecommitdiff
path: root/Utilib/src/ALGUER.f
diff options
context:
space:
mode:
authorstainer_t <thomas.stainer@oecd-nea.org>2025-09-08 13:48:49 +0200
committerstainer_t <thomas.stainer@oecd-nea.org>2025-09-08 13:48:49 +0200
commit7dfcc480ba1e19bd3232349fc733caef94034292 (patch)
tree03ee104eb8846d5cc1a981d267687a729185d3f3 /Utilib/src/ALGUER.f
Initial commit from Polytechnique Montreal
Diffstat (limited to 'Utilib/src/ALGUER.f')
-rw-r--r--Utilib/src/ALGUER.f92
1 files changed, 92 insertions, 0 deletions
diff --git a/Utilib/src/ALGUER.f b/Utilib/src/ALGUER.f
new file mode 100644
index 0000000..ddd93a1
--- /dev/null
+++ b/Utilib/src/ALGUER.f
@@ -0,0 +1,92 @@
+*DECK ALGUER
+ SUBROUTINE ALGUER(A,M,X,ITS,LFAIL)
+*
+*-----------------------------------------------------------------------
+*
+*Purpose:
+* find one root of a polynomial.
+*
+*Copyright:
+* Copyright (C) 1993 Ecole Polytechnique de Montreal
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version
+*
+*Author(s): A. Hebert
+*
+*Parameters: input
+* A polynomial coefficients. DIMENSION A(M+1)
+* M polynomial order.
+*
+*Parameters: output
+* X complex single root.
+* ITS number of iterations.
+* LFAIL set to .true. in case of failure.
+*
+*-----------------------------------------------------------------------
+*
+ IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+*----
+* SUBROUTINE ARGUMENTS
+*----
+ INTEGER M,ITS
+ COMPLEX*16 A(M+1),X
+ LOGICAL LFAIL
+*----
+* LOCAL VARIABLES
+*----
+ INTEGER MAXIT,MR,MT
+ DOUBLE PRECISION EPSS
+ PARAMETER (EPSS=2.D-7,MR=8,MT=10,MAXIT=MT*MR)
+ INTEGER ITER,J
+ DOUBLE PRECISION ABX,ABP,ABM,ERR,FRAC(MR)
+ COMPLEX*16 DX,X1,B,D,F,G,H,SQ,GP,GM,G2,TMP
+ SAVE FRAC
+ DATA FRAC /.5D0,.25D0,.75D0,.13D0,.38D0,.62D0,.88D0,1.D0/
+*
+ LFAIL=.FALSE.
+ DO 12 ITER=1,MAXIT
+ ITS=ITER
+ B=A(M+1)
+ ERR=ABS(B)
+ D=CMPLX(0.D0,0.D0,KIND=KIND(D))
+ F=CMPLX(0.D0,0.D0,KIND=KIND(F))
+ ABX=ABS(X)
+ DO 11 J=M,1,-1
+ F=X*F+D
+ D=X*D+B
+ B=X*B+A(J)
+ ERR=ABS(B)+ABX*ERR
+11 CONTINUE
+ ERR=EPSS*ERR
+ IF(ABS(B).LE.ERR) THEN
+ RETURN
+ ELSE
+ G=D/B
+ G2=G*G
+ H=G2-2.D0*F/B
+ SQ=SQRT((M-1)*(M*H-G2))
+ GP=G+SQ
+ GM=G-SQ
+ ABP=ABS(GP)
+ ABM=ABS(GM)
+ IF(ABP.LT.ABM) GP=GM
+ IF (MAX(ABP,ABM).GT.0.D0) THEN
+ DX=M/GP
+ ELSE
+ TMP=CMPLX(LOG(1.D0+ABX),DBLE(ITER),KIND=KIND(TMP))
+ DX=EXP(TMP)
+ ENDIF
+ ENDIF
+ X1=X-DX
+ IF(X.EQ.X1)RETURN
+ IF (MOD(ITER,MT).NE.0) THEN
+ X=X1
+ ELSE
+ X=X-DX*FRAC(ITER/MT)
+ ENDIF
+12 CONTINUE
+ LFAIL=.TRUE.
+ RETURN
+ END