module Math.Eisenstein
    ( lambda,
      eisensteinE2,
      eisensteinE4,
      eisensteinE6,
      kleinJ,
      kleinJinv,
      modularDiscriminant,
      agm,
      etaDedekind,
      jtheta1DashDashDash0
    ) where
import           Data.Complex           ( Complex(..) )
import           Internal               ( (%^%) )
import           Math.EllipticIntegrals ( ellipticF', ellipticE' )
import           Math.JacobiTheta       ( jtheta2, jtheta3, jtheta4 )


i_ :: Complex Double
i_ :: Complex Double
i_ = Double
0.0 forall a. a -> a -> Complex a
:+ Double
1.0

-- | Lambda modular function (square of elliptic modulus)
lambda :: 
    Complex Double -- ^ tau
 -> Complex Double
lambda :: Complex Double -> Complex Double
lambda Complex Double
tau = (Complex Double
j2 forall a. Fractional a => a -> a -> a
/ Complex Double
j3) Complex Double -> Int -> Complex Double
%^% Int
4
    where
      q :: Complex Double
q = forall a. Floating a => a -> a
exp (Complex Double
i_ forall a. Num a => a -> a -> a
* forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* Complex Double
tau)
      j2 :: Complex Double
j2 = Complex Double -> Complex Double -> Complex Double
jtheta2 Complex Double
0 Complex Double
q
      j3 :: Complex Double
j3 = Complex Double -> Complex Double -> Complex Double
jtheta3 Complex Double
0 Complex Double
q

-- | Eisenstein series of weight 2
eisensteinE2 :: 
    Complex Double -- ^ tau
 -> Complex Double
eisensteinE2 :: Complex Double -> Complex Double
eisensteinE2 Complex Double
tau = 
  Complex Double
6 forall a. Fractional a => a -> a -> a
/ forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* Complex Double
ellE forall a. Num a => a -> a -> a
* Complex Double
j3 forall a. Num a => a -> a -> a
- Complex Double
j3 forall a. Num a => a -> a -> a
* Complex Double
j3 forall a. Num a => a -> a -> a
- Complex Double
j4
    where
      q :: Complex Double
q = forall a. Floating a => a -> a
exp (Complex Double
i_ forall a. Num a => a -> a -> a
* forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* Complex Double
tau)
      j3 :: Complex Double
j3 = Complex Double -> Complex Double -> Complex Double
jtheta3 Complex Double
0 Complex Double
q Complex Double -> Int -> Complex Double
%^% Int
2
      j4 :: Complex Double
j4 = Complex Double -> Complex Double -> Complex Double
jtheta4 Complex Double
0 Complex Double
q Complex Double -> Int -> Complex Double
%^% Int
4
      ellE :: Complex Double
ellE = Double -> Complex Double -> Complex Double -> Complex Double
ellipticE' Double
1e-14 (forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Complex Double
2) (Complex Double -> Complex Double
lambda Complex Double
tau)

-- | Eisenstein series of weight 4
eisensteinE4 :: 
    Complex Double -- ^ tau
 -> Complex Double
eisensteinE4 :: Complex Double -> Complex Double
eisensteinE4 Complex Double
tau = 
  (Complex Double -> Complex Double -> Complex Double
jtheta2 Complex Double
0 Complex Double
q Complex Double -> Int -> Complex Double
%^% Int
8 forall a. Num a => a -> a -> a
+ Complex Double -> Complex Double -> Complex Double
jtheta3 Complex Double
0 Complex Double
q Complex Double -> Int -> Complex Double
%^% Int
8 forall a. Num a => a -> a -> a
+ Complex Double -> Complex Double -> Complex Double
jtheta4 Complex Double
0 Complex Double
q Complex Double -> Int -> Complex Double
%^% Int
8) forall a. Fractional a => a -> a -> a
/ Complex Double
2 
    where
      q :: Complex Double
q = forall a. Floating a => a -> a
exp (Complex Double
i_ forall a. Num a => a -> a -> a
* forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* Complex Double
tau)

-- | Eisenstein series of weight 6
eisensteinE6 :: 
    Complex Double -- ^ tau
 -> Complex Double
