-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Numerical spaces. -- -- numhask-space provides support for spaces where space -- is defined as a set of numbers with a lower and upper bound. -- --
-- >>> {-# LANGUAGE RebindableSyntax #-}
--
-- >>> import NumHask.Prelude
--
-- >>> import NumHask.Space
--
@package numhask-space
@version 0.10.0.1
-- | A Space containing numerical elements
module NumHask.Space.Range
-- | A continuous range over type a
--
-- -- >>> let a = Range (-1) 1 -- -- >>> a -- Range -1 1 ---- --
-- >>> a + a -- Range -2 2 ---- --
-- >>> a * a -- Range -2.0 2.0 ---- --
-- >>> (+1) <$> (Range 1 2) -- Range 2 3 ---- -- Ranges are very useful in shifting a bunch of numbers from one Range -- to another. eg project 0.5 from the range 0 to 1 to the range 1 to 4 -- --
-- >>> project (Range 0 1) (Range 1 4) 0.5 -- 2.5 ---- -- Create an equally spaced grid including outer bounds over a Range -- --
-- >>> grid OuterPos (Range 0.0 10.0) 5 -- [0.0,2.0,4.0,6.0,8.0,10.0] ---- -- divide up a Range into equal-sized sections -- --
-- >>> gridSpace (Range 0.0 1.0) 4 -- [Range 0.0 0.25,Range 0.25 0.5,Range 0.5 0.75,Range 0.75 1.0] --data Range a Range :: a -> a -> Range a -- | a grid for five-digits per limb species -- --
-- >>> gridSensible OuterPos False (Range (-12.0) 23.0) 6 -- [-15.0,-10.0,-5.0,0.0,5.0,10.0,15.0,20.0,25.0] --gridSensible :: Pos -> Bool -> Range Double -> Integer -> [Double] instance GHC.Generics.Generic (NumHask.Space.Range.Range a) instance GHC.Classes.Eq a => GHC.Classes.Eq (NumHask.Space.Range.Range a) instance GHC.Show.Show a => GHC.Show.Show (NumHask.Space.Range.Range a) instance Data.Functor.Classes.Eq1 NumHask.Space.Range.Range instance Data.Functor.Classes.Show1 NumHask.Space.Range.Range instance GHC.Base.Functor NumHask.Space.Range.Range instance Data.Functor.Bind.Class.Apply NumHask.Space.Range.Range instance GHC.Base.Applicative NumHask.Space.Range.Range instance Data.Foldable.Foldable NumHask.Space.Range.Range instance Data.Semigroup.Foldable.Class.Foldable1 NumHask.Space.Range.Range instance Data.Traversable.Traversable NumHask.Space.Range.Range instance Data.Semigroup.Traversable.Class.Traversable1 NumHask.Space.Range.Range instance Data.Distributive.Distributive NumHask.Space.Range.Range instance Data.Functor.Rep.Representable NumHask.Space.Range.Range instance GHC.Classes.Ord a => NumHask.Algebra.Lattice.JoinSemiLattice (NumHask.Space.Range.Range a) instance GHC.Classes.Ord a => NumHask.Algebra.Lattice.MeetSemiLattice (NumHask.Space.Range.Range a) instance GHC.Classes.Ord a => NumHask.Space.Types.Space (NumHask.Space.Range.Range a) instance (NumHask.Algebra.Field.Field a, GHC.Classes.Ord a, NumHask.Data.Integral.FromIntegral a GHC.Types.Int) => NumHask.Space.Types.FieldSpace (NumHask.Space.Range.Range a) instance GHC.Classes.Ord a => GHC.Base.Semigroup (NumHask.Space.Range.Range a) instance (NumHask.Algebra.Additive.Additive a, GHC.Classes.Ord a) => NumHask.Algebra.Additive.Additive (NumHask.Space.Range.Range a) instance (NumHask.Algebra.Additive.Subtractive a, GHC.Classes.Ord a) => NumHask.Algebra.Additive.Subtractive (NumHask.Space.Range.Range a) instance (NumHask.Algebra.Field.Field a, GHC.Classes.Ord a) => NumHask.Algebra.Multiplicative.Multiplicative (NumHask.Space.Range.Range a) instance (GHC.Classes.Ord a, NumHask.Algebra.Field.Field a) => NumHask.Algebra.Multiplicative.Divisive (NumHask.Space.Range.Range a) instance (NumHask.Algebra.Field.Field a, GHC.Classes.Ord a) => NumHask.Algebra.Metric.Signed (NumHask.Space.Range.Range a) -- | data algorithms related to time (as a Space) module NumHask.Space.Time -- | a step in time data TimeGrain Years :: Integer -> TimeGrain Months :: Int -> TimeGrain Days :: Int -> TimeGrain Hours :: Int -> TimeGrain Minutes :: Int -> TimeGrain Seconds :: Double -> TimeGrain -- | compute the floor UTCTime based on the timegrain -- --
-- >>> floorGrain (Years 5) (UTCTime (fromGregorian 1999 1 1) (toDiffTime 0)) -- 1995-12-31 00:00:00 UTC ---- --
-- >>> floorGrain (Months 3) (UTCTime (fromGregorian 2016 12 30) (toDiffTime 0)) -- 2016-09-30 00:00:00 UTC ---- --
-- >>> floorGrain (Days 5) (UTCTime (fromGregorian 2016 12 30) (toDiffTime 1)) -- 2016-12-30 00:00:00 UTC ---- --
-- >>> floorGrain (Minutes 15) (UTCTime (fromGregorian 2016 12 30) (toDiffTime $ 15*60+1)) -- 2016-12-30 00:15:00 UTC ---- --
-- >>> floorGrain (Seconds 0.1) (UTCTime (fromGregorian 2016 12 30) ((toDiffTime 0.12))) -- 2016-12-30 00:00:00.1 UTC --floorGrain :: TimeGrain -> UTCTime -> UTCTime -- | compute the ceiling UTCTime based on the timegrain -- --
-- >>> ceilingGrain (Years 5) (UTCTime (fromGregorian 1999 1 1) (toDiffTime 0)) -- 2000-12-31 00:00:00 UTC ---- --
-- >>> ceilingGrain (Months 3) (UTCTime (fromGregorian 2016 12 30) (toDiffTime 0)) -- 2016-12-31 00:00:00 UTC ---- --
-- >>> ceilingGrain (Days 5) (UTCTime (fromGregorian 2016 12 30) (toDiffTime 1)) -- 2016-12-31 00:00:00 UTC ---- --
-- >>> ceilingGrain (Minutes 15) (UTCTime (fromGregorian 2016 12 30) (toDiffTime $ 15*60+1)) -- 2016-12-30 00:30:00 UTC ---- --
-- >>> ceilingGrain (Seconds 0.1) (UTCTime (fromGregorian 2016 12 30) (toDiffTime 0.12)) -- 2016-12-30 00:00:00.2 UTC --ceilingGrain :: TimeGrain -> UTCTime -> UTCTime -- | add a TimeGrain to a UTCTime -- --
-- >>> addGrain (Years 1) 5 (UTCTime (fromGregorian 2015 2 28) (toDiffTime 0)) -- 2020-02-29 00:00:00 UTC ---- --
-- >>> addGrain (Months 1) 1 (UTCTime (fromGregorian 2015 2 28) (toDiffTime 0)) -- 2015-03-31 00:00:00 UTC ---- --
-- >>> addGrain (Hours 6) 5 (UTCTime (fromGregorian 2015 2 28) (toDiffTime 0)) -- 2015-03-01 06:00:00 UTC ---- --
-- >>> addGrain (Seconds 0.001) (60*1000+1) (UTCTime (fromGregorian 2015 2 28) (toDiffTime 0)) -- 2015-02-28 00:01:00.001 UTC --addGrain :: TimeGrain -> Int -> UTCTime -> UTCTime -- | compute a sensible TimeGrain and list of UTCTimes -- --
-- >>> sensibleTimeGrid InnerPos 2 (Range (UTCTime (fromGregorian 2016 12 31) (toDiffTime 0)) (UTCTime (fromGregorian 2017 12 31) (toDiffTime 0))) -- (Months 6,[2016-12-31 00:00:00 UTC,2017-06-30 00:00:00 UTC,2017-12-31 00:00:00 UTC]) ---- --
-- >>> sensibleTimeGrid InnerPos 2 (Range (UTCTime (fromGregorian 2017 1 1) (toDiffTime 0)) (UTCTime (fromGregorian 2017 12 30) (toDiffTime 0))) -- (Months 6,[2017-06-30 00:00:00 UTC]) ---- --
-- >>> sensibleTimeGrid UpperPos 2 (Range (UTCTime (fromGregorian 2017 1 1) (toDiffTime 0)) (UTCTime (fromGregorian 2017 12 30) (toDiffTime 0))) -- (Months 6,[2017-06-30 00:00:00 UTC,2017-12-31 00:00:00 UTC]) ---- --
-- >>> sensibleTimeGrid LowerPos 2 (Range (UTCTime (fromGregorian 2017 1 1) (toDiffTime 0)) (UTCTime (fromGregorian 2017 12 30) (toDiffTime 0))) -- (Months 6,[2016-12-31 00:00:00 UTC,2017-06-30 00:00:00 UTC]) --sensibleTimeGrid :: Pos -> Int -> Range UTCTime -> (TimeGrain, [UTCTime]) -- | whether to include lower and upper times data PosDiscontinuous PosInnerOnly :: PosDiscontinuous PosIncludeBoundaries :: PosDiscontinuous -- | Dates used for time series analysis or attached to charts are often -- discontinuous, but we want to smooth that reality over and show a -- continuous range on the axis. -- -- The assumption with getSensibleTimeGrid is that there is a list of -- discountinuous UTCTimes rather than a continuous range. Output is a -- list of index points for the original [UTCTime] and label tuples, and -- a list of unused list elements. -- --
-- >>> placedTimeLabelDiscontinuous PosIncludeBoundaries (Just (pack "%d %b")) 2 [UTCTime (fromGregorian 2017 12 6) (toDiffTime 0), UTCTime (fromGregorian 2017 12 29) (toDiffTime 0), UTCTime (fromGregorian 2018 1 31) (toDiffTime 0), UTCTime (fromGregorian 2018 3 3) (toDiffTime 0)] -- ([(0,"06 Dec"),(1,"31 Dec"),(2,"28 Feb"),(3,"03 Mar")],[]) --placedTimeLabelDiscontinuous :: PosDiscontinuous -> Maybe Text -> Int -> [UTCTime] -> ([(Int, Text)], [UTCTime]) -- | A sensible time grid between two dates, projected onto (0,1) with no -- attempt to get finnicky. -- --
-- >>> placedTimeLabelContinuous PosIncludeBoundaries (Just (pack "%d %b")) 2 (Range (UTCTime (fromGregorian 2017 12 6) (toDiffTime 0)) (UTCTime (fromGregorian 2017 12 29) (toDiffTime 0))) -- [(0.0,"06 Dec"),(0.4347826086956521,"16 Dec"),(0.8695652173913042,"26 Dec"),(0.9999999999999999,"29 Dec")] --placedTimeLabelContinuous :: PosDiscontinuous -> Maybe Text -> Int -> Range UTCTime -> [(Double, Text)] -- | convenience conversion to Double fromNominalDiffTime :: NominalDiffTime -> Double -- | convenience conversion from Double toNominalDiffTime :: Double -> NominalDiffTime -- | Convert from DiffTime to seconds (as a Double) -- --
-- >>> fromDiffTime $ toDiffTime 1 -- 1.0 --fromDiffTime :: DiffTime -> Double -- | Convert from seconds (as a Double) to DiffTime >>> -- toDiffTime 1 1s toDiffTime :: Double -> DiffTime instance GHC.Generics.Generic NumHask.Space.Time.TimeGrain instance GHC.Classes.Eq NumHask.Space.Time.TimeGrain instance GHC.Show.Show NumHask.Space.Time.TimeGrain -- | A 2-dimensional point. module NumHask.Space.Point -- | A 2-dimensional Point of a's -- -- In contrast with a tuple, a Point is functorial over both arguments. -- --
-- >>> let p = Point 1 1 -- -- >>> p + p -- Point 2 2 -- -- >>> (2*) <$> p -- Point 2 2 ---- -- A major reason for this bespoke treatment (compared to just using -- linear, say) is that Points do not have maximums and minimums but they -- do form a lattice, and this is useful for folding sets of points to -- find out the (rectangular) Space they occupy. -- --
-- >>> Point 0 1 /\ Point 1 0 -- Point 0 0 -- -- >>> Point 0 1 \/ Point 1 0 -- Point 1 1 ---- -- This is used extensively in chart-svg to ergonomically obtain -- chart areas. -- --
-- unsafeSpace1 [Point 1 0, Point 0 1] :: Rect Double ---- -- Rect 0.0 1.0 0.0 1.0 data Point a Point :: a -> a -> Point a [_x] :: Point a -> a [_y] :: Point a -> a -- | rotate a point by x relative to the origin -- --
-- >>> rotateP (pi/2) (Point 1 0) -- Point 6.123233995736766e-17 1.0 --rotateP :: TrigField a => a -> Point a -> Point a -- | Create Points for a formulae y = f(x) across an x range -- --
-- >>> gridP (^^2) (Range 0 4) 4 -- [Point 0.0 0.0,Point 1.0 1.0,Point 2.0 4.0,Point 3.0 9.0,Point 4.0 16.0] --gridP :: FieldSpace (Range a) => (a -> a) -> Range a -> Grid (Range a) -> [Point a] -- | dot product dotP :: (Multiplicative a, Additive a) => Point a -> Point a -> a -- | dot product operator (<.>) :: (Multiplicative a, Additive a) => Point a -> Point a -> a infix 4 <.> -- | cross product crossP :: (Multiplicative a, Subtractive a) => Point a -> Point a -> a -- | reflect on x-axis flipY :: Subtractive a => Point a -> Point a -- | A line is a composed of 2 Points data Line a Line :: Point a -> Point a -> Line a [lineStart] :: Line a -> Point a [lineEnd] :: Line a -> Point a -- | Return the parameters (a, b, c) for the line equation a*x + b*y + -- c = 0. lineSolve :: (ExpField a, Eq a) => Line a -> (a, a, a) -- | Return the signed distance from a point to the line. If the distance -- is negative, the point lies to the right of the line lineDistance :: ExpField a => Line a -> Point a -> a -- | Return the point on the line closest to the given point. closestPoint :: Field a => Line a -> Point a -> Point a -- | Calculate the intersection of two lines. If the determinant is less -- than tolerance (parallel or coincident lines), return Nothing. lineIntersect :: (Ord a, Epsilon a, Signed a, Field a) => Line a -> Line a -> Maybe (Point a) -- | move an Affinity by a Point translate :: TrigField a => Point a -> Transform a -- | scale an Affinity by a Point scaleT :: TrigField a => Point a -> Transform a -- | Skew transform -- -- x-axis skew -- --
-- skew (Point x 0) --skew :: TrigField a => Point a -> Transform a instance GHC.Generics.Generic (NumHask.Space.Point.Point a) instance GHC.Classes.Eq a => GHC.Classes.Eq (NumHask.Space.Point.Point a) instance Data.Traversable.Traversable NumHask.Space.Point.Line instance Data.Foldable.Foldable NumHask.Space.Point.Line instance GHC.Base.Functor NumHask.Space.Point.Line instance GHC.Classes.Eq a => GHC.Classes.Eq (NumHask.Space.Point.Line a) instance GHC.Show.Show a => GHC.Show.Show (NumHask.Space.Point.Line a) instance (NumHask.Algebra.Multiplicative.Multiplicative a, NumHask.Algebra.Additive.Additive a) => NumHask.Space.Types.Affinity (NumHask.Space.Point.Line a) a instance GHC.Show.Show a => GHC.Show.Show (NumHask.Space.Point.Point a) instance GHC.Base.Functor NumHask.Space.Point.Point instance Data.Functor.Classes.Eq1 NumHask.Space.Point.Point instance Data.Functor.Classes.Show1 NumHask.Space.Point.Point instance GHC.Base.Applicative NumHask.Space.Point.Point instance GHC.Base.Monad NumHask.Space.Point.Point instance Data.Foldable.Foldable NumHask.Space.Point.Point instance Data.Traversable.Traversable NumHask.Space.Point.Point instance GHC.Base.Semigroup a => GHC.Base.Semigroup (NumHask.Space.Point.Point a) instance GHC.Base.Monoid a => GHC.Base.Monoid (NumHask.Space.Point.Point a) instance GHC.Enum.Bounded a => GHC.Enum.Bounded (NumHask.Space.Point.Point a) instance NumHask.Algebra.Additive.Additive a => NumHask.Algebra.Additive.Additive (NumHask.Space.Point.Point a) instance NumHask.Algebra.Additive.Subtractive a => NumHask.Algebra.Additive.Subtractive (NumHask.Space.Point.Point a) instance NumHask.Algebra.Multiplicative.Multiplicative a => NumHask.Algebra.Multiplicative.Multiplicative (NumHask.Space.Point.Point a) instance NumHask.Algebra.Ring.Distributive a => NumHask.Algebra.Ring.Distributive (NumHask.Space.Point.Point a) instance NumHask.Algebra.Field.Field a => NumHask.Algebra.Field.Field (NumHask.Space.Point.Point a) instance NumHask.Algebra.Metric.Signed a => NumHask.Algebra.Metric.Signed (NumHask.Space.Point.Point a) instance NumHask.Algebra.Multiplicative.Divisive a => NumHask.Algebra.Multiplicative.Divisive (NumHask.Space.Point.Point a) instance Data.Distributive.Distributive NumHask.Space.Point.Point instance NumHask.Algebra.Additive.Additive a => NumHask.Algebra.Module.AdditiveAction (NumHask.Space.Point.Point a) a instance NumHask.Algebra.Additive.Subtractive a => NumHask.Algebra.Module.SubtractiveAction (NumHask.Space.Point.Point a) a instance NumHask.Algebra.Multiplicative.Multiplicative a => NumHask.Algebra.Module.MultiplicativeAction (NumHask.Space.Point.Point a) a instance NumHask.Algebra.Multiplicative.Divisive a => NumHask.Algebra.Module.DivisiveAction (NumHask.Space.Point.Point a) a instance Data.Functor.Rep.Representable NumHask.Space.Point.Point instance GHC.Classes.Ord a => NumHask.Algebra.Lattice.JoinSemiLattice (NumHask.Space.Point.Point a) instance GHC.Classes.Ord a => NumHask.Algebra.Lattice.MeetSemiLattice (NumHask.Space.Point.Point a) instance (NumHask.Algebra.Field.ExpField a, GHC.Classes.Eq a) => NumHask.Algebra.Metric.Norm (NumHask.Space.Point.Point a) a instance NumHask.Algebra.Field.TrigField a => NumHask.Algebra.Metric.Direction (NumHask.Space.Point.Point a) a instance System.Random.Internal.UniformRange a => System.Random.Internal.UniformRange (NumHask.Space.Point.Point a) instance (NumHask.Algebra.Multiplicative.Multiplicative a, NumHask.Algebra.Additive.Additive a) => NumHask.Space.Types.Affinity (NumHask.Space.Point.Point a) a -- | A (finite) two-dimensional plane, implemented as a composite of a -- Point of Ranges. module NumHask.Space.Rect -- | a rectangular space often representing a finite 2-dimensional or XY -- plane. -- --
-- >>> one :: Rect Double -- Rect -0.5 0.5 -0.5 0.5 ---- --
-- >>> zero :: Rect Double -- Rect 0.0 0.0 0.0 0.0 ---- --
-- >>> one + one :: Rect Double -- Rect -1.0 1.0 -1.0 1.0 ---- --
-- >>> let a = Rect (-1.0) 1.0 (-2.0) 4.0 -- -- >>> a -- Rect -1.0 1.0 -2.0 4.0 ---- --
-- >>> a * one -- Rect -1.0 1.0 -2.0 4.0 ---- --
-- >>> let (Ranges x y) = a -- -- >>> x -- Range -1.0 1.0 -- -- >>> y -- Range -2.0 4.0 -- -- >>> fmap (+1) (Rect 1 2 3 4) -- Rect 2 3 4 5 ---- -- as a Space instance with Points as Elements -- --
-- >>> project (Rect 0.0 1.0 (-1.0) 0.0) (Rect 1.0 4.0 10.0 0.0) (Point 0.5 1.0) -- Point 2.5 -10.0 -- -- >>> gridSpace (Rect 0.0 10.0 0.0 1.0) (Point (2::Int) (2::Int)) -- [Rect 0.0 5.0 0.0 0.5,Rect 0.0 5.0 0.5 1.0,Rect 5.0 10.0 0.0 0.5,Rect 5.0 10.0 0.5 1.0] -- -- >>> grid MidPos (Rect 0.0 10.0 0.0 1.0) (Point (2::Int) (2::Int)) -- [Point 2.5 0.25,Point 2.5 0.75,Point 7.5 0.25,Point 7.5 0.75] --newtype Rect a Rect' :: Compose Point Range a -> Rect a -- | pattern of Rect lowerx upperx lowery uppery pattern Rect :: a -> a -> a -> a -> Rect a -- | pattern of Ranges xrange yrange pattern Ranges :: Range a -> Range a -> Rect a -- | create a list of points representing the lower left and upper right -- corners of a rectangle. -- --
-- >>> corners one -- [Point -0.5 -0.5,Point 0.5 0.5] --corners :: Ord a => Rect a -> [Point a] -- | the 4 corners -- --
-- >>> corners4 one -- [Point -0.5 -0.5,Point -0.5 0.5,Point 0.5 -0.5,Point 0.5 0.5] --corners4 :: Rect a -> [Point a] -- | project a Rect from an old Space (Rect) to a new one. -- -- The Space instance of Rect uses Points as Elements, but a Rect can -- also be a Space over Rects. -- --
-- >>> projectRect (Rect 0 1 (-1) 0) (Rect 0 4 0 8) (Rect 0.25 0.75 (-0.75) (-0.25)) -- Rect 1.0 3.0 2.0 6.0 --projectRect :: (Field a, Ord a) => Rect a -> Rect a -> Rect a -> Rect a -- | convex hull union of Rect's -- --
-- >>> foldRect [Rect 0 1 0 1, one] -- Just Rect -0.5 1.0 -0.5 1.0 --foldRect :: Ord a => [Rect a] -> Maybe (Rect a) -- | convex hull union of Rect's applied to a non-empty structure -- --
-- >>> foldRectUnsafe [Rect 0 1 0 1, one] -- Rect -0.5 1.0 -0.5 1.0 --foldRectUnsafe :: (Foldable f, Ord a) => f (Rect a) -> Rect a -- | add a Point to a Rect -- --
-- >>> addPoint (Point 0 1) one -- Rect -0.5 0.5 0.5 1.5 --addPoint :: Additive a => Point a -> Rect a -> Rect a -- | rotate the corners of a Rect by x degrees relative to the origin, and -- fold to a new Rect -- --
-- >>> rotationBound (pi/4) one -- Rect -0.7071067811865475 0.7071067811865475 -0.7071067811865475 0.7071067811865475 --rotationBound :: (TrigField a, Ord a) => a -> Rect a -> Rect a -- | Create Rects for a formulae y = f(x) across an x range where the y -- range is Range 0 y -- --
-- >>> gridR (^2) (Range 0 4) 4 -- [Rect 0.0 1.0 0.0 0.25,Rect 1.0 2.0 0.0 2.25,Rect 2.0 3.0 0.0 6.25,Rect 3.0 4.0 0.0 12.25] --gridR :: (Field a, FromIntegral a Int, Ord a) => (a -> a) -> Range a -> Int -> [Rect a] -- | Create values c for Rects data for a formulae c = f(x,y) -- --
-- >>> gridF (\(Point x y) -> x * y) (Rect 0 4 0 4) (Point 2 2) -- [(Rect 0.0 2.0 0.0 2.0,1.0),(Rect 0.0 2.0 2.0 4.0,3.0),(Rect 2.0 4.0 0.0 2.0,3.0),(Rect 2.0 4.0 2.0 4.0,9.0)] --gridF :: (Point Double -> b) -> Rect Double -> Grid (Rect Double) -> [(Rect Double, b)] -- | convert a ratio (eg x:1) to a Rect with a height of one. -- --
-- >>> aspect 2 -- Rect -1.0 1.0 -0.5 0.5 --aspect :: Double -> Rect Double -- | convert a Rect to a ratio -- --
-- >>> :set -XNegativeLiterals -- -- >>> ratio (Rect -1 1 -0.5 0.5) -- 2.0 --ratio :: Field a => Rect a -> a -- | project a Rect from one Rect to another, preserving relative position, -- with guards for singleton Rects. -- --
-- >>> projectOnR one (Rect 0 1 0 1) (Rect 0 0.5 0 0.5) -- Rect -0.5 0.0 -0.5 0.0 --projectOnR :: Rect Double -> Rect Double -> Rect Double -> Rect Double -- | project a Point from one Rect to another, preserving relative -- position, with guards for singleton Rects. -- --
-- >>> projectOnP one (Rect 0 1 0 1) zero -- Point -0.5 -0.5 --projectOnP :: Rect Double -> Rect Double -> Point Double -> Point Double instance GHC.Generics.Generic (NumHask.Space.Rect.Rect a) instance Data.Traversable.Traversable NumHask.Space.Rect.Rect instance Data.Foldable.Foldable NumHask.Space.Rect.Rect instance GHC.Base.Applicative NumHask.Space.Rect.Rect instance GHC.Base.Functor NumHask.Space.Rect.Rect instance GHC.Classes.Eq a => GHC.Classes.Eq (NumHask.Space.Rect.Rect a) instance GHC.Show.Show a => GHC.Show.Show (NumHask.Space.Rect.Rect a) instance Data.Distributive.Distributive NumHask.Space.Rect.Rect instance Data.Functor.Rep.Representable NumHask.Space.Rect.Rect instance GHC.Classes.Ord a => GHC.Base.Semigroup (NumHask.Space.Rect.Rect a) instance GHC.Classes.Ord a => NumHask.Space.Types.Space (NumHask.Space.Rect.Rect a) instance (NumHask.Data.Integral.FromIntegral a GHC.Types.Int, NumHask.Algebra.Field.Field a, GHC.Classes.Ord a) => NumHask.Space.Types.FieldSpace (NumHask.Space.Rect.Rect a) instance NumHask.Algebra.Additive.Additive a => NumHask.Algebra.Additive.Additive (NumHask.Space.Rect.Rect a) instance NumHask.Algebra.Additive.Subtractive a => NumHask.Algebra.Additive.Subtractive (NumHask.Space.Rect.Rect a) instance (GHC.Classes.Ord a, NumHask.Algebra.Field.Field a) => NumHask.Algebra.Multiplicative.Multiplicative (NumHask.Space.Rect.Rect a) instance (GHC.Classes.Ord a, NumHask.Algebra.Field.Field a) => NumHask.Algebra.Multiplicative.Divisive (NumHask.Space.Rect.Rect a) instance (GHC.Classes.Ord a, NumHask.Algebra.Field.Field a) => NumHask.Algebra.Metric.Signed (NumHask.Space.Rect.Rect a) -- | A histogram, if you squint, is a series of contiguous Ranges, -- annotated with values. module NumHask.Space.Histogram -- | This Histogram is a list of contiguous boundaries (a boundary being -- the lower edge of one bucket and the upper edge of another), and a -- value (usually a count) for each bucket, represented here as a map -- -- Overs and Unders are contained in key = 0 and key = length cuts -- Intervals are defined as (l,u] data Histogram Histogram :: Vector Double -> Map Int Double -> Histogram [cuts] :: Histogram -> Vector Double [values] :: Histogram -> Map Int Double -- | A histogram with no cuts nor data. emptyHistogram :: Histogram -- | Whether or not to ignore unders and overs. If overs and unders are -- dealt with, IncludeOvers supplies an assumed width for the outer -- buckets. data DealOvers IgnoreOvers :: DealOvers IncludeOvers :: Double -> DealOvers -- | Fill a Histogram using pre-specified cuts -- --
-- >>> fill [0,50,100] [0..99]
-- Histogram {cuts = [0.0,50.0,100.0], values = fromList [(1,50.0),(2,50.0)]}
--
fill :: Foldable f => [Double] -> f Double -> Histogram
-- | find the index of the bucket the value is contained in.
cutI :: Ord a => Vector a -> a -> Int
-- | Make a histogram using n equally spaced cuts over the entire range of
-- the data
--
--
-- >>> regular 4 [0..100]
-- Histogram {cuts = [0.0,25.0,50.0,75.0,100.0], values = fromList [(1,25.0),(2,25.0),(3,25.0),(4,25.0),(5,1.0)]}
--
regular :: Int -> [Double] -> Histogram
-- | Transform a Histogram to Rects
--
-- -- >>> makeRects IgnoreOvers (regular 4 [0..100]) -- [Rect 0.0 25.0 0.0 0.25,Rect 25.0 50.0 0.0 0.25,Rect 50.0 75.0 0.0 0.25,Rect 75.0 100.0 0.0 0.25] --makeRects :: DealOvers -> Histogram -> [Rect Double] -- | approx regular n-quantiles -- --
-- >>> regularQuantiles 4 [0..100] -- [0.0,24.75,50.0,75.25,100.0] --regularQuantiles :: Double -> [Double] -> [Double] -- | one-pass approximate quantiles fold quantileFold :: [Double] -> [Double] -> [Double] -- | normalize a histogram -- --
-- \h -> sum (values $ freq h) == one ---- --
-- >>> freq $ fill [0,50,100] [0..99]
-- Histogram {cuts = [0.0,50.0,100.0], values = fromList [(1,0.5),(2,0.5)]}
--
freq :: Histogram -> Histogram
-- | average
--
-- -- >>> average [0..1000] -- 500.0 --average :: Foldable f => f Double -> Double -- | Regularly spaced (approx) quantiles -- --
-- >>> quantiles 5 [1..1000] -- [1.0,200.5,400.5,600.5000000000001,800.5,1000.0] --quantiles :: Foldable f => Int -> f Double -> [Double] -- | single (approx) quantile -- --
-- >>> quantile 0.1 [1..1000] -- 100.5 --quantile :: Foldable f => Double -> f Double -> Double instance GHC.Classes.Eq NumHask.Space.Histogram.Histogram instance GHC.Show.Show NumHask.Space.Histogram.Histogram -- | Mathematics does not rigorously define a space, leaving library -- devs free to explore. -- -- “But who can quantify the algebra of space, or weigh those worlds that -- swim each in its place? Who can outdo the dark? And what computer -- knows how beauty comes to birth - shell star and rose? -- -- ~ Technicians by Jean Kenward” ~ John Foster module NumHask.Space -- | A Space is a continuous set of numbers. Continuous here means -- that the set has an upper and lower bound, and an element that is -- between these two bounds is a member of the Space. -- --
-- a `union` b == b `union` a -- a `intersection` b == b `intersection` a -- (a `union` b) `intersection` c == (a `intersection` b) `union` (a `intersection` c) -- (a `intersection` b) `union` c == (a `union` b) `intersection` (a `union` c) -- norm (norm a) = norm a -- a |>| b == b |<| a -- a |.| singleton a --class Space s where { -- | the underlying element in the space type Element s :: Type; } -- | lower boundary lower :: Space s => s -> Element s -- | upper boundary upper :: Space s => s -> Element s -- | space containing a single element singleton :: Space s => Element s -> s -- | the intersection of two spaces intersection :: Space s => s -> s -> s -- | the intersection of two spaces intersection :: (Space s, Ord (Element s)) => s -> s -> s -- | the union of two spaces union :: Space s => s -> s -> s -- | the union of two spaces union :: (Space s, Ord (Element s)) => s -> s -> s -- | Normalise a space so that -- --
-- lower a \/ upper a == lower a -- lower a /\ upper a == upper a --normalise :: Space s => s -> s -- | create a normalised space from two elements (...) :: Space s => Element s -> Element s -> s -- | create a normalised space from two elements (...) :: (Space s, Ord (Element s)) => Element s -> Element s -> s -- | create a space from two elements without normalising (>.<) :: Space s => Element s -> Element s -> s -- | is an element in the space (|.|) :: Space s => Element s -> s -> Bool -- | is an element in the space (|.|) :: (Space s, Ord (Element s)) => Element s -> s -> Bool -- | is one space completely above the other (|>|) :: Space s => s -> s -> Bool -- | is one space completely above the other (|>|) :: (Space s, Ord (Element s)) => s -> s -> Bool -- | is one space completely below the other (|<|) :: Space s => s -> s -> Bool -- | is one space completely below the other (|<|) :: (Space s, Ord (Element s)) => s -> s -> Bool infix 3 >.< infix 3 ... infixl 7 |.| infixl 7 |>| infixl 7 |<| -- | a convex hull newtype Union a Union :: a -> Union a [getUnion] :: Union a -> a -- | https://en.wikipedia.org/wiki/Intersection_(set_theory) newtype Intersection a Intersection :: a -> Intersection a [getIntersection] :: Intersection a -> a -- | a space that can be divided neatly -- --
-- unsafeSpace1 (grid OuterPos s g) == s -- getUnion (sconcat (Union <$> (gridSpace s g))) == s --class (Space s, Field (Element s)) => FieldSpace s where { type Grid s :: Type; } -- | create equally-spaced elements across a space grid :: FieldSpace s => Pos -> s -> Grid s -> [Element s] -- | create equally-spaced spaces from a space gridSpace :: FieldSpace s => s -> Grid s -> [s] -- | middle element of the space mid :: (Space s, Field (Element s)) => s -> Element s -- | interpolate a space -- --
-- interpolate s x == project s (zero ... one) x --interpolate :: (Space s, Ring (Element s)) => s -> Element s -> Element s -- | project an element from one space to another, preserving relative -- position. -- --
-- project o n (lower o) = lower n -- project o n (upper o) = upper n -- project o n (mid o) = mid n -- project a a x = x --project :: (Space s, Field (Element s)) => s -> s -> Element s -> Element s -- | Pos suggests where points should be placed in forming a grid across a -- field space. data Pos -- | include boundaries OuterPos :: Pos -- | don't include boundaries InnerPos :: Pos -- | include the lower boundary LowerPos :: Pos -- | include the upper boundary UpperPos :: Pos -- | use the mid-point of the space MidPos :: Pos -- | Maybe containing space of a traversable. space1 :: (Space s, Traversable f) => f (Element s) -> Maybe s -- | the containing space of a non-empty Traversable. -- -- partial function. -- --
-- all $ unsafeSpace1 a `contains` <$> a --unsafeSpace1 :: (Space s, Traversable f) => f (Element s) -> s -- | supply a random element within a Space -- --
-- >>> randomS (one :: Range Double) g
-- (0.43085240252163404,StdGen {unStdGen = SMGen 4530528345362647137 13679457532755275413})
--
randomS :: (Space s, RandomGen g, UniformRange (Element s)) => s -> g -> (Element s, g)
-- | StatefulGen version of randomS
--
-- -- >>> import Control.Monad -- -- >>> runStateGen_ g (randomSM (one :: Range Double)) -- 0.43085240252163404 --randomSM :: (UniformRange (Element s), StatefulGen g m, Space s) => s -> g -> m (Element s) -- | list of n random elements within a Space -- --
-- >>> let g = mkStdGen 42 -- -- >>> fst (randomSs 3 (one :: Range Double) g) -- [0.43085240252163404,-6.472345419562497e-2,0.3854692674681801] ---- --
-- >>> fst (randomSs 3 (Rect 0 10 0 10 :: Rect Int) g) -- [Point 0 7,Point 0 2,Point 1 7] --randomSs :: (Space s, RandomGen g, UniformRange (Element s)) => Int -> s -> g -> ([Element s], g) -- | is an element contained within a space memberOf :: Space s => Element s -> s -> Bool -- | is a space contained within another? -- --
-- (a `union` b) `contains` a -- (a `union` b) `contains` b --contains :: Space s => s -> s -> Bool -- | are two spaces disjoint? disjoint :: Space s => s -> s -> Bool -- | distance between boundaries width :: (Space s, Subtractive (Element s)) => s -> Element s -- | create a space centered on a plus or minus b (+/-) :: (Space s, Subtractive (Element s)) => Element s -> Element s -> s infixl 6 +/- -- | lift a monotone function (increasing or decreasing) over a given space monotone :: (Space a, Space b) => (Element a -> Element b) -> a -> b -- | a small space eps :: (Space s, FromRational (Element s), Field (Element s)) => Element s -> Element s -> s -- | widen a space widen :: (Space s, Ring (Element s)) => Element s -> s -> s -- | widen by a small amount widenEps :: (Space s, FromRational (Element s), Ring (Element s)) => Element s -> s -> s -- | Scale a Space. (scalar multiplication) scale :: (Multiplicative (Element s), Space s) => Element s -> s -> s -- | Move a Space. (scalar addition) move :: (Additive (Element s), Space s) => Element s -> s -> s -- | linear transform + translate of a point-like number -- --
-- (x, y) -> (ax + by + c, dx + ey + d) ---- -- or -- -- <math> data Transform a Transform :: !a -> !a -> !a -> !a -> !a -> !a -> Transform a [ta] :: Transform a -> !a [tb] :: Transform a -> !a [tc] :: Transform a -> !a [td] :: Transform a -> !a [te] :: Transform a -> !a [tf] :: Transform a -> !a -- | Calculate the inverse of a transformation. inverseTransform :: (Eq a, Field a) => Transform a -> Maybe (Transform a) -- | An Affinity is something that can be subjected to an affine -- transformation in 2-dimensional space, where affine means a linear -- matrix operation or a translation (+). -- -- https://en.wikipedia.org/wiki/Affine_transformation class Affinity a b | a -> b transform :: Affinity a b => Transform b -> a -> a -- | Apply a Transform to an Affinity (|.) :: Affinity a b => Transform b -> a -> a infix 3 |. -- | Rotate an Affinity (counter-clockwise) rotate :: TrigField a => a -> Transform a