module Hyperdualmod
implicit none
type Hyperdual
! x = x0 + x1 e1 + x2 e2 + x3 e1 e2
double precision::x0
double precision::x1
double precision::x2
double precision::x3
end type Hyperdual
! Equal =
interface assignment (=)
module procedure Equal_HH
module procedure Equal_HD
end interface assignment (=)
! Unary operator +, -
interface operator (+)
module procedure Plus_HH
end interface operator (+)
interface operator (-)
module procedure Minus_HH
end interface operator (-)
! Addition operator +
interface operator (+)
module procedure Add_HH
module procedure Add_HD
module procedure Add_DH
end interface operator (+)
! Subtraction operator -
interface operator (-)
module procedure Sub_HH
module procedure Sub_HD
module procedure Sub_DH
end interface operator (-)
! Multiply operator -
interface operator (*)
module procedure Mul_HH
module procedure Mul_HD
module procedure Mul_DH
module procedure Mul_HI
module procedure Mul_IH
end interface operator (*)
! Division operator
interface operator (/)
module procedure Div_HH
module procedure Div_HD
module procedure Div_DH
end interface operator (/)
! Power operator
interface operator (**)
module procedure Pow_HI
module procedure Pow_HH
module procedure Pow_HD
module procedure Pow_DH
end interface operator (**)
! Equal logical
interface operator (.eq.)
module procedure eq_HH
module procedure eq_HD
module procedure eq_DH
module procedure eq_HI
module procedure eq_IH
end interface operator (.eq.)
! Not equal logical
interface operator (.ne.)
module procedure ne_HH
module procedure ne_HD
module procedure ne_DH
module procedure ne_HI
module procedure ne_IH
end interface operator (.ne.)
! Less than logical
interface operator (.lt.)
module procedure lt_HH
module procedure lt_HD
module procedure lt_DH
module procedure lt_HI
module procedure lt_IH
end interface operator (.lt.)
! Less or equal logical
interface operator (.le.)
module procedure le_HH
module procedure le_HD
module procedure le_DH
module procedure le_HI
module procedure le_IH
end interface operator (.le.)
! Greater than logical
interface operator (.gt.)
module procedure gt_HH
module procedure gt_HD
module procedure gt_DH
module procedure gt_HI
module procedure gt_IH
end interface operator (.gt.)
! Greater than or equal
interface operator (.ge.)
module procedure ge_HH
module procedure ge_HD
module procedure ge_DH
module procedure ge_HI
module procedure ge_IH
end interface operator (.ge.)
! abs
interface abs
module procedure abs_H
end interface abs
! int
interface int
module procedure int_H
end interface int
! nint
interface nint
module procedure nint_H
end interface nint
! real
interface real
module procedure real_H
end interface real
! sign
interface sign
module procedure sign_HH
module procedure sign_HD
module procedure sign_DH
end interface sign
! sin
interface sin
module procedure sin_H
end interface sin
! cos
interface cos
module procedure cos_H
end interface cos
! tan
interface tan
module procedure tan_H
end interface tan
! sqrt
interface sqrt
module procedure sqrt_H
end interface sqrt
! log
interface log
module procedure log_H
end interface log
! log10
interface log10
module procedure log10_H
end interface log10
! exp
interface exp
module procedure exp_H
end interface exp
! sinh
interface sinh
module procedure sinh_H
end interface sinh
! cosh
interface cosh
module procedure cosh_H
end interface cosh
! tanh
interface tanh
module procedure tanh_H
end interface tanh
! acos
interface acos
module procedure acos_H
end interface acos
! asin
interface asin
module procedure asin_H
end interface asin
! atan
interface atan
module procedure atan_H
end interface atan
! atan2
interface atan2
module procedure atan2_H
end interface atan2
contains
subroutine Equal_HH(res, inp)
implicit none
type(Hyperdual),intent(out) :: res
type(Hyperdual),intent(in) :: inp
res%x0 = inp%x0
res%x1 = inp%x1
res%x2 = inp%x2
res%x3 = inp%x3
end subroutine Equal_HH
subroutine Equal_HD(res, inp)
implicit none
type(Hyperdual),intent(out) :: res
double precision,intent(in) :: inp
res%x0 = inp
res%x1 = 0d0
res%x2 = 0d0
res%x3 = 0d0
end subroutine Equal_HD
!---------------------------------------
function Plus_HH(t1) result (t2)
type(Hyperdual),intent(in) :: t1
type(Hyperdual) :: t2
t2%x0 = t1%x0
t2%x1 = t1%x1
t2%x2 = t1%x2
t2%x3 = t1%x3
end function Plus_HH
function Minus_HH(t1) result (t2)
type(Hyperdual),intent(in) :: t1
type(Hyperdual) :: t2
t2%x0 = -t1%x0
t2%x1 = -t1%x1
t2%x2 = -t1%x2
t2%x3 = -t1%x3
end function Minus_HH
!---------------------------------------
function Add_HH(t1,t2) result (t3)
type(Hyperdual), intent(in) :: t1,t2
type(Hyperdual) :: t3
t3%x0 = t1%x0 + t2%x0
t3%x1 = t1%x1 + t2%x1
t3%x2 = t1%x2 + t2%x2
t3%x3 = t1%x3 + t2%x3
end function Add_HH
function Add_HD(t1,t2) result (t3)
type(Hyperdual), intent(in) :: t1
double precision,intent(in) :: t2
type(Hyperdual) :: t3
t3%x0 = t1%x0 + t2
t3%x1 = t1%x1
t3%x2 = t1%x2
t3%x3 = t1%x3
end function Add_HD
function Add_DH(t1,t2) result (t3)
double precision,intent(in) :: t1
type(Hyperdual), intent(in) :: t2
type(Hyperdual) :: t3
t3%x0 = t1 + t2%x0
t3%x1 = t2%x1
t3%x2 = t2%x2
t3%x3 = t2%x3
end function Add_DH
!---------------------------------------
function Sub_HH(t1,t2) result (t3)
type(Hyperdual), intent(in) :: t1,t2
type(Hyperdual) :: t3
t3%x0 = t1%x0 - t2%x0
t3%x1 = t1%x1 - t2%x1
t3%x2 = t1%x2 - t2%x2
t3%x3 = t1%x3 - t2%x3
end function Sub_HH
function Sub_HD(t1,t2) result (t3)
type(Hyperdual), intent(in) :: t1
double precision,intent(in) :: t2
type(Hyperdual) :: t3
t3%x0 = t1%x0 - t2
t3%x1 = t1%x1
t3%x2 = t1%x2
t3%x3 = t1%x3
end function Sub_HD
function Sub_DH(t1,t2) result (t3)
double precision,intent(in) :: t1
type(Hyperdual), intent(in) :: t2
type(Hyperdual) :: t3
t3%x0 = t1 - t2%x0
t3%x1 = t2%x1
t3%x2 = t2%x2
t3%x3 = t2%x3
end function Sub_DH
!---------------------------------------
function Mul_HH(t1,t2) result (t3)
type(Hyperdual), intent(in) :: t1,t2
type(Hyperdual) :: t3
t3%x0 = t1%x0 * t2%x0
t3%x1 = t1%x0 * t2%x1 + t1%x1 * t2%x0
t3%x2 = t1%x0 * t2%x2 + t1%x2 * t2%x0
t3%x3 = t1%x0 * t2%x3 + t1%x1 * t2%x2 &
+ t1%x2 * t2%x1 + t1%x3 * t2%x0
end function Mul_HH
function Mul_HD(t1,t2) result (t3)
type(Hyperdual), intent(in) :: t1
double precision,intent(in) :: t2
type(Hyperdual) :: t3
t3%x0 = t1%x0 * t2
t3%x1 = t1%x1 * t2
t3%x2 = t1%x2 * t2
t3%x3 = t1%x3 * t2
end function Mul_HD
function Mul_DH(t1,t2) result (t3)
double precision,intent(in) :: t1
type(Hyperdual), intent(in) :: t2
type(Hyperdual) :: t3
t3%x0 = t1 * t2%x0
t3%x1 = t1 * t2%x1
t3%x2 = t1 * t2%x2
t3%x3 = t1 * t2%x3
end function Mul_DH
function Mul_HI(t1,t2) result (t3)
type(Hyperdual), intent(in) :: t1
integer ,intent(in) :: t2
type(Hyperdual) :: t3
t3%x0 = t1%x0 * t2
t3%x1 = t1%x1 * t2
t3%x2 = t1%x2 * t2
t3%x3 = t1%x3 * t2
end function Mul_HI
function Mul_IH(t1,t2) result (t3)
integer ,intent(in) :: t1
type(Hyperdual), intent(in) :: t2
type(Hyperdual) :: t3
t3%x0 = t1 * t2%x0
t3%x1 = t1 * t2%x1
t3%x2 = t1 * t2%x2
t3%x3 = t1 * t2%x3
end function Mul_IH
!-----------------------------------------
function Div_HH(t1,t2) result (t3)
type(Hyperdual), intent(in) :: t1,t2
type(Hyperdual) :: s2, t3
double precision:: u2
s2%x0 = 1d0/t2%x0
u2 = s2%x0 * s2%x0
s2%x1 = - t2%x1 * u2
s2%x2 = - t2%x2 * u2
s2%x3 = (- t2%x3 + 2d0 * t2%x1 * t2%x2 * s2%x0) * u2
t3%x0 = t1%x0 * s2%x0
t3%x1 = t1%x0 * s2%x1 + t1%x1 * s2%x0
t3%x2 = t1%x0 * s2%x2 + t1%x2 * s2%x0
t3%x3 = t1%x0 * s2%x3 + t1%x1 * s2%x2 &
+ t1%x2 * s2%x1 + t1%x3 * s2%x0
end function Div_HH
function Div_HD(t1,t2) result (t3)
type(Hyperdual), intent(in) :: t1
double precision,intent(in) :: t2
type(Hyperdual) :: t3
double precision :: s2
s2 = 1d0/t2
t3%x0 = t1%x0 * s2
t3%x1 = t1%x1 * s2
t3%x2 = t1%x2 * s2
t3%x3 = t1%x3 * s2
end function Div_HD
function Div_DH(t1,t2) result (t3)
double precision,intent(in) :: t1
type(Hyperdual), intent(in) :: t2
type(Hyperdual) :: s2, t3
double precision :: u2
s2%x0 = 1d0/t2%x0
u2 = s2%x0 * s2%x0
s2%x1 = - t2%x1 * u2
s2%x2 = - t2%x2 * u2
s2%x3 = (- t2%x3 + 2d0 * t2%x1 * t2%x2 * s2%x0) * u2
t3%x0 = t1 * s2%x0
t3%x1 = t1 * s2%x1
t3%x2 = t1 * s2%x2
t3%x3 = t1 * s2%x3
end function Div_DH
!--------------------------
function Pow_HI(t1,t2) result (t3)
type(Hyperdual),intent(in) :: t1
integer,intent(in) :: t2
integer :: i, m
type(Hyperdual) :: t3
t3 = 1d0
m = abs(t2)
do i=1,m
t3 = t3*t1
enddo
if(t2 .lt. 0) t3 = 1d0/t3
end function Pow_HI
function Pow_HH(t1,t2) result (t3)
type(Hyperdual),intent(in) :: t1, t2
type(Hyperdual) :: t3, v4
v4 = log_H(t1)
t3 = exp_H(t2*v4)
end function Pow_HH
function Pow_DH(t1,t2) result (t3)
double precision,intent(in) :: t1
type(Hyperdual), intent(in) :: t2
double precision :: v4
type(Hyperdual) :: t3
v4 = log(t1)
t3 = exp_H(t2*v4)
end function Pow_DH
function Pow_HD(t1,t2) result (t3)
type(Hyperdual), intent(in) :: t1
double precision,intent(in) :: t2
type(Hyperdual) :: t3
double precision,parameter :: tol=1d-30
double precision :: tx, p1, p2
tx = t1%x0
if(abs(tx) .lt. tol) then
if(tx .ge. 0d0) then
tx = tol
else
tx = -tol
endif
endif
p1 = t2*(tx**(t2-1d0))
p2 = t2*(t2-1d0)*(tx**(t2-2d0))
t3%x0 = (t1%x0)**t2
t3%x1 = t1%x1 *p1
t3%x2 = t1%x2 *p1
t3%x3 = t1%x3 *p1 + t1%x1 * t1%x2 *p2
end function Pow_HD
!---------------------------------
! .eq.
logical function eq_HH(lhs, rhs)
type(Hyperdual),intent(in)::lhs, rhs
eq_HH = lhs%x0 == rhs%x0
end function eq_HH
logical function eq_HD(lhs, rhs)
type(Hyperdual),intent(in)::lhs
double precision,intent(in)::rhs
eq_HD = lhs%x0 == rhs
end function eq_HD
logical function eq_DH(lhs, rhs)
double precision,intent(in)::lhs
type(Hyperdual),intent(in)::rhs
eq_DH = lhs == rhs%x0
end function eq_DH
logical function eq_HI(lhs, rhs)
type(Hyperdual),intent(in)::lhs
integer,intent(in)::rhs
eq_HI = lhs%x0 == rhs
end function eq_HI
logical function eq_IH(lhs, rhs)
integer,intent(in)::lhs
type(Hyperdual),intent(in)::rhs
eq_IH = lhs == rhs%x0
end function eq_IH
!------------------------
! .ne.
logical function ne_HH(lhs, rhs)
type(Hyperdual),intent(in)::lhs, rhs
ne_HH = lhs%x0 /= rhs%x0
end function ne_HH
logical function ne_HD(lhs, rhs)
type(Hyperdual),intent(in)::lhs
double precision,intent(in)::rhs
ne_HD = lhs%x0 /= rhs
end function ne_HD
logical function ne_DH(lhs, rhs)
double precision,intent(in)::lhs
type(Hyperdual),intent(in)::rhs
ne_DH = lhs /= rhs%x0
end function ne_DH
logical function ne_HI(lhs, rhs)
type(Hyperdual),intent(in)::lhs
integer,intent(in)::rhs
ne_HI = lhs%x0 /= rhs
end function ne_HI
logical function ne_IH(lhs, rhs)
integer,intent(in)::lhs
type(Hyperdual),intent(in)::rhs
ne_IH = lhs /= rhs%x0
end function ne_IH
!-------------------
! .lt.
logical function lt_HH(lhs, rhs)
type(Hyperdual),intent(in)::lhs, rhs
lt_HH = lhs%x0 < rhs%x0
end function lt_HH
logical function lt_HD(lhs, rhs)
type(Hyperdual),intent(in)::lhs
double precision,intent(in)::rhs
lt_HD = lhs%x0 < rhs
end function lt_HD
logical function lt_DH(lhs, rhs)
double precision,intent(in)::lhs
type(Hyperdual),intent(in)::rhs
lt_DH = lhs < rhs%x0
end function lt_DH
logical function lt_HI(lhs, rhs)
type(Hyperdual),intent(in)::lhs
integer,intent(in)::rhs
lt_HI = lhs%x0 < rhs
end function lt_HI
logical function lt_IH(lhs, rhs)
integer,intent(in)::lhs
type(Hyperdual),intent(in)::rhs
lt_IH = lhs < rhs%x0
end function lt_IH
!-------------------
!.le.
logical function le_HH(lhs, rhs)
type(Hyperdual),intent(in)::lhs, rhs
le_HH = lhs%x0 <= rhs%x0
end function le_HH
logical function le_HD(lhs, rhs)
type(Hyperdual),intent(in)::lhs
double precision,intent(in)::rhs
le_HD = lhs%x0 <= rhs
end function le_HD
logical function le_DH(lhs, rhs)
double precision,intent(in)::lhs
type(Hyperdual),intent(in)::rhs
le_DH = lhs <= rhs%x0
end function le_DH
logical function le_HI(lhs, rhs)
type(Hyperdual),intent(in)::lhs
integer,intent(in)::rhs
le_HI = lhs%x0 <= rhs
end function le_HI
logical function le_IH(lhs, rhs)
integer,intent(in)::lhs
type(Hyperdual),intent(in)::rhs
le_IH = lhs <= rhs%x0
end function le_IH
!-------------------
! .gt.
logical function gt_HH(lhs, rhs)
type(Hyperdual),intent(in)::lhs, rhs
gt_HH = lhs%x0 > rhs%x0
end function gt_HH
logical function gt_HD(lhs, rhs)
type(Hyperdual),intent(in)::lhs
double precision,intent(in)::rhs
gt_HD = lhs%x0 > rhs
end function gt_HD
logical function gt_DH(lhs, rhs)
double precision,intent(in)::lhs
type(Hyperdual),intent(in)::rhs
gt_DH = lhs > rhs%x0
end function gt_DH
logical function gt_HI(lhs, rhs)
type(Hyperdual),intent(in)::lhs
integer,intent(in)::rhs
gt_HI = lhs%x0 > rhs
end function gt_HI
logical function gt_IH(lhs, rhs)
integer,intent(in)::lhs
type(Hyperdual),intent(in)::rhs
gt_IH = lhs > rhs%x0
end function gt_IH
!----------------------------
! .ge.
logical function ge_HH(lhs, rhs)
type(Hyperdual),intent(in)::lhs, rhs
ge_HH = lhs%x0 >= rhs%x0
end function ge_HH
logical function ge_HD(lhs, rhs)
type(Hyperdual),intent(in)::lhs
double precision,intent(in)::rhs
ge_HD = lhs%x0 >= rhs
end function ge_HD
logical function ge_DH(lhs, rhs)
double precision,intent(in)::lhs
type(Hyperdual),intent(in)::rhs
ge_DH = lhs >= rhs%x0
end function ge_DH
logical function ge_HI(lhs, rhs)
type(Hyperdual),intent(in)::lhs
integer,intent(in)::rhs
ge_HI = lhs%x0 >= rhs
end function ge_HI
logical function ge_IH(lhs, rhs)
integer,intent(in)::lhs
type(Hyperdual),intent(in)::rhs
ge_IH = lhs >= rhs%x0
end function ge_IH
!------------------------------
! Absolute
function abs_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
type(Hyperdual)::t2
if(t1%x0 .ge. 0d0) then
t2%x0 = t1%x0
t2%x1 = t1%x1
t2%x2 = t1%x2
t2%x3 = t1%x3
else
t2%x0 = -t1%x0
t2%x1 = -t1%x1
t2%x2 = -t1%x2
t2%x3 = -t1%x3
endif
end function abs_H
! Int
function int_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
integer :: t2
t2 = int(t1%x0)
end function int_H
! Nearest int
function nint_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
integer :: t2
t2 = nint(t1%x0)
end function nint_H
! Real
function real_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
double precision::t2
t2 = t1%x0
end function real_H
! Sign
function sign_HH(t1,t2) result (t3)
type(Hyperdual),intent(in)::t1, t2
type(Hyperdual)::t3
double precision::ssign
if(t2%x0 .lt. 0d0) then
ssign = -1d0
else
ssign = 1d0
endif
t3 = ssign*t1
end function sign_HH
function sign_HD(t1,t2) result (t3)
type(Hyperdual),intent(in)::t1
double precision,intent(in) :: t2
type(Hyperdual)::t3
double precision::ssign
if(t2 .lt. 0d0) then
ssign = -1d0
else
ssign = 1d0
endif
t3 = ssign*t1
end function sign_HD
function sign_DH(t1,t2) result (t3)
double precision,intent(in) :: t1
type(Hyperdual),intent(in)::t2
type(Hyperdual)::t3
double precision :: ssign
if(t2%x0 .lt. 0d0) then
ssign = -1d0
else
ssign = 1d0
endif
t3 = ssign*t1
end function sign_DH
! sin
function sin_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
type(Hyperdual)::t2
double precision::df0, df1, df2
df0 = sin(t1%x0)
df1 = cos(t1%x0)
df2 = -df0
t2%x0 = df0
t2%x1 = t1%x1 * df1
t2%x2 = t1%x2 * df1
t2%x3 = t1%x3 * df1 + t1%x1 * t1%x2 * df2
end function sin_H
! cos
function cos_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
type(Hyperdual)::t2
double precision::df0, df1, df2
df0 = cos(t1%x0)
df1 = -sin(t1%x0)
df2 = -df0
t2%x0 = df0
t2%x1 = t1%x1 * df1
t2%x2 = t1%x2 * df1
t2%x3 = t1%x3 * df1 + t1%x1 * t1%x2 * df2
end function cos_H
! tan
function tan_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
type(Hyperdual)::t2
double precision::df0, df1, df2
df0 = tan(t1%x0)
df1 = 1d0 + df0*df0
df2 = 2d0 * df0 * df1
t2%x0 = df0
t2%x1 = t1%x1 * df1
t2%x2 = t1%x2 * df1
t2%x3 = t1%x3 * df1 + t1%x1 * t1%x2 * df2
end function tan_H
! sqrt
function sqrt_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
type(Hyperdual)::t2
double precision::df0, df1, df2
df0 = sqrt(t1%x0)
df1 = 1d0/(2*df0)
df2 = -2d0*df1*df1*df1
t2%x0 = df0
t2%x1 = t1%x1 * df1
t2%x2 = t1%x2 * df1
t2%x3 = t1%x3 * df1 + t1%x1 * t1%x2 * df2
end function sqrt_H
! log
function log_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
type(Hyperdual)::t2
double precision::df0, df1, df2
df0 = log(t1%x0)
df1 = 1d0/t1%x0
df2 = -df1*df1
t2%x0 = df0
t2%x1 = t1%x1 * df1
t2%x2 = t1%x2 * df1
t2%x3 = t1%x3 * df1 + t1%x1 * t1%x2 * df2
end function log_H
! log10
function log10_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
type(Hyperdual)::t2
double precision::df0, df1, df2
df0 = log10(t1%x0)
df1 = 1d0/(log(10d0)*t1%x0)
df2 = -df1/(t1%x0)
t2%x0 = df0
t2%x1 = t1%x1 * df1
t2%x2 = t1%x2 * df1
t2%x3 = t1%x3 * df1 + t1%x1 * t1%x2 * df2
end function log10_H
! exp
function exp_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
type(Hyperdual)::t2
double precision::df0, df1, df2
df0 = exp(t1%x0)
df1 = df0
df2 = df1
t2%x0 = df0
t2%x1 = t1%x1 * df1
t2%x2 = t1%x2 * df1
t2%x3 = t1%x3 * df1 + t1%x1 * t1%x2 * df2
end function exp_H
! sinh
function sinh_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
type(Hyperdual)::u1, u2, t2
u1 = exp(t1)
u2 = exp(-t1)
t2 = 0.5d0*(u1-u2)
end function sinh_H
! cosh
function cosh_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
type(Hyperdual)::u1, u2, t2
u1 = exp(t1)
u2 = exp(-t1)
t2 = 0.5d0*(u1+u2)
end function cosh_H
! tanh
function tanh_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
type(Hyperdual)::u1, u2, t2
u1 = exp(t1)
u2 = exp(-t1)
t2 = (u1-u2)/(u1+u2)
end function tanh_H
! acos
function acos_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
type(Hyperdual)::t2
double precision::df0, df1, df2
df0 = acos(t1%x0)
df1 = -1d0/sqrt(1d0 - t1%x0*t1%x0)
df2 = df1*df1*df1 * t1%x0
t2%x0 = df0
t2%x1 = t1%x1 * df1
t2%x2 = t1%x2 * df1
t2%x3 = t1%x3 * df1 + t1%x1 * t1%x2 * df2
end function acos_H
! asin
function asin_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
type(Hyperdual)::t2
double precision::df0, df1, df2
df0 = asin(t1%x0)
df1 = 1d0/sqrt(1d0 - t1%x0*t1%x0)
df2 = df1*df1*df1 * t1%x0
t2%x0 = df0
t2%x1 = t1%x1 * df1
t2%x2 = t1%x2 * df1
t2%x3 = t1%x3 * df1 + t1%x1 * t1%x2 * df2
end function asin_H
! atan
function atan_H(t1) result (t2)
type(Hyperdual),intent(in)::t1
type(Hyperdual)::t2
double precision::df0, df1, df2
df0 = atan(t1%x0)
df1 = 1d0/(1.0d0 + t1%x0*t1%x0)
df2 = -2d0*t1%x0*df1*df1
t2%x0 = df0
t2%x1 = t1%x1 * df1
t2%x2 = t1%x2 * df1
t2%x3 = t1%x3 * df1 + t1%x1 * t1%x2 * df2
end function atan_H
! atan2
function atan2_H(t1, t2) result (t3)
type(Hyperdual),intent(in)::t1, t2
type(Hyperdual)::t3
double precision::a, b, c, d, e, f, g, h
double precision::df0, r2, fx, fy
!y0 y1 y2 y3
a = t1%x0; b = t1%x1; c = t1%x2; d = t1%x3
!x0 x1 x2 x3
e = t2%x0; f = t2%x1; g = t2%x2; h = t2%x3
r2 = a*a + e*e
fx = -e/r2
fy = a/r2
df0 = atan2(a,e)
t3%x0 = df0
t3%x1 = f*fx + b*fy
t3%x2 = g*fx + c*fy
t3%x3 = h*fx + d*fy + (f*c+g*b)*(fx-fy)*(fx+fy) - 2d0*(f*g+b*c)*fx*fy
end function atan2_H
end module Hyperdualmod