module Math.EllipticIntegrals.Elliptic
  where
import Math.EllipticIntegrals.Carlson  ( carlsonRF', carlsonRD', carlsonRJ' )
import Data.Complex                    ( realPart, Complex )
import Math.EllipticIntegrals.Internal ( toCplx, getPhiK )

-- | Elliptic integral of the first kind.
ellipticF' :: 
     Double -- ^ bound on the relative error passed to `carlsonRF'`
  -> Complex Double -- ^ amplitude
  -> Complex Double -- ^ parameter
  -> Complex Double
ellipticF' :: Double -> Complex Double -> Complex Double -> Complex Double
ellipticF' Double
err Complex Double
phi Complex Double
m
  | Complex Double
phi forall a. Eq a => a -> a -> Bool
== Complex Double
0 =
    Double -> Complex Double
toCplx Double
0
  | Complex Double
m forall a. Eq a => a -> a -> Bool
== Complex Double
1 Bool -> Bool -> Bool
&& forall a. Num a => a -> a
abs(forall a. Complex a -> a
realPart Complex Double
phi) forall a. Eq a => a -> a -> Bool
== forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Double
2 =
    Double -> Complex Double
toCplx (Double
0forall a. Fractional a => a -> a -> a
/Double
0)
  | Complex Double
m forall a. Eq a => a -> a -> Bool
== Complex Double
1 Bool -> Bool -> Bool
&& forall a. Num a => a -> a
abs(forall a. Complex a -> a
realPart Complex Double
phi) forall a. Ord a => a -> a -> Bool
< forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Double
2 =
    forall a. Floating a => a -> a
atanh(forall a. Floating a => a -> a
sin Complex Double
phi)
  | forall a. Num a => a -> a
abs(forall a. Complex a -> a
realPart Complex Double
phi) forall a. Ord a => a -> a -> Bool
<= forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Double
2 =
    if Complex Double
m forall a. Eq a => a -> a -> Bool
== Complex Double
0
      then
        Complex Double
phi
      else
        let sine :: Complex Double
sine = forall a. Floating a => a -> a
sin Complex Double
phi in
        let sine2 :: Complex Double
sine2 = Complex Double
sineforall a. Num a => a -> a -> a
*Complex Double
sine in
        let (Complex Double
cosine2, Complex Double
oneminusmsine2) = (Complex Double
1 forall a. Num a => a -> a -> a
- Complex Double
sine2, Complex Double
1 forall a. Num a => a -> a -> a
- Complex Double
mforall a. Num a => a -> a -> a
*Complex Double
sine2) in
        Complex Double
sine forall a. Num a => a -> a -> a
* Double
-> Complex Double
-> Complex Double
-> Complex Double
-> Complex Double
carlsonRF' Double
err Complex Double
cosine2 Complex Double
oneminusmsine2 Complex Double
1
  | Bool
otherwise =
    let (Complex Double
phi', Int
k) = Complex Double -> (Complex Double, Int)
getPhiK Complex Double
phi in
    Complex Double
2 forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Num a => a -> a -> a
* Double -> Complex Double -> Complex Double -> Complex Double
ellipticF' Double
err (forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Complex Double
2) Complex Double
m forall a. Num a => a -> a -> a
+ Double -> Complex Double -> Complex Double -> Complex Double
ellipticF' Double
err Complex Double
phi' Complex Double
m

-- | Elliptic integral of the first kind.
ellipticF :: 
     Complex Double -- ^ amplitude
  -> Complex Double -- ^ parameter
  -> Complex Double
ellipticF :: Complex Double -> Complex Double -> Complex Double
ellipticF = Double -> Complex Double -> Complex Double -> Complex Double
ellipticF' Double
1e-15

-- | Elliptic integral of the second kind.
ellipticE' :: 
     Double -- ^ bound on the relative error passed to `carlsonRF'` and `carlsonRD'` 
  -> Complex Double -- ^ amplitude
  -> Complex Double -- ^ parameter
  -> Complex Double
ellipticE' :: Double -> Complex Double -> Complex Double -> Complex Double
ellipticE' Double
err Complex Double
phi Complex Double
m
  | Complex Double
phi forall a. Eq a => a -> a -> Bool
== Complex Double
0 =
    Double -> Complex Double
toCplx Double
0
  | forall a. Num a => a -> a
abs(forall a. Complex a -> a
realPart Complex Double
phi) forall a. Ord a => a -> a -> Bool
<= forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Double
2 =
    case Complex Double
m of
      Complex Double
0 -> Complex Double
phi
      Complex Double
1 -> forall a. Floating a => a -> a
sin Complex Double
phi
      Complex Double
_ ->
        let sine :: Complex Double
sine = forall a. Floating a => a -> a
sin Complex Double
phi in
        let sine2 :: Complex Double
sine2 = Complex Double
sineforall a. Num a => a -> a -> a
*Complex Double
sine in
        let (Complex Double
cosine2, Complex Double
oneminusmsine2) = (Complex Double
1 forall a. Num a => a -> a -> a
- Complex Double
sine2, Complex Double
1 forall a. Num a => a -> a -> a
- Complex Double
mforall a. Num a => a -> a -> a
*Complex Double
sine2) in
        Complex Double
sine forall a. Num a => a -> a -> a
* (Double
-> Complex Double
-> Complex Double
-> Complex Double
-> Complex Double
carlsonRF' Double
err Complex Double
cosine2 Complex Double
oneminusmsine2 Complex Double
1 forall a. Num a => a -> a -> a
-
          Complex Double
m forall a. Num a => a -> a -> a
* Complex Double
sine2 forall a. Fractional a => a -> a -> a
/ Complex Double
3 forall a. Num a => a -> a -> a
* Double
-> Complex Double
-> Complex Double
-> Complex Double
-> Complex Double
carlsonRD' Double
err Complex Double
cosine2 Complex Double
oneminusmsine2 Complex Double
1)
  | Bool
otherwise =
    let (Complex Double
phi', Int
k) = Complex Double -> (Complex Double, Int)
getPhiK Complex Double
phi in
    Complex Double
2 forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Num a => a -> a -> a
* Double -> Complex Double -> Complex Double -> Complex Double
ellipticE' Double
err (forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Complex Double
2) Complex Double
m forall a. Num a => a -> a -> a
+ Double -> Complex Double -> Complex Double -> Complex Double
ellipticE' Double
err Complex Double
phi' Complex Double
m

-- | Elliptic integral of the second kind.
ellipticE :: 
     Complex Double -- ^ amplitude
  -> Complex Double -- ^ parameter
  -> Complex Double
ellipticE :: Complex Double -> Complex Double -> Complex Double
ellipticE = Double -> Complex Double -> Complex Double -> Complex Double
ellipticE' Double
1e-15

-- | Elliptic integral of the third kind.
ellipticPI' :: 
     Double -- ^ bound on the relative error passed to `carlsonRF'` and `carlsonRJ'` 
  -> Complex Double -- ^ amplitude
  -> Complex Double -- ^ characteristic
  -> Complex Double -- ^ parameter
  -> Complex Double
ellipticPI' :: Double
-> Complex Double
-> Complex Double
-> Complex Double
-> Complex Double
ellipticPI' Double
err Complex Double
phi Complex Double
n Complex Double
m
  | Complex Double
phi forall a. Eq a => a -> a -> Bool
== Complex Double
0 =
    Double -> Complex Double
toCplx Double
0
  | Complex Double
phi forall a. Eq a => a -> a -> Bool
== forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Complex Double
2 Bool -> Bool -> Bool
&& Complex Double
n forall a. Eq a => a -> a -> Bool
== Complex Double
1 =
    Complex Double
0forall a. Fractional a => a -> a -> a
/Complex Double
0
  | Complex Double
phi forall a. Eq a => a -> a -> Bool
== forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Complex Double
2 Bool -> Bool -> Bool
&& Complex Double
m forall a. Eq a => a -> a -> Bool
== Complex Double
0 =
    forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Complex Double
2forall a. Fractional a => a -> a -> a
/forall a. Floating a => a -> a
sqrt(Complex Double
1forall a. Num a => a -> a -> a
-Complex Double
n)
  | Complex Double
phi forall a. Eq a => a -> a -> Bool
== forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Complex Double
2 Bool -> Bool -> Bool
&& Complex Double
m forall a. Eq a => a -> a -> Bool
== Complex Double
n =
    Double -> Complex Double -> Complex Double -> Complex Double
ellipticE' Double
err (forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Complex Double
2) Complex Double
m forall a. Fractional a => a -> a -> a
/ (Complex Double
1forall a. Num a => a -> a -> a
-Complex Double
m)
  | Complex Double
phi forall a. Eq a => a -> a -> Bool
== forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Complex Double
2 Bool -> Bool -> Bool
&& Complex Double
n forall a. Eq a => a -> a -> Bool
== Complex Double
0 =
    Double -> Complex Double -> Complex Double -> Complex Double
ellipticF' Double
err (forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Complex Double
2) Complex Double
m
  | forall a. Num a => a -> a
abs(forall a. Complex a -> a
realPart Complex Double
phi) forall a. Ord a => a -> a -> Bool
<= forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Double
2 =
    let sine :: Complex Double
sine = forall a. Floating a => a -> a
sin Complex Double
phi in
    let sine2 :: Complex Double
sine2 = Complex Double
sineforall a. Num a => a -> a -> a
*Complex Double
sine in
    let (Complex Double
cosine2, Complex Double
oneminusmsine2) = (Complex Double
1 forall a. Num a => a -> a -> a
- Complex Double
sine2, Complex Double
1 forall a. Num a => a -> a -> a
- Complex Double
mforall a. Num a => a -> a -> a
*Complex Double
sine2) in
    Complex Double
sine forall a. Num a => a -> a -> a
* (Double
-> Complex Double
-> Complex Double
-> Complex Double
-> Complex Double
carlsonRF' Double
err Complex Double
cosine2 Complex Double
oneminusmsine2 Complex Double
1 forall a. Num a => a -> a -> a
+
      Complex Double
n forall a. Num a => a -> a -> a
* Complex Double
sine2 forall a. Fractional a => a -> a -> a
/ Complex Double
3 forall a. Num a => a -> a -> a
* Double
-> Complex Double
-> Complex Double
-> Complex Double
-> Complex Double
-> Complex Double
carlsonRJ' Double
err Complex Double
cosine2 Complex Double
oneminusmsine2 Complex Double
1 (Complex Double
1forall a. Num a => a -> a -> a
-Complex Double
nforall a. Num a => a -> a -> a
*Complex Double
sine2))
  | Bool
otherwise =
    let (Complex Double
phi', Int
k) = Complex Double -> (Complex Double, Int)
getPhiK Complex Double
phi in
    Complex Double
2 forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Num a => a -> a -> a
* Double
-> Complex Double
-> Complex Double
-> Complex Double
-> Complex Double
ellipticPI' Double
err (forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Complex Double
2) Complex Double
n Complex Double
m forall a. Num a => a -> a -> a
+ Double
-> Complex Double
-> Complex Double
-> Complex Double
-> Complex Double
ellipticPI' Double
err Complex Double
phi' Complex Double
n Complex Double
m

-- | Elliptic integral of the third kind.
ellipticPI ::
     Complex Double -- ^ amplitude
  -> Complex Double -- ^ characteristic
  -> Complex Double -- ^ parameter
  -> Complex Double
ellipticPI :: Complex Double
-> Complex Double -> Complex Double -> Complex Double
ellipticPI = Double
-> Complex Double
-> Complex Double
-> Complex Double
-> Complex Double
ellipticPI' Double
1e-15

-- | Jacobi zeta function.
jacobiZeta' ::
     Double -- ^ bound on the relative error passed to `ellipticF'` and `ellipticE'` 
  -> Complex Double -- ^ amplitude
  -> Complex Double -- ^ parameter
  -> Complex Double
jacobiZeta' :: Double -> Complex Double -> Complex Double -> Complex Double
jacobiZeta' Double
err Complex Double
phi Complex Double
m =
  if Complex Double
m forall a. Eq a => a -> a -> Bool
== Complex Double
1
    then
      if forall a. Num a => a -> a
abs(forall a. Complex a -> a
realPart Complex Double
phi) forall a. Ord a => a -> a -> Bool
<= forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Double
2
        then forall a. Floating a => a -> a
sin Complex Double
phi
        else let (Complex Double
phi',Int
_) = Complex Double -> (Complex Double, Int)
getPhiK Complex Double
phi in forall a. Floating a => a -> a
sin Complex Double
phi'
    else
      Double -> Complex Double -> Complex Double -> Complex Double
ellipticE' Double
err Complex Double
phi Complex Double
m forall a. Num a => a -> a -> a
-
        Double -> Complex Double -> Complex Double -> Complex Double
ellipticE' Double
err (forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Complex Double
2) Complex Double
m forall a. Fractional a => a -> a -> a
/ Double -> Complex Double -> Complex Double -> Complex Double
ellipticF' Double
err (forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Complex Double
2) Complex Double
m forall a. Num a => a -> a -> a
*
        Double -> Complex Double -> Complex Double -> Complex Double
ellipticF' Double
err Complex Double
phi Complex Double
m

-- | Jacobi zeta function.
jacobiZeta ::
     Complex Double -- ^ amplitude
  -> Complex Double -- ^ parameter
  -> Complex Double
jacobiZeta :: Complex Double -> Complex Double -> Complex Double
jacobiZeta = Double -> Complex Double -> Complex Double -> Complex Double
jacobiZeta' Double
1e-15