eisensteinE6 :: Complex Double -> Complex Double
eisensteinE6 Complex Double
tau = 
  (Complex Double -> Complex Double -> Complex Double
jtheta3 Complex Double
0 Complex Double
q Complex Double -> Int -> Complex Double
%^% Int
12 forall a. Num a => a -> a -> a
+ Complex Double -> Complex Double -> Complex Double
jtheta4 Complex Double
0 Complex Double
q Complex Double -> Int -> Complex Double
%^% Int
12 forall a. Num a => a -> a -> a
- Complex Double
3 forall a. Num a => a -> a -> a
* Complex Double -> Complex Double -> Complex Double
jtheta2 Complex Double
0 Complex Double
q Complex Double -> Int -> Complex Double
%^% Int
8 
    forall a. Num a => a -> a -> a
* (Complex Double -> Complex Double -> Complex Double
jtheta3 Complex Double
0 Complex Double
q Complex Double -> Int -> Complex Double
%^% Int
4 forall a. Num a => a -> a -> a
+ Complex Double -> Complex Double -> Complex Double
jtheta4 Complex Double
0 Complex Double
q Complex Double -> Int -> Complex Double
%^% Int
4)) forall a. Fractional a => a -> a -> a
/ Complex Double
2
    where
      q :: Complex Double
q = forall a. Floating a => a -> a
exp (Complex Double
i_ forall a. Num a => a -> a -> a
* forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* Complex Double
tau)

-- | Modular discriminant
modularDiscriminant ::
    Complex Double -- ^ tau
 -> Complex Double
modularDiscriminant :: Complex Double -> Complex Double
modularDiscriminant Complex Double
tau = 
  (Complex Double -> Complex Double
eisensteinE4 Complex Double
tau Complex Double -> Int -> Complex Double
%^% Int
3 forall a. Num a => a -> a -> a
- Complex Double -> Complex Double
eisensteinE6 Complex Double
tau Complex Double -> Int -> Complex Double
%^% Int
2) forall a. Fractional a => a -> a -> a
/ Complex Double
1728

-- | Klein J-function
kleinJ :: 
    Complex Double -- ^ tau
 -> Complex Double
kleinJ :: Complex Double -> Complex Double
kleinJ Complex Double
tau = 
  Complex Double -> Complex Double
eisensteinE4 Complex Double
tau Complex Double -> Int -> Complex Double
%^% Int
3 forall a. Fractional a => a -> a -> a
/ Complex Double -> Complex Double
modularDiscriminant Complex Double
tau

-- | Arithmetic-geometric mean
agm :: 
    Complex Double -- ^ x 
 -> Complex Double -- ^ y
 -> Complex Double
agm :: Complex Double -> Complex Double -> Complex Double
agm Complex Double
x Complex Double
y = 
  if Complex Double
x forall a. Eq a => a -> a -> Bool
== Complex Double
0 Bool -> Bool -> Bool
|| Complex Double
y forall a. Eq a => a -> a -> Bool
== Complex Double
0 Bool -> Bool -> Bool
|| Complex Double
x forall a. Num a => a -> a -> a
+ Complex Double
y forall a. Eq a => a -> a -> Bool
== Complex Double
0
    then Complex Double
0
    else forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Complex Double
4 forall a. Num a => a -> a -> a
* (Complex Double
x forall a. Num a => a -> a -> a
+ Complex Double
y) forall a. Fractional a => a -> a -> a
/ Double -> Complex Double -> Complex Double -> Complex Double
ellipticF' Double
1e-15 (forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Complex Double
2) (((Complex Double
x forall a. Num a => a -> a -> a
- Complex Double
y) forall a. Fractional a => a -> a -> a
/ (Complex Double
x forall a. Num a => a -> a -> a
+ Complex Double
y)) Complex Double -> Int -> Complex Double
%^% Int
2)

-- | Inverse Klein-J function
kleinJinv :: 
    Complex Double
 -> Complex Double
kleinJinv :: Complex Double -> Complex Double
kleinJinv Complex Double
j = 
  if Complex Double
j forall a. Eq a => a -> a -> Bool
== Complex Double
0
    then Double
0.5 forall a. a -> a -> Complex a
:+ (forall a. Floating a => a -> a
sqrt Double
3 forall a. Fractional a => a -> a -> a
/ Double
2)
    else Complex Double
