algebraic-0.1.0.2: src/Math/Coordinate/Elliptic.hs
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Math.Coordinate.Elliptic where
import Data.Typeable (Typeable)
import Control.Applicative
import Data.Array.Accelerate
import Data.Array.Accelerate.Smart
import Data.Array.Accelerate.Tuple
import Data.Array.Accelerate.Array.Sugar
import Data.Complex
import qualified Data.Foldable as F
import Data.Complex
import qualified Math.Coordinate.Cartesian as Cartesian
import Math.Coordinate.Cartesian (Cartesian)
import Math.Coordinate.Coordinate (CoordConversion(..), ManualConversion(..), convertCoord)
import Math.Space.Space (Space2)
data Elliptic a = Elliptic !a deriving (Show)
data Point a = Point { a :: !a
, u :: !a
, v :: !a
} deriving (Eq, Ord, Show, Read, Typeable)
toElliptic = convertCoord . Elliptic
--------------------------------------------------------------------------------
-- Instances
--------------------------------------------------------------------------------
instance Floating a => CoordConversion ManualConversion Cartesian space (Point a) (Cartesian.Point2 a) where
convertCoordBase _ _ _ (Point a u v) = Cartesian.Point2 x y where
x = a * (cosh u * cos v)
y = a * (sinh u * sin v)
instance (Floating a, a~b) => CoordConversion ManualConversion (Elliptic b) space (Cartesian.Point2 a) (Point a) where
convertCoordBase _ (Elliptic a) _ (Cartesian.Point2 x y) = Point a u v
where u = acosh $ -sqrt(2)*x / (sqrt $ 1 + x**2 + y**2 - (sqrt $ 4*y**2+ (-1 + x**2 + y**2)**2))
v = acos $ -sqrt(1 + x**2 + y**2 - (sqrt $ 4*y**2 + (-1 + x**2 + y**2)**2)) / (sqrt 2)
--------------------------------------------------------------------------------
-- Point
--------------------------------------------------------------------------------
instance Functor Point where
fmap f (Point a b c) = Point (f a) (f b) (f c)
instance Applicative Point where
pure a = Point a a a
{-# INLINE pure #-}
Point a b c <*> Point d e f = Point (a d) (b e) (c f)
{-# INLINE (<*>) #-}
instance Num a => Num (Point a) where
(+) = liftA2 (+)
{-# INLINE (+) #-}
(-) = liftA2 (-)
{-# INLINE (-) #-}
(*) = liftA2 (*)
{-# INLINE (*) #-}
negate = fmap negate
{-# INLINE negate #-}
abs = fmap abs
{-# INLINE abs #-}
signum = fmap signum
{-# INLINE signum #-}
fromInteger = pure . fromInteger
{-# INLINE fromInteger #-}
instance Fractional a => Fractional (Point a) where
recip = fmap recip
{-# INLINE recip #-}
(/) = liftA2 (/)
{-# INLINE (/) #-}
fromRational = pure . fromRational
{-# INLINE fromRational #-}
type instance EltRepr (Point a) = EltRepr (a, a, a)
type instance EltRepr' (Point a) = EltRepr' (a, a, a)
instance Elt a => Elt (Point a) where
eltType _ = eltType (undefined :: (a,a,a))
toElt p = case toElt p of
(x, y, z) -> Point x y z
fromElt (Point x y z) = fromElt (x, y, z)
eltType' _ = eltType' (undefined :: (a,a,a))
toElt' p = case toElt' p of
(x, y, z) -> Point x y z
fromElt' (Point x y z) = fromElt' (x, y, z)
instance IsTuple (Point a) where
type TupleRepr (Point a) = TupleRepr (a,a,a)
fromTuple (Point x y z) = fromTuple (x,y,z)
toTuple t = case toTuple t of
(x, y, z) -> Point x y z
instance (Lift Exp a, Elt (Plain a)) => Lift Exp (Point a) where
type Plain (Point a) = Point (Plain a)
--lift = Exp . Tuple . F.foldl SnocTup NilTup
lift (Point x y z) = Exp $ Tuple $ NilTup `SnocTup` lift x `SnocTup` lift y `SnocTup` lift z
instance (Elt a, e ~ Exp a) => Unlift Exp (Point e) where
unlift t = Point (Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` t)
(Exp $ SuccTupIdx ZeroTupIdx `Prj` t)
(Exp $ ZeroTupIdx `Prj` t)