module Data.Manifold.Types.Primitive (
Real0, Real1, RealPlus, Real2, Real3
, Sphere0, Sphere1, Sphere2
, Projective1, Projective2
, Disk1, Disk2, Cone, OpenCone
, ZeroDim(..), isoAttachZeroDim
, ℝ⁰, ℝ, ℝ², ℝ³
, S⁰(..), otherHalfSphere, S¹(..), S²(..)
, ℝP¹, ℝP²(..)
, D¹(..), D²(..)
, ℝay
, CD¹(..), Cℝay(..)
, (⊗)(..)
, NaturallyEmbedded(..)
, GraphWindowSpec(..), Endomorphism, (^), (^.), EqFloating
, empty
) where
import Data.VectorSpace
import Data.AffineSpace
import Data.Basis
import Data.Complex hiding (magnitude)
import Data.Void
import Data.Monoid
import qualified Numeric.LinearAlgebra.HMatrix as HMat
import Control.Applicative (Const(..), Alternative(..))
import qualified Prelude
import Control.Category.Constrained.Prelude hiding ((^))
import Control.Arrow.Constrained
import Control.Monad.Constrained
import Data.Foldable.Constrained
import Data.Embedding
type EqFloating f = (Eq f, Ord f, Floating f)
data GraphWindowSpec = GraphWindowSpec {
lBound, rBound, bBound, tBound :: Double
, xResolution, yResolution :: Int
}
data ZeroDim k = Origin deriving(Eq, Show)
instance Monoid (ZeroDim k) where
mempty = Origin
mappend Origin Origin = Origin
instance AffineSpace (ZeroDim k) where
type Diff (ZeroDim k) = ZeroDim k
Origin .+^ Origin = Origin
Origin .-. Origin = Origin
instance AdditiveGroup (ZeroDim k) where
zeroV = Origin
Origin ^+^ Origin = Origin
negateV Origin = Origin
instance VectorSpace (ZeroDim k) where
type Scalar (ZeroDim k) = k
_ *^ Origin = Origin
instance HasBasis (ZeroDim k) where
type Basis (ZeroDim k) = Void
basisValue = absurd
decompose Origin = []
decompose' Origin = absurd
isoAttachZeroDim :: ( WellPointed c, UnitObject c ~ (), ObjectPair c a ()
, Object c (ZeroDim k), ObjectPair c a (ZeroDim k)
, PointObject c (ZeroDim k) )
=> Isomorphism c a (a, ZeroDim k)
isoAttachZeroDim = second (Isomorphism (const Origin) terminal) . attachUnit
data S⁰ = PositiveHalfSphere | NegativeHalfSphere deriving(Eq, Show)
otherHalfSphere :: S⁰ -> S⁰
otherHalfSphere PositiveHalfSphere = NegativeHalfSphere
otherHalfSphere NegativeHalfSphere = PositiveHalfSphere
newtype S¹ = S¹ { φParamS¹ :: Double
} deriving (Show)
data S² = S² { ϑParamS² :: !Double
, φParamS² :: !Double
} deriving (Show)
type ℝP¹ = S¹
data ℝP² = ℝP² { rParamℝP² :: !Double
, φParamℝP² :: !Double
} deriving (Show)
newtype D¹ = D¹ { xParamD¹ :: Double
}
data D² = D² { rParamD² :: !Double
, φParamD² :: !Double
} deriving (Show)
data CD¹ x = CD¹ { hParamCD¹ :: !Double
, pParamCD¹ :: !x
}
data Cℝay x = Cℝay { hParamCℝay :: !Double
, pParamCℝay :: !x
}
newtype x⊗y = DensTensProd { getDensTensProd :: HMat.Matrix (Scalar y) }
class NaturallyEmbedded m v where
embed :: m -> v
coEmbed :: v -> m
instance (VectorSpace y) => NaturallyEmbedded x (x,y) where
embed x = (x, zeroV)
coEmbed (x,_) = x
instance (VectorSpace y, VectorSpace z) => NaturallyEmbedded x ((x,y),z) where
embed x = (embed x, zeroV)
coEmbed (x,_) = coEmbed x
instance NaturallyEmbedded S⁰ ℝ where
embed PositiveHalfSphere = 1
embed NegativeHalfSphere = 1
coEmbed x | x>=0 = PositiveHalfSphere
| otherwise = NegativeHalfSphere
instance NaturallyEmbedded S¹ ℝ² where
embed (S¹ φ) = (cos φ, sin φ)
coEmbed (x,y) = S¹ $ atan2 y x
instance NaturallyEmbedded S² ℝ³ where
embed (S² ϑ φ) = ((cos φ * sin ϑ, sin φ * sin ϑ), cos ϑ)
coEmbed ((x,y),z) = S² (acos $ z/r) (atan2 y x)
where r = sqrt $ x^2 + y^2 + z^2
instance NaturallyEmbedded ℝP² ℝ³ where
embed (ℝP² r φ) = ((r * cos φ, r * sin φ), sqrt $ 1r^2)
coEmbed ((x,y),z) = ℝP² (sqrt $ 1(z/r)^2) (atan2 (y/r) (x/r))
where r = sqrt $ x^2 + y^2 + z^2
instance NaturallyEmbedded D¹ ℝ where
embed = xParamD¹
coEmbed = D¹ . max (1) . min 1
instance (NaturallyEmbedded x p) => NaturallyEmbedded (Cℝay x) (p,ℝ) where
embed (Cℝay h p) = (embed p, h)
coEmbed (v,z) = Cℝay (max 0 z) (coEmbed v)
type Endomorphism a = a->a
type ℝ⁰ = ZeroDim ℝ
type ℝ = Double
type ℝ² = (ℝ,ℝ)
type ℝ³ = (ℝ²,ℝ)
type ℝay = Cℝay ℝ⁰
type Real0 = ℝ⁰
type Real1 = ℝ
type RealPlus = ℝay
type Real2 = ℝ²
type Real3 = ℝ³
type Sphere0 = S⁰
type Sphere1 = S¹
type Sphere2 = S²
type Projective1 = ℝP¹
type Projective2 = ℝP²
type Disk1 = D¹
type Disk2 = D²
type Cone = CD¹
type OpenCone = Cℝay
instance VectorSpace () where
type Scalar () = ℝ
_ *^ () = ()
instance HasBasis () where
type Basis () = Void
basisValue = absurd
decompose () = []
decompose' () = absurd
instance InnerSpace () where
() <.> () = 0
infixr 8 ^
(^) :: Num a => a -> Int -> a
(^) = (Prelude.^)
infixl 8 ^.
(^.) :: s -> (forall f . Prelude.Functor f => (a->f a) -> s->f s) -> a
o ^. g = getConst (g Const o)