-- |
-- Module      : Math.Manifold.Real.Coordinates
-- Copyright   : (c) Justus Sagemüller 2018
-- License     : GPL v3
-- 
-- Maintainer  : (@) jsagemue $ uni-koeln.de
-- Stability   : experimental
-- Portability : portable
-- 

{-# LANGUAGE FlexibleInstances      #-}
{-# LANGUAGE FlexibleContexts       #-}
{-# LANGUAGE Rank2Types             #-}
{-# LANGUAGE GADTs                  #-}
{-# LANGUAGE TypeFamilies           #-}
{-# LANGUAGE UnicodeSyntax          #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE UndecidableInstances   #-}
{-# LANGUAGE EmptyCase              #-}
{-# LANGUAGE StandaloneDeriving     #-}
{-# LANGUAGE CPP                    #-}
{-# LANGUAGE ScopedTypeVariables    #-}



module Math.Manifold.Real.Coordinates
         ( Coordinate, coordinate
         , HasCoordinates(..)
         -- * Vector space axes
         , HasXCoord(..), HasYCoord(..), HasZCoord(..)
         -- * Fibre bundle / tangent space diffs
         , location's
         , CoordDifferential(..)
         -- * Spherical coordinates
         , HasAzimuth(..)
         , HasZenithDistance(..)
         ) where


import Data.Manifold.Types.Primitive
import Data.Manifold.Types.Stiefel
import Data.Manifold.PseudoAffine
import Math.LinearMap.Category
import Math.VectorSpace.Dual
import Data.VectorSpace

import Control.Lens hiding ((<.>))
import Data.List (intercalate, transpose)

import qualified Linear as Lin

import qualified Test.QuickCheck as QC
import qualified Test.QuickCheck.Gen as QC (unGen)
import qualified Test.QuickCheck.Random as QC (mkQCGen)
import Data.Maybe (fromJust, isJust)

import qualified Numeric.IEEE as IEEE

-- | To give a custom type coordinate axes, first define an instance of this class.
class HasCoordinates m where
  -- | A unique description of a coordinate axis.
  data CoordinateIdentifier m :: *
  -- | How to use a coordinate axis for points in the containing space.
  --   This is what 'coordinate' calls under the hood.
  coordinateAsLens :: CoordinateIdentifier m -> Lens' m 
  -- | Delimiters for the possible values one may choose for a given coordinate,
  --   around a point on the manifold.
  --   For example, in spherical coordinates, the 'azimuth' generally has a range
  --   of @(-'pi', 'pi')@, except at the poles where it's @(0,0)@.
  validCoordinateRange :: CoordinateIdentifier m -> m -> (,)
  validCoordinateRange CoordinateIdentifier m
_ m
_ = (-1ℝ -> ℝ -> ℝ
forall a. Fractional a => a -> a -> a
/0, 1ℝ -> ℝ -> ℝ
forall a. Fractional a => a -> a -> a
/0)

class CoordinateIsh q m | q -> m where
  useCoordinate :: CoordinateIdentifier m -> q

instance CoordinateIsh (CoordinateIdentifier m) m where
  useCoordinate :: CoordinateIdentifier m -> CoordinateIdentifier m
useCoordinate = CoordinateIdentifier m -> CoordinateIdentifier m
forall a. a -> a
id
instance (Functor f, HasCoordinates m, a ~ ( -> f ), b ~ (m -> f m))
          => CoordinateIsh (a -> b) m where
  useCoordinate :: CoordinateIdentifier m -> a -> b
useCoordinate = CoordinateIdentifier m -> a -> b
forall m. HasCoordinates m => CoordinateIdentifier m -> Lens' m ℝ
coordinateAsLens

coordinate :: CoordinateIdentifier m -> Coordinate m
coordinate :: CoordinateIdentifier m -> Coordinate m
coordinate = CoordinateIdentifier m -> q
forall q m. CoordinateIsh q m => CoordinateIdentifier m -> q
useCoordinate

-- | A coordinate is a function that can be used both to determine the position
-- of a point on a manifold along the one of some family of (possibly curved) axes on
-- which it lies, and for moving the point along that axis.
-- Basically, this is a 'Lens' and can indeed be used with the '^.', '.~' and '%~'
-- operators.
-- 
-- @
-- 'Coordinate' m ~ 'Lens'' m 'ℝ'
-- @
-- 
-- In addition, each type may also have a way of identifying particular coordinate
-- axes. This is done with 'CoordinateIdentifier', which is what should be used
-- for /defining/ given coordinate axes.
type Coordinate m =  q . CoordinateIsh q m => q

instance HasCoordinates ℝ⁰ where
  data CoordinateIdentifier ℝ⁰
  coordinateAsLens :: CoordinateIdentifier ℝ⁰ -> Lens' ℝ⁰ ℝ
coordinateAsLens CoordinateIdentifier ℝ⁰
b = case CoordinateIdentifier ℝ⁰
b of {}

instance HasCoordinates  where
  data CoordinateIdentifier  = RealCoord { CoordinateIdentifier ℝ -> ℝ
realAxisTfmStretch :: ! }
                      deriving (CoordinateIdentifier ℝ -> CoordinateIdentifier ℝ -> Bool
(CoordinateIdentifier ℝ -> CoordinateIdentifier ℝ -> Bool)
-> (CoordinateIdentifier ℝ -> CoordinateIdentifier ℝ -> Bool)
-> Eq (CoordinateIdentifier ℝ)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CoordinateIdentifier ℝ -> CoordinateIdentifier ℝ -> Bool
$c/= :: CoordinateIdentifier ℝ -> CoordinateIdentifier ℝ -> Bool
== :: CoordinateIdentifier ℝ -> CoordinateIdentifier ℝ -> Bool
$c== :: CoordinateIdentifier ℝ -> CoordinateIdentifier ℝ -> Bool
Eq,Int -> CoordinateIdentifier ℝ -> ShowS
[CoordinateIdentifier ℝ] -> ShowS
CoordinateIdentifier ℝ -> String
(Int -> CoordinateIdentifier ℝ -> ShowS)
-> (CoordinateIdentifier ℝ -> String)
-> ([CoordinateIdentifier ℝ] -> ShowS)
-> Show (CoordinateIdentifier ℝ)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CoordinateIdentifier ℝ] -> ShowS
$cshowList :: [CoordinateIdentifier ℝ] -> ShowS
show :: CoordinateIdentifier ℝ -> String
$cshow :: CoordinateIdentifier ℝ -> String
showsPrec :: Int -> CoordinateIdentifier ℝ -> ShowS
$cshowsPrec :: Int -> CoordinateIdentifier ℝ -> ShowS
Show)
  coordinateAsLens :: CoordinateIdentifier ℝ -> Lens' ℝ ℝ
coordinateAsLens (RealCoord μ) = (ℝ -> ℝ) -> (ℝ -> ℝ) -> Iso ℝ ℝ ℝ ℝ
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso (ℝ -> ℝ -> ℝ
forall a. Fractional a => a -> a -> a
/μ) (ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
*μ)
  {-# INLINE coordinateAsLens #-}

instance QC.Arbitrary (CoordinateIdentifier ) where
  arbitrary :: Gen (CoordinateIdentifier ℝ)
arbitrary = ℝ -> CoordinateIdentifier ℝ
RealCoord (ℝ -> CoordinateIdentifier ℝ)
-> (NonZero ℝ -> ℝ) -> NonZero ℝ -> CoordinateIdentifier ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonZero ℝ -> ℝ
forall a. NonZero a -> a
QC.getNonZero (NonZero ℝ -> CoordinateIdentifier ℝ)
-> Gen (NonZero ℝ) -> Gen (CoordinateIdentifier ℝ)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (NonZero ℝ)
forall a. Arbitrary a => Gen a
QC.arbitrary
  shrink :: CoordinateIdentifier ℝ -> [CoordinateIdentifier ℝ]
shrink (RealCoord μ) = [ ℝ -> CoordinateIdentifier ℝ
RealCoord ν | ν <- ℝ -> [ℝ]
forall a. Arbitrary a => a -> [a]
QC.shrink μ, νℝ -> ℝ -> Bool
forall a. Eq a => a -> a -> Bool
/=0 ]

data OriginAxisCoord v = OriginAxisCoord
       { OriginAxisCoord v -> v
coordHeading :: !v             -- ^ Must be conjugate to heading, i.e.
       , OriginAxisCoord v -> DualVector v
coordSensor :: !(DualVector v) -- ^ @'coordSensor' <.>^ 'coordHeading' = 1@.
       }
deriving instance (Show v, Show (DualVector v)) => Show (OriginAxisCoord v)
deriving instance (Eq v, Eq (DualVector v)) => Eq (OriginAxisCoord v)

originAxisCoordAsLens :: LinearSpace v => OriginAxisCoord v -> Lens' v (Scalar v)
originAxisCoordAsLens :: OriginAxisCoord v -> Lens' v (Scalar v)
originAxisCoordAsLens (OriginAxisCoord v
v DualVector v
dv)
     = (v -> Scalar v) -> (v -> Scalar v -> v) -> Lens' v (Scalar v)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens (DualVector v
dvDualVector v -> v -> Scalar v
forall v. LinearSpace v => DualVector v -> v -> Scalar v
<.>^)
            (\v
w Scalar v
c' -> v
w v -> v -> v
forall v. AdditiveGroup v => v -> v -> v
^+^ (Scalar v
c' Scalar v -> Scalar v -> Scalar v
forall a. Num a => a -> a -> a
- DualVector v
dvDualVector v -> v -> Scalar v
forall v. LinearSpace v => DualVector v -> v -> Scalar v
<.>^v
w)Scalar v -> v -> v
forall v. VectorSpace v => Scalar v -> v -> v
*^v
v)
{-# INLINE originAxisCoordAsLens #-}

instance (QC.Arbitrary v, InnerSpace v, v ~ DualVector v, Scalar v ~ )
    => QC.Arbitrary (OriginAxisCoord v) where
  arbitrary :: Gen (OriginAxisCoord v)
arbitrary = Gen v
forall a. Arbitrary a => Gen a
QC.arbitrary Gen v
-> (v -> Maybe (OriginAxisCoord v)) -> Gen (OriginAxisCoord v)
forall a b. Gen a -> (a -> Maybe b) -> Gen b
`suchThatMap` \v
v
   -> case v -> ℝ
forall v s. (InnerSpace v, s ~ Scalar v) => v -> s
magnitudeSq v
v of
       0 -> Maybe (OriginAxisCoord v)
forall a. Maybe a
Nothing
        -> OriginAxisCoord v -> Maybe (OriginAxisCoord v)
forall a. a -> Maybe a
Just (OriginAxisCoord v -> Maybe (OriginAxisCoord v))
-> OriginAxisCoord v -> Maybe (OriginAxisCoord v)
forall a b. (a -> b) -> a -> b
$ v -> DualVector v -> OriginAxisCoord v
forall v. v -> DualVector v -> OriginAxisCoord v
OriginAxisCoord v
v (v
vv -> ℝ -> v
forall v s.
(VectorSpace v, s ~ Scalar v, Fractional s) =>
v -> s -> v
^/)
  shrink :: OriginAxisCoord v -> [OriginAxisCoord v]
shrink (OriginAxisCoord v
v DualVector v
_) = [ v -> DualVector v -> OriginAxisCoord v
forall v. v -> DualVector v -> OriginAxisCoord v
OriginAxisCoord v
w (v
wv -> ℝ -> v
forall v s.
(VectorSpace v, s ~ Scalar v, Fractional s) =>
v -> s -> v
^/)
                                 | v
w <- v -> [v]
forall a. Arbitrary a => a -> [a]
QC.shrink v
v
                                 , let w² :: ℝ
 = v -> ℝ
forall v s. (InnerSpace v, s ~ Scalar v) => v -> s
magnitudeSq v
w
                                 ,  ℝ -> ℝ -> Bool
forall a. Ord a => a -> a -> Bool
> 0 ]

instance HasCoordinates ℝ² where
  data CoordinateIdentifier ℝ² = ℝ²Coord !(OriginAxisCoord ℝ²) deriving (CoordinateIdentifier ℝ² -> CoordinateIdentifier ℝ² -> Bool
(CoordinateIdentifier ℝ² -> CoordinateIdentifier ℝ² -> Bool)
-> (CoordinateIdentifier ℝ² -> CoordinateIdentifier ℝ² -> Bool)
-> Eq (CoordinateIdentifier ℝ²)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CoordinateIdentifier ℝ² -> CoordinateIdentifier ℝ² -> Bool
$c/= :: CoordinateIdentifier ℝ² -> CoordinateIdentifier ℝ² -> Bool
== :: CoordinateIdentifier ℝ² -> CoordinateIdentifier ℝ² -> Bool
$c== :: CoordinateIdentifier ℝ² -> CoordinateIdentifier ℝ² -> Bool
Eq,Int -> CoordinateIdentifier ℝ² -> ShowS
[CoordinateIdentifier ℝ²] -> ShowS
CoordinateIdentifier ℝ² -> String
(Int -> CoordinateIdentifier ℝ² -> ShowS)
-> (CoordinateIdentifier ℝ² -> String)
-> ([CoordinateIdentifier ℝ²] -> ShowS)
-> Show (CoordinateIdentifier ℝ²)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CoordinateIdentifier ℝ²] -> ShowS
$cshowList :: [CoordinateIdentifier ℝ²] -> ShowS
show :: CoordinateIdentifier ℝ² -> String
$cshow :: CoordinateIdentifier ℝ² -> String
showsPrec :: Int -> CoordinateIdentifier ℝ² -> ShowS
$cshowsPrec :: Int -> CoordinateIdentifier ℝ² -> ShowS
Show)
  coordinateAsLens :: CoordinateIdentifier ℝ² -> Lens' ℝ² ℝ
coordinateAsLens (ℝ²Coord b) = OriginAxisCoord ℝ² -> Lens' ℝ² (Scalar ℝ²)
forall v. LinearSpace v => OriginAxisCoord v -> Lens' v (Scalar v)
originAxisCoordAsLens OriginAxisCoord ℝ²
b
  {-# INLINE coordinateAsLens #-}

instance QC.Arbitrary ℝ² => QC.Arbitrary (CoordinateIdentifier ℝ²) where
  arbitrary :: Gen (CoordinateIdentifier ℝ²)
arbitrary = OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²
ℝ²Coord (OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²)
-> Gen (OriginAxisCoord ℝ²) -> Gen (CoordinateIdentifier ℝ²)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (OriginAxisCoord ℝ²)
forall a. Arbitrary a => Gen a
QC.arbitrary
  shrink :: CoordinateIdentifier ℝ² -> [CoordinateIdentifier ℝ²]
shrink (ℝ²Coord q) = OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²
ℝ²Coord (OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²)
-> [OriginAxisCoord ℝ²] -> [CoordinateIdentifier ℝ²]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> OriginAxisCoord ℝ² -> [OriginAxisCoord ℝ²]
forall a. Arbitrary a => a -> [a]
QC.shrink OriginAxisCoord ℝ²
q

instance HasCoordinates ℝ³ where
  data CoordinateIdentifier ℝ³ = ℝ³Coord !(OriginAxisCoord ℝ³) deriving (CoordinateIdentifier ℝ³ -> CoordinateIdentifier ℝ³ -> Bool
(CoordinateIdentifier ℝ³ -> CoordinateIdentifier ℝ³ -> Bool)
-> (CoordinateIdentifier ℝ³ -> CoordinateIdentifier ℝ³ -> Bool)
-> Eq (CoordinateIdentifier ℝ³)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CoordinateIdentifier ℝ³ -> CoordinateIdentifier ℝ³ -> Bool
$c/= :: CoordinateIdentifier ℝ³ -> CoordinateIdentifier ℝ³ -> Bool
== :: CoordinateIdentifier ℝ³ -> CoordinateIdentifier ℝ³ -> Bool
$c== :: CoordinateIdentifier ℝ³ -> CoordinateIdentifier ℝ³ -> Bool
Eq,Int -> CoordinateIdentifier ℝ³ -> ShowS
[CoordinateIdentifier ℝ³] -> ShowS
CoordinateIdentifier ℝ³ -> String
(Int -> CoordinateIdentifier ℝ³ -> ShowS)
-> (CoordinateIdentifier ℝ³ -> String)
-> ([CoordinateIdentifier ℝ³] -> ShowS)
-> Show (CoordinateIdentifier ℝ³)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CoordinateIdentifier ℝ³] -> ShowS
$cshowList :: [CoordinateIdentifier ℝ³] -> ShowS
show :: CoordinateIdentifier ℝ³ -> String
$cshow :: CoordinateIdentifier ℝ³ -> String
showsPrec :: Int -> CoordinateIdentifier ℝ³ -> ShowS
$cshowsPrec :: Int -> CoordinateIdentifier ℝ³ -> ShowS
Show)
  coordinateAsLens :: CoordinateIdentifier ℝ³ -> Lens' ℝ³ ℝ
coordinateAsLens (ℝ³Coord b) = OriginAxisCoord ℝ³ -> Lens' ℝ³ (Scalar ℝ³)
forall v. LinearSpace v => OriginAxisCoord v -> Lens' v (Scalar v)
originAxisCoordAsLens OriginAxisCoord ℝ³
b
  {-# INLINE coordinateAsLens #-}

instance QC.Arbitrary ℝ³ => QC.Arbitrary (CoordinateIdentifier ℝ³) where
  arbitrary :: Gen (CoordinateIdentifier ℝ³)
arbitrary = OriginAxisCoord ℝ³ -> CoordinateIdentifier ℝ³
ℝ³Coord (OriginAxisCoord ℝ³ -> CoordinateIdentifier ℝ³)
-> Gen (OriginAxisCoord ℝ³) -> Gen (CoordinateIdentifier ℝ³)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (OriginAxisCoord ℝ³)
forall a. Arbitrary a => Gen a
QC.arbitrary
  shrink :: CoordinateIdentifier ℝ³ -> [CoordinateIdentifier ℝ³]
shrink (ℝ³Coord q) = OriginAxisCoord ℝ³ -> CoordinateIdentifier ℝ³
ℝ³Coord (OriginAxisCoord ℝ³ -> CoordinateIdentifier ℝ³)
-> [OriginAxisCoord ℝ³] -> [CoordinateIdentifier ℝ³]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> OriginAxisCoord ℝ³ -> [OriginAxisCoord ℝ³]
forall a. Arbitrary a => a -> [a]
QC.shrink OriginAxisCoord ℝ³
q

instance (HasCoordinates a, HasCoordinates b) => HasCoordinates (a,b) where
  data CoordinateIdentifier (a,b) = LSubspaceCoord (CoordinateIdentifier a)
                                  | RSubspaceCoord (CoordinateIdentifier b)
  coordinateAsLens :: CoordinateIdentifier (a, b) -> Lens' (a, b) ℝ
coordinateAsLens (LSubspaceCoord ca) = (a -> f a) -> (a, b) -> f (a, b)
forall s t a b. Field1 s t a b => Lens s t a b
_1 ((a -> f a) -> (a, b) -> f (a, b))
-> ((ℝ -> f ℝ) -> a -> f a) -> (ℝ -> f ℝ) -> (a, b) -> f (a, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoordinateIdentifier a -> Lens' a ℝ
forall m. HasCoordinates m => CoordinateIdentifier m -> Lens' m ℝ
coordinateAsLens CoordinateIdentifier a
ca
  coordinateAsLens (RSubspaceCoord cb) = (b -> f b) -> (a, b) -> f (a, b)
forall s t a b. Field2 s t a b => Lens s t a b
_2 ((b -> f b) -> (a, b) -> f (a, b))
-> ((ℝ -> f ℝ) -> b -> f b) -> (ℝ -> f ℝ) -> (a, b) -> f (a, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoordinateIdentifier b -> Lens' b ℝ
forall m. HasCoordinates m => CoordinateIdentifier m -> Lens' m ℝ
coordinateAsLens CoordinateIdentifier b
cb
  {-# INLINE coordinateAsLens #-}

deriving instance (Eq (CoordinateIdentifier a), Eq (CoordinateIdentifier b))
            => Eq (CoordinateIdentifier (a,b))
deriving instance (Show (CoordinateIdentifier a), Show (CoordinateIdentifier b))
            => Show (CoordinateIdentifier (a,b))

instance (QC.Arbitrary (CoordinateIdentifier a), QC.Arbitrary (CoordinateIdentifier b))
    => QC.Arbitrary (CoordinateIdentifier (a,b)) where
  arbitrary :: Gen (CoordinateIdentifier (a, b))
arbitrary = [Gen (CoordinateIdentifier (a, b))]
-> Gen (CoordinateIdentifier (a, b))
forall a. [Gen a] -> Gen a
QC.oneof [CoordinateIdentifier a -> CoordinateIdentifier (a, b)
forall a b. CoordinateIdentifier a -> CoordinateIdentifier (a, b)
LSubspaceCoord(CoordinateIdentifier a -> CoordinateIdentifier (a, b))
-> Gen (CoordinateIdentifier a)
-> Gen (CoordinateIdentifier (a, b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Gen (CoordinateIdentifier a)
forall a. Arbitrary a => Gen a
QC.arbitrary, CoordinateIdentifier b -> CoordinateIdentifier (a, b)
forall a b. CoordinateIdentifier b -> CoordinateIdentifier (a, b)
RSubspaceCoord(CoordinateIdentifier b -> CoordinateIdentifier (a, b))
-> Gen (CoordinateIdentifier b)
-> Gen (CoordinateIdentifier (a, b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Gen (CoordinateIdentifier b)
forall a. Arbitrary a => Gen a
QC.arbitrary]
  shrink :: CoordinateIdentifier (a, b) -> [CoordinateIdentifier (a, b)]
shrink (LSubspaceCoord ba) = CoordinateIdentifier a -> CoordinateIdentifier (a, b)
forall a b. CoordinateIdentifier a -> CoordinateIdentifier (a, b)
LSubspaceCoord (CoordinateIdentifier a -> CoordinateIdentifier (a, b))
-> [CoordinateIdentifier a] -> [CoordinateIdentifier (a, b)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CoordinateIdentifier a -> [CoordinateIdentifier a]
forall a. Arbitrary a => a -> [a]
QC.shrink CoordinateIdentifier a
ba
  shrink (RSubspaceCoord bb) = CoordinateIdentifier b -> CoordinateIdentifier (a, b)
forall a b. CoordinateIdentifier b -> CoordinateIdentifier (a, b)
RSubspaceCoord (CoordinateIdentifier b -> CoordinateIdentifier (a, b))
-> [CoordinateIdentifier b] -> [CoordinateIdentifier (a, b)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CoordinateIdentifier b -> [CoordinateIdentifier b]
forall a. Arbitrary a => a -> [a]
QC.shrink CoordinateIdentifier b
bb

class HasCoordinates m => HasXCoord m where
  xCoord :: Coordinate m

instance HasXCoord  where
  xCoord :: q
xCoord = CoordinateIdentifier ℝ -> Coordinate ℝ
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (ℝ -> CoordinateIdentifier ℝ
RealCoord 1)
  {-# INLINE xCoord #-}
instance HasXCoord ℝ² where
  xCoord :: q
xCoord = CoordinateIdentifier ℝ² -> Coordinate ℝ²
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²
ℝ²Coord (OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²)
-> OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²
forall a b. (a -> b) -> a -> b
$ ℝ² -> DualVector ℝ² -> OriginAxisCoord ℝ²
forall v. v -> DualVector v -> OriginAxisCoord v
OriginAxisCoord (ℝ -> ℝ -> ℝ²
forall a. a -> a -> V2 a
Lin.V2 1 0) (ℝ -> ℝ -> ℝ²
forall a. a -> a -> V2 a
Lin.V2 1 0))
  {-# INLINE xCoord #-}
instance HasXCoord ℝ³ where
  xCoord :: q
xCoord = CoordinateIdentifier ℝ³ -> Coordinate ℝ³
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (OriginAxisCoord ℝ³ -> CoordinateIdentifier ℝ³
ℝ³Coord (OriginAxisCoord ℝ³ -> CoordinateIdentifier ℝ³)
-> OriginAxisCoord ℝ³ -> CoordinateIdentifier ℝ³
forall a b. (a -> b) -> a -> b
$ ℝ³ -> DualVector ℝ³ -> OriginAxisCoord ℝ³
forall v. v -> DualVector v -> OriginAxisCoord v
OriginAxisCoord (ℝ -> ℝ -> ℝ -> ℝ³
forall a. a -> a -> a -> V3 a
Lin.V3 1 0 0) (ℝ -> ℝ -> ℝ -> ℝ³
forall a. a -> a -> a -> V3 a
Lin.V3 1 0 0))
  {-# INLINE xCoord #-}
instance (HasXCoord v, HasCoordinates w) => HasXCoord (v,w) where
  xCoord :: q
xCoord = CoordinateIdentifier (v, w) -> Coordinate (v, w)
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (CoordinateIdentifier (v, w) -> Coordinate (v, w))
-> CoordinateIdentifier (v, w) -> Coordinate (v, w)
forall a b. (a -> b) -> a -> b
$ CoordinateIdentifier v -> CoordinateIdentifier (v, w)
forall a b. CoordinateIdentifier a -> CoordinateIdentifier (a, b)
LSubspaceCoord CoordinateIdentifier v
forall m. HasXCoord m => Coordinate m
xCoord

class HasYCoord m where
  yCoord :: Coordinate m

instance HasYCoord ℝ² where
  yCoord :: q
yCoord = CoordinateIdentifier ℝ² -> Coordinate ℝ²
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²
ℝ²Coord (OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²)
-> OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²
forall a b. (a -> b) -> a -> b
$ ℝ² -> DualVector ℝ² -> OriginAxisCoord ℝ²
forall v. v -> DualVector v -> OriginAxisCoord v
OriginAxisCoord (ℝ -> ℝ -> ℝ²
forall a. a -> a -> V2 a
Lin.V2 0 1) (ℝ -> ℝ -> ℝ²
forall a. a -> a -> V2 a
Lin.V2 0 1))
  {-# INLINE yCoord #-}
instance HasYCoord ℝ³ where
  yCoord :: q
yCoord = CoordinateIdentifier ℝ³ -> Coordinate ℝ³
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (OriginAxisCoord ℝ³ -> CoordinateIdentifier ℝ³
ℝ³Coord (OriginAxisCoord ℝ³ -> CoordinateIdentifier ℝ³)
-> OriginAxisCoord ℝ³ -> CoordinateIdentifier ℝ³
forall a b. (a -> b) -> a -> b
$ ℝ³ -> DualVector ℝ³ -> OriginAxisCoord ℝ³
forall v. v -> DualVector v -> OriginAxisCoord v
OriginAxisCoord (ℝ -> ℝ -> ℝ -> ℝ³
forall a. a -> a -> a -> V3 a
Lin.V3 0 1 0) (ℝ -> ℝ -> ℝ -> ℝ³
forall a. a -> a -> a -> V3 a
Lin.V3 0 1 0))
  {-# INLINE yCoord #-}
instance HasCoordinates w => HasYCoord ((,),w) where
  yCoord :: q
yCoord = CoordinateIdentifier ((ℝ, ℝ), w) -> Coordinate ((ℝ, ℝ), w)
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (CoordinateIdentifier ((ℝ, ℝ), w) -> Coordinate ((ℝ, ℝ), w))
-> CoordinateIdentifier ((ℝ, ℝ), w) -> Coordinate ((ℝ, ℝ), w)
forall a b. (a -> b) -> a -> b
$ CoordinateIdentifier (ℝ, ℝ) -> CoordinateIdentifier ((ℝ, ℝ), w)
forall a b. CoordinateIdentifier a -> CoordinateIdentifier (a, b)
LSubspaceCoord CoordinateIdentifier (ℝ, ℝ)
forall m. HasYCoord m => Coordinate m
yCoord
instance (HasXCoord w) => HasYCoord (,w) where
  yCoord :: q
yCoord = CoordinateIdentifier (ℝ, w) -> Coordinate (ℝ, w)
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (CoordinateIdentifier (ℝ, w) -> Coordinate (ℝ, w))
-> CoordinateIdentifier (ℝ, w) -> Coordinate (ℝ, w)
forall a b. (a -> b) -> a -> b
$ CoordinateIdentifier w -> CoordinateIdentifier (ℝ, w)
forall a b. CoordinateIdentifier b -> CoordinateIdentifier (a, b)
RSubspaceCoord CoordinateIdentifier w
forall m. HasXCoord m => Coordinate m
xCoord

class HasZCoord m where
  zCoord :: Coordinate m

instance HasZCoord ℝ³ where
  zCoord :: q
zCoord = CoordinateIdentifier ℝ³ -> Coordinate ℝ³
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (OriginAxisCoord ℝ³ -> CoordinateIdentifier ℝ³
ℝ³Coord (OriginAxisCoord ℝ³ -> CoordinateIdentifier ℝ³)
-> OriginAxisCoord ℝ³ -> CoordinateIdentifier ℝ³
forall a b. (a -> b) -> a -> b
$ ℝ³ -> DualVector ℝ³ -> OriginAxisCoord ℝ³
forall v. v -> DualVector v -> OriginAxisCoord v
OriginAxisCoord (ℝ -> ℝ -> ℝ -> ℝ³
forall a. a -> a -> a -> V3 a
Lin.V3 0 0 1) (ℝ -> ℝ -> ℝ -> ℝ³
forall a. a -> a -> a -> V3 a
Lin.V3 0 0 1))
  {-# INLINE zCoord #-}
instance HasXCoord w => HasZCoord ((,),w) where
  zCoord :: q
zCoord = CoordinateIdentifier ((ℝ, ℝ), w) -> Coordinate ((ℝ, ℝ), w)
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (CoordinateIdentifier ((ℝ, ℝ), w) -> Coordinate ((ℝ, ℝ), w))
-> CoordinateIdentifier ((ℝ, ℝ), w) -> Coordinate ((ℝ, ℝ), w)
forall a b. (a -> b) -> a -> b
$ CoordinateIdentifier w -> CoordinateIdentifier ((ℝ, ℝ), w)
forall a b. CoordinateIdentifier b -> CoordinateIdentifier (a, b)
RSubspaceCoord CoordinateIdentifier w
forall m. HasXCoord m => Coordinate m
xCoord
instance (HasYCoord w) => HasZCoord (,w) where
  zCoord :: q
zCoord = CoordinateIdentifier (ℝ, w) -> Coordinate (ℝ, w)
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (CoordinateIdentifier (ℝ, w) -> Coordinate (ℝ, w))
-> CoordinateIdentifier (ℝ, w) -> Coordinate (ℝ, w)
forall a b. (a -> b) -> a -> b
$ CoordinateIdentifier w -> CoordinateIdentifier (ℝ, w)
forall a b. CoordinateIdentifier b -> CoordinateIdentifier (a, b)
RSubspaceCoord CoordinateIdentifier w
forall m. HasYCoord m => Coordinate m
yCoord

instance (HasCoordinates b, HasCoordinates f)
              => HasCoordinates (FibreBundle b f) where
  data CoordinateIdentifier (FibreBundle b f)
           = BaseSpaceCoordinate (CoordinateIdentifier b)
           | FibreSpaceCoordinate (b -> CoordinateIdentifier f)
  coordinateAsLens :: CoordinateIdentifier (FibreBundle b f) -> Lens' (FibreBundle b f) ℝ
coordinateAsLens (BaseSpaceCoordinate b)
            = (FibreBundle b f -> b)
-> (FibreBundle b f -> b -> FibreBundle b f)
-> Lens (FibreBundle b f) (FibreBundle b f) b b
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens (\(FibreBundle b
p f
_) -> b
p)
                   (\(FibreBundle b
_ f
f) b
p -> b -> f -> FibreBundle b f
forall b f. b -> f -> FibreBundle b f
FibreBundle b
p f
f)
                ((b -> f b) -> FibreBundle b f -> f (FibreBundle b f))
-> ((ℝ -> f ℝ) -> b -> f b)
-> (ℝ -> f ℝ)
-> FibreBundle b f
-> f (FibreBundle b f)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoordinateIdentifier b -> Lens' b ℝ
forall m. HasCoordinates m => CoordinateIdentifier m -> Lens' m ℝ
coordinateAsLens CoordinateIdentifier b
b
  coordinateAsLens (FibreSpaceCoordinate b)
            = \ℝ -> f ℝ
φ pf :: FibreBundle b f
pf@(FibreBundle b
p f
f) -> case CoordinateIdentifier f -> Lens' f ℝ
forall m. HasCoordinates m => CoordinateIdentifier m -> Lens' m ℝ
coordinateAsLens (CoordinateIdentifier f -> Lens' f ℝ)
-> CoordinateIdentifier f -> Lens' f ℝ
forall a b. (a -> b) -> a -> b
$ b -> CoordinateIdentifier f
b b
p of
                 (ℝ -> f ℝ) -> f -> f f
fLens -> b -> f -> FibreBundle b f
forall b f. b -> f -> FibreBundle b f
FibreBundle b
p (f -> FibreBundle b f) -> f f -> f (FibreBundle b f)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ℝ -> f ℝ) -> f -> f f
fLens ℝ -> f ℝ
φ f
f
  validCoordinateRange :: CoordinateIdentifier (FibreBundle b f) -> FibreBundle b f -> (ℝ, ℝ)
validCoordinateRange (BaseSpaceCoordinate b) (FibreBundle b
p f
_) = CoordinateIdentifier b -> b -> (ℝ, ℝ)
forall m. HasCoordinates m => CoordinateIdentifier m -> m -> (ℝ, ℝ)
validCoordinateRange CoordinateIdentifier b
b b
p
  validCoordinateRange (FibreSpaceCoordinate bf) (FibreBundle b
p f
f)
                          = CoordinateIdentifier f -> f -> (ℝ, ℝ)
forall m. HasCoordinates m => CoordinateIdentifier m -> m -> (ℝ, ℝ)
validCoordinateRange (b -> CoordinateIdentifier f
bf b
p) f
f
  
instance  b f . ( Show (CoordinateIdentifier b)
                 , Show (CoordinateIdentifier f)
                 , Eq b, Eq (CoordinateIdentifier f)
                 , QC.Arbitrary b, Show b )
    => Show (CoordinateIdentifier (FibreBundle b f)) where
  showsPrec :: Int -> CoordinateIdentifier (FibreBundle b f) -> ShowS
showsPrec Int
p (BaseSpaceCoordinate b)
      = Bool -> ShowS -> ShowS
showParen (Int
pInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
9) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ (String
"BaseSpaceCoordinate "String -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> CoordinateIdentifier b -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
10 CoordinateIdentifier b
b
  showsPrec Int
p (FibreSpaceCoordinate bf)
      = Bool -> ShowS -> ShowS
showParen (Int
pInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
0) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ \String
cont ->
          String
"BaseSpaceCoordinate $ \\case {"
          String -> ShowS
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"; " [ Int -> b -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
5 b
p ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
" -> "String -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoordinateIdentifier f -> ShowS
forall a. Show a => a -> ShowS
shows (b -> CoordinateIdentifier f
bf b
p) ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ String
""
                              | b
p <- [b]
exampleArgs ]
          String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"... }" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
cont
   where exampleArgs :: [b]
         exampleArgs :: [b]
exampleArgs = [[b]] -> [b]
forall a. [a] -> a
head ([[b]] -> [b]) -> [[b]] -> [b]
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> [[b]]
go Int
1 Int
0 Int
2384148716156
          where go :: Int -> Int -> Int -> [[b]]
                go :: Int -> Int -> Int -> [[b]]
go Int
n Int
tries Int
seed
                  | [b] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [b]
candidate Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
n, [b] -> Bool
forall a. Eq a => [a] -> Bool
allDifferent [b]
candidate
                  , ([b]
shrunk:[[b]]
_) <- ([b] -> Bool) -> [[b]] -> [[b]]
forall a. (a -> Bool) -> [a] -> [a]
filter ([CoordinateIdentifier f] -> Bool
forall a. Eq a => [a] -> Bool
allDifferent ([CoordinateIdentifier f] -> Bool)
-> ([b] -> [CoordinateIdentifier f]) -> [b] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b -> CoordinateIdentifier f) -> [b] -> [CoordinateIdentifier f]
forall a b. (a -> b) -> [a] -> [b]
map b -> CoordinateIdentifier f
bf)
                                     ([[b]] -> [[b]]) -> [[b]] -> [[b]]
forall a b. (a -> b) -> a -> b
$ [b] -> [[b]]
forall a. Arbitrary a => [a] -> [[a]]
shrinkElems [b]
candidate [[b]] -> [[b]] -> [[b]]
forall a. [a] -> [a] -> [a]
++ [[b]
candidate]
                  , [] <- Int -> [[b]] -> [[b]]
forall a. Int -> [a] -> [a]
take (Int
5Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
n) ([[b]] -> [[b]]) -> [[b]] -> [[b]]
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> [[b]]
go (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Int
0 Int
seed'
                                      = [[b]
shrunk]
                  | Int
triesInt -> Int -> Int
forall a. Num a => a -> a -> a
*(Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
15  = []
                  | Bool
otherwise         = Int -> Int -> Int -> [[b]]
go Int
n (Int
triesInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Int
seed'
                 where candidate :: [b]
candidate = Int -> [b] -> [b]
forall a. Int -> [a] -> [a]
take Int
n ([b] -> [b]) -> [b] -> [b]
forall a b. (a -> b) -> a -> b
$ Int -> Gen [b] -> [b]
forall s a. CoArbitrary s => s -> Gen a -> a
generateFrom Int
seed Gen [b]
forall a. Arbitrary a => Gen a
QC.arbitrary
                       seed' :: Int
seed' = Int -> Gen Int -> Int
forall s a. CoArbitrary s => s -> Gen a -> a
generateFrom Int
seed Gen Int
forall a. Arbitrary a => Gen a
QC.arbitrary
         allDifferent :: [a] -> Bool
allDifferent (a
x:[a]
ys) = (a -> Bool) -> [a] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (a
xa -> a -> Bool
forall a. Eq a => a -> a -> Bool
/=) [a]
ys Bool -> Bool -> Bool
&& [a] -> Bool
allDifferent [a]
ys
         allDifferent [] = Bool
True

generateFrom :: QC.CoArbitrary s => s -> QC.Gen a -> a
generateFrom :: s -> Gen a -> a
generateFrom s
seed Gen a
val = Gen a -> QCGen -> Int -> a
forall a. Gen a -> QCGen -> Int -> a
QC.unGen (s -> Gen a -> Gen a
forall a b. CoArbitrary a => a -> Gen b -> Gen b
QC.coarbitrary s
seed Gen a
val) (Int -> QCGen
QC.mkQCGen Int
256592) Int
110818

-- | Keep length of the list, but shrink the individual elements.
shrinkElems :: QC.Arbitrary a => [a] -> [[a]]
shrinkElems :: [a] -> [[a]]
shrinkElems [a]
l = ([a] -> Bool) -> [[a]] -> [[a]]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==[a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
l) (Int -> Bool) -> ([a] -> Int) -> [a] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length) ([[a]] -> [[a]]) -> ([[a]] -> [[a]]) -> [[a]] -> [[a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[a]] -> [[a]]
forall a. [[a]] -> [[a]]
transpose ([[a]] -> [[a]]) -> [[a]] -> [[a]]
forall a b. (a -> b) -> a -> b
$ (a -> [a]) -> [a] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map a -> [a]
forall a. Arbitrary a => a -> [a]
QC.shrink [a]
l


location's :: (HasCoordinates b, HasCoordinates f)
                => CoordinateIdentifier b -> Coordinate (FibreBundle b f)
location's :: CoordinateIdentifier b -> Coordinate (FibreBundle b f)
location's = CoordinateIdentifier (FibreBundle b f) -> q
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (CoordinateIdentifier (FibreBundle b f) -> q)
-> (CoordinateIdentifier b
    -> CoordinateIdentifier (FibreBundle b f))
-> CoordinateIdentifier b
-> q
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoordinateIdentifier b -> CoordinateIdentifier (FibreBundle b f)
forall b f.
CoordinateIdentifier b -> CoordinateIdentifier (FibreBundle b f)
BaseSpaceCoordinate

class HasCoordinates m => CoordDifferential m where
  -- | Observe local, small variations (in the tangent space) of a coordinate.
  --   The idea is that @((p & coord+~δc) − p) ^. delta coord ≈ δc@, thus the name
  --   “'delta'”. Note however that this only holds exactly for flat spaces;
  --   in most manifolds it can (by design) only be understood in an asymptotic
  --   sense, i.e. used for evaluating directional derivatives of some function.
  --   In particular, @delta 'azimuth'@ is unstable near the poles of a sphere,
  --   because it has to compensate for the sensitive rotation of the @eφ@ unit vector.
  delta :: CoordinateIdentifier m -> Coordinate (TangentBundle m)

instance ( CoordDifferential m, f ~ Needle m
         , QC.Arbitrary m
         , QC.Arbitrary (CoordinateIdentifier m)
         , QC.Arbitrary (CoordinateIdentifier f) )
             => QC.Arbitrary (CoordinateIdentifier (FibreBundle m f)) where
  arbitrary :: Gen (CoordinateIdentifier (FibreBundle m f))
arbitrary = [Gen (CoordinateIdentifier (FibreBundle m f))]
-> Gen (CoordinateIdentifier (FibreBundle m f))
forall a. [Gen a] -> Gen a
QC.oneof [ CoordinateIdentifier m -> CoordinateIdentifier (FibreBundle m f)
forall b f.
CoordinateIdentifier b -> CoordinateIdentifier (FibreBundle b f)
BaseSpaceCoordinate (CoordinateIdentifier m -> CoordinateIdentifier (FibreBundle m f))
-> Gen (CoordinateIdentifier m)
-> Gen (CoordinateIdentifier (FibreBundle m f))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (CoordinateIdentifier m)
forall a. Arbitrary a => Gen a
QC.arbitrary
                       , CoordinateIdentifier m -> CoordinateIdentifier (FibreBundle m f)
forall m.
CoordDifferential m =>
CoordinateIdentifier m -> Coordinate (TangentBundle m)
delta (CoordinateIdentifier m -> CoordinateIdentifier (FibreBundle m f))
-> Gen (CoordinateIdentifier m)
-> Gen (CoordinateIdentifier (FibreBundle m f))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (CoordinateIdentifier m)
forall a. Arbitrary a => Gen a
QC.arbitrary ]
  shrink :: CoordinateIdentifier (FibreBundle m f)
-> [CoordinateIdentifier (FibreBundle m f)]
shrink (BaseSpaceCoordinate b) = CoordinateIdentifier m -> CoordinateIdentifier (FibreBundle m f)
forall b f.
CoordinateIdentifier b -> CoordinateIdentifier (FibreBundle b f)
BaseSpaceCoordinate (CoordinateIdentifier m -> CoordinateIdentifier (FibreBundle m f))
-> [CoordinateIdentifier m]
-> [CoordinateIdentifier (FibreBundle m f)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CoordinateIdentifier m -> [CoordinateIdentifier m]
forall a. Arbitrary a => a -> [a]
QC.shrink CoordinateIdentifier m
b
  shrink (FibreSpaceCoordinate bf) = (m -> CoordinateIdentifier f)
-> CoordinateIdentifier (FibreBundle m f)
forall b f.
(b -> CoordinateIdentifier f)
-> CoordinateIdentifier (FibreBundle b f)
FibreSpaceCoordinate ((m -> CoordinateIdentifier f)
 -> CoordinateIdentifier (FibreBundle m f))
-> (CoordinateIdentifier f -> m -> CoordinateIdentifier f)
-> CoordinateIdentifier f
-> CoordinateIdentifier (FibreBundle m f)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoordinateIdentifier f -> m -> CoordinateIdentifier f
forall a b. a -> b -> a
const
                     (CoordinateIdentifier f -> CoordinateIdentifier (FibreBundle m f))
-> [CoordinateIdentifier f]
-> [CoordinateIdentifier (FibreBundle m f)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CoordinateIdentifier f -> [CoordinateIdentifier f]
forall a. Arbitrary a => a -> [a]
QC.shrink (m -> CoordinateIdentifier f
bf m
cRef)
   where cRef₀ :: m
cRef₀ = Gen m -> QCGen -> Int -> m
forall a. Gen a -> QCGen -> Int -> a
QC.unGen Gen m
forall a. Arbitrary a => Gen a
QC.arbitrary (Int -> QCGen
QC.mkQCGen Int
534373) Int
57314
         cRef :: m
cRef = [m] -> m
forall a. [a] -> a
head ([m] -> m) -> [m] -> m
forall a b. (a -> b) -> a -> b
$ m -> [m]
forall a. Arbitrary a => a -> [a]
QC.shrink m
cRef₀ [m] -> [m] -> [m]
forall a. [a] -> [a] -> [a]
++ [m
cRef₀]

instance CoordDifferential  where
  delta :: CoordinateIdentifier ℝ -> Coordinate (TangentBundle ℝ)
delta CoordinateIdentifier ℝ
ζ = CoordinateIdentifier (FibreBundle ℝ ℝ) -> q
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (CoordinateIdentifier (FibreBundle ℝ ℝ) -> q)
-> ((ℝ -> CoordinateIdentifier ℝ)
    -> CoordinateIdentifier (FibreBundle ℝ ℝ))
-> (ℝ -> CoordinateIdentifier ℝ)
-> q
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ℝ -> CoordinateIdentifier ℝ)
-> CoordinateIdentifier (FibreBundle ℝ ℝ)
forall b f.
(b -> CoordinateIdentifier f)
-> CoordinateIdentifier (FibreBundle b f)
FibreSpaceCoordinate ((ℝ -> CoordinateIdentifier ℝ) -> q)
-> (ℝ -> CoordinateIdentifier ℝ) -> q
forall a b. (a -> b) -> a -> b
$ CoordinateIdentifier ℝ -> ℝ -> CoordinateIdentifier ℝ
forall a b. a -> b -> a
const CoordinateIdentifier ℝ
ζ
instance CoordDifferential ℝ² where
  delta :: CoordinateIdentifier ℝ² -> Coordinate (TangentBundle ℝ²)
delta CoordinateIdentifier ℝ²
ζ = CoordinateIdentifier (FibreBundle ℝ² ℝ²) -> q
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (CoordinateIdentifier (FibreBundle ℝ² ℝ²) -> q)
-> ((ℝ² -> CoordinateIdentifier ℝ²)
    -> CoordinateIdentifier (FibreBundle ℝ² ℝ²))
-> (ℝ² -> CoordinateIdentifier ℝ²)
-> q
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ℝ² -> CoordinateIdentifier ℝ²)
-> CoordinateIdentifier (FibreBundle ℝ² ℝ²)
forall b f.
(b -> CoordinateIdentifier f)
-> CoordinateIdentifier (FibreBundle b f)
FibreSpaceCoordinate ((ℝ² -> CoordinateIdentifier ℝ²) -> q)
-> (ℝ² -> CoordinateIdentifier ℝ²) -> q
forall a b. (a -> b) -> a -> b
$ CoordinateIdentifier ℝ² -> ℝ² -> CoordinateIdentifier ℝ²
forall a b. a -> b -> a
const CoordinateIdentifier ℝ²
ζ
instance CoordDifferential ℝ³ where
  delta :: CoordinateIdentifier ℝ³ -> Coordinate (TangentBundle ℝ³)
delta CoordinateIdentifier ℝ³
ζ = CoordinateIdentifier (FibreBundle ℝ³ ℝ³) -> q
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (CoordinateIdentifier (FibreBundle ℝ³ ℝ³) -> q)
-> ((ℝ³ -> CoordinateIdentifier ℝ³)
    -> CoordinateIdentifier (FibreBundle ℝ³ ℝ³))
-> (ℝ³ -> CoordinateIdentifier ℝ³)
-> q
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ℝ³ -> CoordinateIdentifier ℝ³)
-> CoordinateIdentifier (FibreBundle ℝ³ ℝ³)
forall b f.
(b -> CoordinateIdentifier f)
-> CoordinateIdentifier (FibreBundle b f)
FibreSpaceCoordinate ((ℝ³ -> CoordinateIdentifier ℝ³) -> q)
-> (ℝ³ -> CoordinateIdentifier ℝ³) -> q
forall a b. (a -> b) -> a -> b
$ CoordinateIdentifier ℝ³ -> ℝ³ -> CoordinateIdentifier ℝ³
forall a b. a -> b -> a
const CoordinateIdentifier ℝ³
ζ

instance (CoordDifferential a, CoordDifferential b) => CoordDifferential (a,b) where
  delta :: CoordinateIdentifier (a, b) -> Coordinate (TangentBundle (a, b))
delta (LSubspaceCoord ba) = CoordinateIdentifier (FibreBundle (a, b) (Needle a, Needle b))
-> Coordinate (FibreBundle (a, b) (Needle a, Needle b))
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (CoordinateIdentifier (FibreBundle (a, b) (Needle a, Needle b))
 -> Coordinate (FibreBundle (a, b) (Needle a, Needle b)))
-> CoordinateIdentifier (FibreBundle (a, b) (Needle a, Needle b))
-> Coordinate (FibreBundle (a, b) (Needle a, Needle b))
forall a b. (a -> b) -> a -> b
$ case CoordinateIdentifier a -> Coordinate (FibreBundle a (Needle a))
forall m.
CoordDifferential m =>
CoordinateIdentifier m -> Coordinate (TangentBundle m)
delta CoordinateIdentifier a
ba of
     FibreSpaceCoordinate bf -> ((a, b) -> CoordinateIdentifier (Needle a, Needle b))
-> CoordinateIdentifier (FibreBundle (a, b) (Needle a, Needle b))
forall b f.
(b -> CoordinateIdentifier f)
-> CoordinateIdentifier (FibreBundle b f)
FibreSpaceCoordinate (((a, b) -> CoordinateIdentifier (Needle a, Needle b))
 -> CoordinateIdentifier (FibreBundle (a, b) (Needle a, Needle b)))
-> ((a, b) -> CoordinateIdentifier (Needle a, Needle b))
-> CoordinateIdentifier (FibreBundle (a, b) (Needle a, Needle b))
forall a b. (a -> b) -> a -> b
$ \(a
δa,b
_) -> CoordinateIdentifier (Needle a)
-> CoordinateIdentifier (Needle a, Needle b)
forall a b. CoordinateIdentifier a -> CoordinateIdentifier (a, b)
LSubspaceCoord (CoordinateIdentifier (Needle a)
 -> CoordinateIdentifier (Needle a, Needle b))
-> CoordinateIdentifier (Needle a)
-> CoordinateIdentifier (Needle a, Needle b)
forall a b. (a -> b) -> a -> b
$ a -> CoordinateIdentifier (Needle a)
bf a
δa
  delta (RSubspaceCoord bb) = CoordinateIdentifier (FibreBundle (a, b) (Needle a, Needle b))
-> Coordinate (FibreBundle (a, b) (Needle a, Needle b))
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (CoordinateIdentifier (FibreBundle (a, b) (Needle a, Needle b))
 -> Coordinate (FibreBundle (a, b) (Needle a, Needle b)))
-> CoordinateIdentifier (FibreBundle (a, b) (Needle a, Needle b))
-> Coordinate (FibreBundle (a, b) (Needle a, Needle b))
forall a b. (a -> b) -> a -> b
$ case CoordinateIdentifier b -> Coordinate (FibreBundle b (Needle b))
forall m.
CoordDifferential m =>
CoordinateIdentifier m -> Coordinate (TangentBundle m)
delta CoordinateIdentifier b
bb of
     FibreSpaceCoordinate bf -> ((a, b) -> CoordinateIdentifier (Needle a, Needle b))
-> CoordinateIdentifier (FibreBundle (a, b) (Needle a, Needle b))
forall b f.
(b -> CoordinateIdentifier f)
-> CoordinateIdentifier (FibreBundle b f)
FibreSpaceCoordinate (((a, b) -> CoordinateIdentifier (Needle a, Needle b))
 -> CoordinateIdentifier (FibreBundle (a, b) (Needle a, Needle b)))
-> ((a, b) -> CoordinateIdentifier (Needle a, Needle b))
-> CoordinateIdentifier (FibreBundle (a, b) (Needle a, Needle b))
forall a b. (a -> b) -> a -> b
$ \(a
_,b
δb) -> CoordinateIdentifier (Needle b)
-> CoordinateIdentifier (Needle a, Needle b)
forall a b. CoordinateIdentifier b -> CoordinateIdentifier (a, b)
RSubspaceCoord (CoordinateIdentifier (Needle b)
 -> CoordinateIdentifier (Needle a, Needle b))
-> CoordinateIdentifier (Needle b)
-> CoordinateIdentifier (Needle a, Needle b)
forall a b. (a -> b) -> a -> b
$ b -> CoordinateIdentifier (Needle b)
bf b
δb

instance HasCoordinates  where
  data CoordinateIdentifier  = S¹Azimuth deriving (CoordinateIdentifier S¹ -> CoordinateIdentifier S¹ -> Bool
(CoordinateIdentifier S¹ -> CoordinateIdentifier S¹ -> Bool)
-> (CoordinateIdentifier S¹ -> CoordinateIdentifier S¹ -> Bool)
-> Eq (CoordinateIdentifier S¹)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CoordinateIdentifier S¹ -> CoordinateIdentifier S¹ -> Bool
$c/= :: CoordinateIdentifier S¹ -> CoordinateIdentifier S¹ -> Bool
== :: CoordinateIdentifier S¹ -> CoordinateIdentifier S¹ -> Bool
$c== :: CoordinateIdentifier S¹ -> CoordinateIdentifier S¹ -> Bool
Eq,Int -> CoordinateIdentifier S¹ -> ShowS
[CoordinateIdentifier S¹] -> ShowS
CoordinateIdentifier S¹ -> String
(Int -> CoordinateIdentifier S¹ -> ShowS)
-> (CoordinateIdentifier S¹ -> String)
-> ([CoordinateIdentifier S¹] -> ShowS)
-> Show (CoordinateIdentifier S¹)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CoordinateIdentifier S¹] -> ShowS
$cshowList :: [CoordinateIdentifier S¹] -> ShowS
show :: CoordinateIdentifier S¹ -> String
$cshow :: CoordinateIdentifier S¹ -> String
showsPrec :: Int -> CoordinateIdentifier S¹ -> ShowS
$cshowsPrec :: Int -> CoordinateIdentifier S¹ -> ShowS
Show)
  coordinateAsLens :: CoordinateIdentifier S¹ -> Lens' S¹ ℝ
coordinateAsLens CoordinateIdentifier S¹
S¹Azimuth = (S¹ -> ℝ) -> (S¹ -> ℝ -> S¹) -> Lens' S¹ ℝ
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens S¹ -> ℝ
forall r. S¹_ r -> r
φParamS¹ ((ℝ -> S¹) -> S¹ -> ℝ -> S¹
forall a b. a -> b -> a
const ℝ -> S¹
forall r. r -> S¹_ r
S¹Polar)
  validCoordinateRange :: CoordinateIdentifier S¹ -> S¹ -> (ℝ, ℝ)
validCoordinateRange CoordinateIdentifier S¹
S¹Azimuth _ = (-ℝ
forall a. Floating a => a
pi, ℝ
forall a. Floating a => a
pi)

instance QC.Arbitrary (CoordinateIdentifier ) where
  arbitrary :: Gen (CoordinateIdentifier S¹)
arbitrary = CoordinateIdentifier S¹ -> Gen (CoordinateIdentifier S¹)
forall (m :: * -> *) a. Monad m => a -> m a
return CoordinateIdentifier S¹
S¹Azimuth

class HasAzimuth m where
  azimuth :: Coordinate m

instance HasAzimuth  where
  azimuth :: q
azimuth = CoordinateIdentifier S¹ -> Coordinate S¹
forall m. CoordinateIdentifier m -> Coordinate m
coordinate CoordinateIdentifier S¹
S¹Azimuth

instance CoordDifferential  where
  delta :: CoordinateIdentifier S¹ -> Coordinate (TangentBundle S¹)
delta CoordinateIdentifier S¹
S¹Azimuth = CoordinateIdentifier (FibreBundle S¹ ℝ) -> q
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (CoordinateIdentifier (FibreBundle S¹ ℝ) -> q)
-> ((S¹ -> CoordinateIdentifier ℝ)
    -> CoordinateIdentifier (FibreBundle S¹ ℝ))
-> (S¹ -> CoordinateIdentifier ℝ)
-> q
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (S¹ -> CoordinateIdentifier ℝ)
-> CoordinateIdentifier (FibreBundle S¹ ℝ)
forall b f.
(b -> CoordinateIdentifier f)
-> CoordinateIdentifier (FibreBundle b f)
FibreSpaceCoordinate ((S¹ -> CoordinateIdentifier ℝ) -> q)
-> (S¹ -> CoordinateIdentifier ℝ) -> q
forall a b. (a -> b) -> a -> b
$ CoordinateIdentifier ℝ -> S¹ -> CoordinateIdentifier ℝ
forall a b. a -> b -> a
const CoordinateIdentifier ℝ
forall m. HasXCoord m => Coordinate m
xCoord
  
instance HasCoordinates  where
  data CoordinateIdentifier  = S²ZenithAngle | S²Azimuth deriving (CoordinateIdentifier S² -> CoordinateIdentifier S² -> Bool
(CoordinateIdentifier S² -> CoordinateIdentifier S² -> Bool)
-> (CoordinateIdentifier S² -> CoordinateIdentifier S² -> Bool)
-> Eq (CoordinateIdentifier S²)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CoordinateIdentifier S² -> CoordinateIdentifier S² -> Bool
$c/= :: CoordinateIdentifier S² -> CoordinateIdentifier S² -> Bool
== :: CoordinateIdentifier S² -> CoordinateIdentifier S² -> Bool
$c== :: CoordinateIdentifier S² -> CoordinateIdentifier S² -> Bool
Eq,Int -> CoordinateIdentifier S² -> ShowS
[CoordinateIdentifier S²] -> ShowS
CoordinateIdentifier S² -> String
(Int -> CoordinateIdentifier S² -> ShowS)
-> (CoordinateIdentifier S² -> String)
-> ([CoordinateIdentifier S²] -> ShowS)
-> Show (CoordinateIdentifier S²)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CoordinateIdentifier S²] -> ShowS
$cshowList :: [CoordinateIdentifier S²] -> ShowS
show :: CoordinateIdentifier S² -> String
$cshow :: CoordinateIdentifier S² -> String
showsPrec :: Int -> CoordinateIdentifier S² -> ShowS
$cshowsPrec :: Int -> CoordinateIdentifier S² -> ShowS
Show)
  coordinateAsLens :: CoordinateIdentifier S² -> Lens' S² ℝ
coordinateAsLens CoordinateIdentifier S²
S²ZenithAngle = (S² -> ℝ) -> (S² -> ℝ -> S²) -> Lens' S² ℝ
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens S² -> ℝ
forall r. S²_ r -> r
ϑParamS² (\(S²Polar _ φ) θ -> ℝ -> ℝ -> S²
forall r. r -> r -> S²_ r
S²Polar θ φ)
  coordinateAsLens CoordinateIdentifier S²
S²Azimuth = (S² -> ℝ) -> (S² -> ℝ -> S²) -> Lens' S² ℝ
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens S² -> ℝ
forall r. S²_ r -> r
φParamS² (\(S²Polar θ _) φ -> ℝ -> ℝ -> S²
forall r. r -> r -> S²_ r
S²Polar θ φ)
  validCoordinateRange :: CoordinateIdentifier S² -> S² -> (ℝ, ℝ)
validCoordinateRange CoordinateIdentifier S²
S²ZenithAngle _ = (0, ℝ
forall a. Floating a => a
pi)
  validCoordinateRange CoordinateIdentifier S²
S²Azimuth (S²Polar θ _)
    | θℝ -> ℝ -> Bool
forall a. Ord a => a -> a -> Bool
>0 Bool -> Bool -> Bool
&& θℝ -> ℝ -> Bool
forall a. Ord a => a -> a -> Bool
<ℝ
forall a. Floating a => a
pi  = (-ℝ
forall a. Floating a => a
pi, ℝ
forall a. Floating a => a
pi)
    | Bool
otherwise    = (0, 0)

instance QC.Arbitrary (CoordinateIdentifier ) where
  arbitrary :: Gen (CoordinateIdentifier S²)
arbitrary = [CoordinateIdentifier S²] -> Gen (CoordinateIdentifier S²)
forall a. [a] -> Gen a
QC.elements [CoordinateIdentifier S²
S²Azimuth, CoordinateIdentifier S²
S²ZenithAngle]

instance HasAzimuth  where
  azimuth :: q
azimuth = CoordinateIdentifier S² -> Coordinate S²
forall m. CoordinateIdentifier m -> Coordinate m
coordinate CoordinateIdentifier S²
S²Azimuth
  
class HasZenithDistance m where
  zenithAngle :: Coordinate m

instance HasZenithDistance  where
  zenithAngle :: q
zenithAngle = CoordinateIdentifier S² -> Coordinate S²
forall m. CoordinateIdentifier m -> Coordinate m
coordinate CoordinateIdentifier S²
S²ZenithAngle

instance CoordDifferential  where
  delta :: CoordinateIdentifier S² -> Coordinate (TangentBundle S²)
delta CoordinateIdentifier S²
S²ZenithAngle = CoordinateIdentifier (FibreBundle S² ℝ²) -> q
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (CoordinateIdentifier (FibreBundle S² ℝ²) -> q)
-> ((S² -> CoordinateIdentifier ℝ²)
    -> CoordinateIdentifier (FibreBundle S² ℝ²))
-> (S² -> CoordinateIdentifier ℝ²)
-> q
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (S² -> CoordinateIdentifier ℝ²)
-> CoordinateIdentifier (FibreBundle S² ℝ²)
forall b f.
(b -> CoordinateIdentifier f)
-> CoordinateIdentifier (FibreBundle b f)
FibreSpaceCoordinate
            ((S² -> CoordinateIdentifier ℝ²) -> q)
-> (S² -> CoordinateIdentifier ℝ²) -> q
forall a b. (a -> b) -> a -> b
$ \(S²Polar θ φ) -> let eθ :: ℝ²

                                     | θ ℝ -> ℝ -> Bool
forall a. Ord a => a -> a -> Bool
< ℝ
forall a. Floating a => a
piℝ -> ℝ -> ℝ
forall a. Fractional a => a -> a -> a
/2   = S¹ -> ℝ²
forall m v. NaturallyEmbedded m v => m -> v
embed (S¹ -> ℝ²) -> (ℝ -> S¹) -> ℝ -> ℝ²
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ℝ -> S¹
forall r. r -> S¹_ r
S¹Polar (ℝ -> ℝ²) -> ℝ -> ℝ²
forall a b. (a -> b) -> a -> b
$  φ
                                     | Bool
otherwise  = S¹ -> ℝ²
forall m v. NaturallyEmbedded m v => m -> v
embed (S¹ -> ℝ²) -> (ℝ -> S¹) -> ℝ -> ℝ²
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ℝ -> S¹
forall r. r -> S¹_ r
S¹Polar (ℝ -> ℝ²) -> ℝ -> ℝ²
forall a b. (a -> b) -> a -> b
$ -φ
                                in OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²
ℝ²Coord (OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²)
-> OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²
forall a b. (a -> b) -> a -> b
$ ℝ² -> DualVector ℝ² -> OriginAxisCoord ℝ²
forall v. v -> DualVector v -> OriginAxisCoord v
OriginAxisCoord ℝ²
 ℝ²
DualVector ℝ²

  delta CoordinateIdentifier S²
S²Azimuth = CoordinateIdentifier (FibreBundle S² ℝ²) -> q
forall m. CoordinateIdentifier m -> Coordinate m
coordinate (CoordinateIdentifier (FibreBundle S² ℝ²) -> q)
-> ((S² -> CoordinateIdentifier ℝ²)
    -> CoordinateIdentifier (FibreBundle S² ℝ²))
-> (S² -> CoordinateIdentifier ℝ²)
-> q
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (S² -> CoordinateIdentifier ℝ²)
-> CoordinateIdentifier (FibreBundle S² ℝ²)
forall b f.
(b -> CoordinateIdentifier f)
-> CoordinateIdentifier (FibreBundle b f)
FibreSpaceCoordinate
            ((S² -> CoordinateIdentifier ℝ²) -> q)
-> (S² -> CoordinateIdentifier ℝ²) -> q
forall a b. (a -> b) -> a -> b
$ \(S²Polar θ φ) -> let eφ :: ℝ²

                                     | θ ℝ -> ℝ -> Bool
forall a. Ord a => a -> a -> Bool
< ℝ
forall a. Floating a => a
piℝ -> ℝ -> ℝ
forall a. Fractional a => a -> a -> a
/2   = S¹ -> ℝ²
forall m v. NaturallyEmbedded m v => m -> v
embed (S¹ -> ℝ²) -> (ℝ -> S¹) -> ℝ -> ℝ²
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ℝ -> S¹
forall r. r -> S¹_ r
S¹Polar (ℝ -> ℝ²) -> ℝ -> ℝ²
forall a b. (a -> b) -> a -> b
$ φ ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ ℝ
forall a. Floating a => a
piℝ -> ℝ -> ℝ
forall a. Fractional a => a -> a -> a
/2
                                     | Bool
otherwise  = S¹ -> ℝ²
forall m v. NaturallyEmbedded m v => m -> v
embed (S¹ -> ℝ²) -> (ℝ -> S¹) -> ℝ -> ℝ²
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ℝ -> S¹
forall r. r -> S¹_ r
S¹Polar (ℝ -> ℝ²) -> ℝ -> ℝ²
forall a b. (a -> b) -> a -> b
$ ℝ
forall a. Floating a => a
piℝ -> ℝ -> ℝ
forall a. Fractional a => a -> a -> a
/2 ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
- φ
                                    sθ :: ℝ
 = ℝ -> ℝ
forall a. Floating a => a -> a
sin θ ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ tiny
                                    -- ^ Right at the poles, azimuthal movements
                                    --   become inexpressible, which manifests itself
                                    --   in giving infinite diffs. Moreover,
                                    --   we also can't retrieve tangent diffs we put
                                    --   in anymore. Arguably, this just expresses
                                    --   the fact that azimuthal changes are meaningless
                                    --   at the poles, however it violates the lens
                                    --   laws, so prevent the infinity by keeping
                                    --   sin θ very slightly above 0.
                                in OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²
ℝ²Coord (OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²)
-> OriginAxisCoord ℝ² -> CoordinateIdentifier ℝ²
forall a b. (a -> b) -> a -> b
$ ℝ² -> DualVector ℝ² -> OriginAxisCoord ℝ²
forall v. v -> DualVector v -> OriginAxisCoord v
OriginAxisCoord (ℝ²
ℝ² -> ℝ -> ℝ²
forall v s. (VectorSpace v, s ~ Scalar v) => v -> s -> v
^*) (ℝ²
ℝ² -> ℝ -> ℝ²
forall v s.
(VectorSpace v, s ~ Scalar v, Fractional s) =>
v -> s -> v
^/)

-- | @2e-162@. A value that's so small that it can't notably disturb any nonzero value
--   you might realistically encounter (i.e. @x + tiny == x@), but still large enough
--   that ratios can reliably be represented (i.e. @x * tiny / tiny == x@).
tiny :: 
tiny :: ℝ
tiny = ℝ -> ℝ -> ℝ
forall a. IEEE a => a -> a -> a
IEEE.bisectIEEE ℝ
forall a. IEEE a => a
IEEE.minNormal ℝ
forall a. IEEE a => a
IEEE.epsilon
                

suchThatMap :: QC.Gen a -> (a -> Maybe b) -> QC.Gen b
#if !MIN_VERSION_QuickCheck(2,11,0)
gen `suchThatMap` f =
  fmap fromJust $ fmap f gen `QC.suchThat` isJust
#else
suchThatMap :: Gen a -> (a -> Maybe b) -> Gen b
suchThatMap = Gen a -> (a -> Maybe b) -> Gen b
forall a b. Gen a -> (a -> Maybe b) -> Gen b
QC.suchThatMap
#endif