i_ forall a. Num a => a -> a -> a
* Complex Double -> Complex Double -> Complex Double
agm Complex Double
1 (forall a. Floating a => a -> a
sqrt(Complex Double
1 forall a. Num a => a -> a -> a
- Complex Double
lbd)) forall a. Fractional a => a -> a -> a
/ Complex Double -> Complex Double -> Complex Double
agm Complex Double
1 (forall a. Floating a => a -> a
sqrt Complex Double
lbd)
  where
    j2 :: Complex Double
j2 = Complex Double
j forall a. Num a => a -> a -> a
* Complex Double
j
    j3 :: Complex Double
j3 = Complex Double
j2 forall a. Num a => a -> a -> a
* Complex Double
j
    t :: Complex Double
t = -Complex Double
j3 forall a. Num a => a -> a -> a
+ Complex Double
2304 forall a. Num a => a -> a -> a
* Complex Double
j2 forall a. Num a => a -> a -> a
+ Complex Double
12288 forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
sqrt(Complex Double
3 forall a. Num a => a -> a -> a
* (Complex Double
1728 forall a. Num a => a -> a -> a
* Complex Double
j2 forall a. Num a => a -> a -> a
- Complex Double
j3)) forall a. Num a => a -> a -> a
- Complex Double
884736 forall a. Num a => a -> a -> a
* Complex Double
j
    u :: Complex Double
u = Complex Double
t forall a. Floating a => a -> a -> a
** (Complex Double
1forall a. Fractional a => a -> a -> a
/Complex Double
3)
    x :: Complex Double
x = Complex Double
4 forall a. Num a => a -> a -> a
+ (Complex Double
u forall a. Num a => a -> a -> a
- Complex Double
j) forall a. Fractional a => a -> a -> a
/ Complex Double
192 forall a. Num a => a -> a -> a
- (Complex Double
1536 forall a. Num a => a -> a -> a
* Complex Double
j forall a. Num a => a -> a -> a
- Complex Double
j2) forall a. Fractional a => a -> a -> a
/ (Complex Double
192 forall a. Num a => a -> a -> a
* Complex Double
u)
    lbd :: Complex Double
lbd = -(-Complex Double
1 forall a. Num a => a -> a -> a
- forall a. Floating a => a -> a
sqrt(Complex Double
1 forall a. Num a => a -> a -> a
- Complex Double
x)) forall a. Fractional a => a -> a -> a
/ Complex Double
2

-- | Dedekind eta function
etaDedekind ::
    Complex Double -- ^ tau
 -> Complex Double
etaDedekind :: Complex Double -> Complex Double
etaDedekind Complex Double
tau = forall a. Floating a => a -> a
exp (Complex Double
ipitau forall a. Fractional a => a -> a -> a
/ Complex Double
12) forall a. Num a => a -> a -> a
* Complex Double
j3
  where
    ipitau :: Complex Double
ipitau = Complex Double
i_ forall a. Num a => a -> a -> a
* forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* Complex Double
tau
    q :: Complex Double
q = forall a. Floating a => a -> a
exp (Complex Double
3 forall a. Num a => a -> a -> a
* Complex Double
ipitau)
    j3 :: Complex Double
j3 = Complex Double -> Complex Double -> Complex Double
jtheta3 (forall a. Floating a => a
pi forall a. Fractional a => a -> a -> a
/ Complex Double
2 forall a. Num a => a -> a -> a
* (Complex Double
tau forall a. Num a => a -> a -> a
+ Complex Double
1)) Complex Double
q

-- | Third derivative at 0 of the first Jacobi theta function
jtheta1DashDashDash0 :: 
    Complex Double -- ^ tau
 -> Complex Double
jtheta1DashDashDash0 :: Complex Double -> Complex Double
jtheta1DashDashDash0 Complex Double
tau = -Complex Double
2 forall a. Num a => a -> a -> a
* Complex Double -> Complex Double
etaDedekind Complex Double
tau Complex Double -> Int -> Complex Double
%^% Int
3 forall a. Num a => a -> a -> a
* Complex Double -> Complex Double
eisensteinE2 Complex Double
tau