manifolds-0.5.0.1: Coordinate-free hypersurfaces

Copyright(c) Justus Sagemüller 2015
LicenseGPL v3
Maintainer(@) sagemueller $ geo.uni-koeln.de
Stabilityexperimental
Portabilityportable
Safe HaskellNone
LanguageHaskell2010

Data.Function.Differentiable

Contents

Description

 

Synopsis

Everywhere differentiable functions

data Differentiable s d c Source #

The category of differentiable functions between manifolds over scalar s.

As you might guess, these offer automatic differentiation of sorts (basically, simple forward AD), but that's in itself is not really the killer feature here. More interestingly, we actually have the (à la Curry-Howard) proof built in: the function f has at x₀ derivative f'ₓ₀, if, for¹ ε>0, there exists δ such that |f x − (f x₀ + xf'ₓ₀)| < ε for all |xx₀| < δ.

Observe that, though this looks quite similar to the standard definition of differentiability, it is not equivalent thereto – in fact it does not prove any analytic properties at all. To make it equivalent, we need a lower bound on δ: simply δ gives us continuity, and for continuous differentiability, δ must grow at least like √ε for small ε. Neither of these conditions are enforced by the type system, but we do require them for any allowed values because these proofs are obviously tremendously useful – for instance, you can have a root-finding algorithm and actually be sure you get all solutions correctly, not just some that are (hopefully) the closest to some reference point you'd need to laborously define!

Unfortunately however, this also prevents doing any serious algebra with the category, because even something as simple as division necessary introduces singularities where the derivatives must diverge. Not to speak of many e.g. trigonometric functions that are undefined on whole regions. The PWDiffable and RWDiffable categories have explicit handling for those issues built in; you may simply use these categories even when you know the result will be smooth in your relevant domain (or must be, for e.g. physics reasons).

¹(The implementation does not deal with ε and δ as difference-bounding reals, but rather as metric tensors which define a boundary by prohibiting the overlap from exceeding one. This makes the category actually work on general manifolds.)

Region-wise defined diff'able functions

data RWDiffable s d c Source #

Category of functions that, where defined, have an open region in which they are continuously differentiable. Hence RegionWiseDiff'able. Basically these are the partial version of PWDiffable.

Though the possibility of undefined regions is of course not too nice (we don't need Java to demonstrate this with its everywhere-looming null values...), this category will propably be the “workhorse” for most serious calculus applications, because it contains all the usual trig etc. functions and of course everything algebraic you can do in the reals.

The easiest way to define ordinary functions in this category is hence with its AgentValues, which have instances of the standard classes Num through Floating. For instance, the following defines the binary entropy as a differentiable function on the interval ]0,1[: (it will actually know where it's defined and where not. And I don't mean you need to exhaustively isNaN-check all results...)

hb :: RWDiffable ℝ ℝ ℝ
hb = alg (\p -> - p * logBase 2 p - (1-p) * logBase 2 (1-p) )

Instances

type UnitObject (RWDiffable s) # 
type PointObject (RWDiffable s) x # 
type PointObject (RWDiffable s) x = ()
type Object (RWDiffable s) o # 
type PairObjects (RWDiffable s) a b # 
type PairObjects (RWDiffable s) a b = ()
type AgentVal (RWDiffable s) d c # 
type AgentVal (RWDiffable s) d c

Operators for piecewise definition

Because the agents of RWDiffable aren't really values in Hask, you can't use the standard comparison operators on them, nor the built-in syntax of guards or if-statements.

However, because this category allows functions to be undefined in some region, such decisions can be faked quite well: ?-> restricts a function to some region, by simply marking it undefined outside, and ?|: replaces these regions with values from another function.

Example: define a function that is compactly supported on the interval ]-1,1[, i.e. exactly zero everywhere outside.

Graphics.Dynamic.Plot.R2> plotWindow [fnPlot (\x -> -1 ?< x ?< 1 ?-> cos (x*pi/2)^2 ?|: 0)]

Note that it may not be necessary to restrict explicitly: for instance if a square root appears somewhere in an expression, then the expression is automatically restricted so that the root has a positive argument!

Graphics.Dynamic.Plot.R2> plotWindow [fnPlot (\x -> sqrt x ?|: -sqrt (-x))]

(?->) :: (RealDimension n, LocallyScalable n a, LocallyScalable n b, LocallyScalable n c, Manifold b, Manifold c, SimpleSpace (Needle b), SimpleSpace (Needle c)) => RWDfblFuncValue n c a -> RWDfblFuncValue n c b -> RWDfblFuncValue n c b infixr 4 Source #

Require the LHS to be defined before considering the RHS as result. This works analogously to the standard Applicative method

  (*>) :: Maybe a -> Maybe b -> Maybe b
  Just _ *> a = a
  _      *> a = Nothing
  

(?>) :: (RealDimension n, LocallyScalable n a, Manifold a, SimpleSpace (Needle a)) => RWDfblFuncValue n a n -> RWDfblFuncValue n a n -> RWDfblFuncValue n a n infixl 5 Source #

Return the RHS, if it is less than the LHS. (Really the purpose is just to compare the values, but returning one of them allows chaining of comparison operators like in Python.) Note that less-than comparison is equivalent to less-or-equal comparison, because there is no such thing as equality.

(?<) :: (RealDimension n, LocallyScalable n a, Manifold a, SimpleSpace (Needle a)) => RWDfblFuncValue n a n -> RWDfblFuncValue n a n -> RWDfblFuncValue n a n infixl 5 Source #

Return the RHS, if it is greater than the LHS.

(?|:) :: (RealDimension n, LocallyScalable n a, LocallyScalable n b, Manifold a, Manifold b, SimpleSpace (Needle a), SimpleSpace (Needle b)) => RWDfblFuncValue n a b -> RWDfblFuncValue n a b -> RWDfblFuncValue n a b infixl 3 Source #

Try the LHS, if it is undefined use the RHS. This works analogously to the standard Alternative method

  (<|>) :: Maybe a -> Maybe a -> Maybe a
  Just x <|> _ = Just x
  _      <|> a = a
  

Basically a weaker and agent-ised version of backupRegions.

backupRegions :: (RealDimension n, LocallyScalable n a, LocallyScalable n b) => RWDiffable n a b -> RWDiffable n a b -> RWDiffable n a b Source #

Replace the regions in which the first function is undefined with values from the second function.

Regions within a manifold

data Region s m Source #

A pathwise connected subset of a manifold m, whose tangent space has scalar s.

smoothIndicator :: LocallyScalable q => Region q -> Differentiable q Source #

Represent a Region by a smooth function which is positive within the region, and crosses zero at the boundary.

Evaluation of differentiable functions

discretisePathIn Source #

Arguments

:: (WithField Manifold y, SimpleSpace (Needle y)) 
=> Int

Limit the number of steps taken in either direction. Note this will not cap the resolution but length of the discretised path.

-> ℝInterval

Parameter interval of interest.

-> (RieMetric , RieMetric y)

Inaccuracy allowance ε.

-> Differentiable y

Path specification.

-> [(, y)]

Trail of points along the path, such that a linear interpolation deviates nowhere by more as ε.

discretisePathSegs Source #

Arguments

:: (WithField Manifold y, SimpleSpace (Needle y)) 
=> Int

Maximum number of path segments and/or points per segment.

-> (RieMetric , RieMetric y)

Inaccuracy allowance δ for arguments (mostly relevant for resolution of discontinuity boundaries – consider it a “safety margin from singularities”), and ε for results in the target space.

-> RWDiffable y

Path specification. It is recommended that this function be limited to a compact interval (e.g. with ?>, ?< and ?->). For many functions the discretisation will even work on an infinite interval: the point density is exponentially decreased towards the infinities. But this is still pretty bad for performance.

-> ([[(, y)]], [[(, y)]])

Discretised paths: continuous segments in either direction

continuityRanges Source #

Arguments

:: WithField Manifold y 
=> Int

Max number of exploration steps per region

-> RieMetric

Needed resolution of boundaries

-> RWDiffable y

Function to investigate

-> ([ℝInterval], [ℝInterval])

Subintervals on which the function is guaranteed continuous.

analyseLocalBehaviour Source #

Arguments

:: RWDiffable  
->

x₀ value.

-> Maybe ((, ), -> Maybe )

f x₀, derivative (i.e. Taylor-1-coefficient), and reverse propagation of O (δ²) bound.

intervalImages Source #

Arguments

:: Int

Max number of exploration steps per region

-> (RieMetric , RieMetric )

Needed resolution in (x,y) direction

-> RWDiffable

Function to investigate

-> ([(ℝInterval, ℝInterval)], [(ℝInterval, ℝInterval)])

(XInterval, YInterval) rectangles in which the function graph lies.

Orphan instances

RealDimension s => Morphism (RWDiffable s) Source # 

Methods

first :: (ObjectPair (RWDiffable s) b d, ObjectPair (RWDiffable s) c d) => RWDiffable s b c -> RWDiffable s (b, d) (c, d) #

second :: (ObjectPair (RWDiffable s) d b, ObjectPair (RWDiffable s) d c) => RWDiffable s b c -> RWDiffable s (d, b) (d, c) #

(***) :: (ObjectPair (RWDiffable s) b b', ObjectPair (RWDiffable s) c c') => RWDiffable s b c -> RWDiffable s b' c' -> RWDiffable s (b, b') (c, c') #

RealFrac' s => Morphism (Differentiable s) Source # 

Methods

first :: (ObjectPair (Differentiable s) b d, ObjectPair (Differentiable s) c d) => Differentiable s b c -> Differentiable s (b, d) (c, d) #

second :: (ObjectPair (Differentiable s) d b, ObjectPair (Differentiable s) d c) => Differentiable s b c -> Differentiable s (d, b) (d, c) #

(***) :: (ObjectPair (Differentiable s) b b', ObjectPair (Differentiable s) c c') => Differentiable s b c -> Differentiable s b' c' -> Differentiable s (b, b') (c, c') #

RealDimension s => PreArrow (RWDiffable s) Source # 

Methods

(&&&) :: (Object (RWDiffable s) b, ObjectPair (RWDiffable s) c c') => RWDiffable s b c -> RWDiffable s b c' -> RWDiffable s b (c, c') #

terminal :: Object (RWDiffable s) b => RWDiffable s b (UnitObject (RWDiffable s)) #

fst :: ObjectPair (RWDiffable s) x y => RWDiffable s (x, y) x #

snd :: ObjectPair (RWDiffable s) x y => RWDiffable s (x, y) y #

RealFrac' s => PreArrow (Differentiable s) Source # 
RealDimension s => WellPointed (RWDiffable s) Source # 

Associated Types

type PointObject (RWDiffable s :: * -> * -> *) x :: Constraint #

RealFrac' s => WellPointed (Differentiable s) Source # 
RealDimension s => CartesianAgent (RWDiffable s) Source # 

Methods

alg1to2 :: (Object (RWDiffable s) a, ObjectPair (RWDiffable s) b c) => (forall q. Object (RWDiffable s) q => AgentVal (RWDiffable s) q a -> (AgentVal (RWDiffable s) q b, AgentVal (RWDiffable s) q c)) -> RWDiffable s a (b, c) #

alg2to1 :: (ObjectPair (RWDiffable s) a b, Object (RWDiffable s) c) => (forall q. Object (RWDiffable s) q => AgentVal (RWDiffable s) q a -> AgentVal (RWDiffable s) q b -> AgentVal (RWDiffable s) q c) -> RWDiffable s (a, b) c #

alg2to2 :: (ObjectPair (RWDiffable s) a b, ObjectPair (RWDiffable s) c d) => (forall q. Object (RWDiffable s) q => AgentVal (RWDiffable s) q a -> AgentVal (RWDiffable s) q b -> (AgentVal (RWDiffable s) q c, AgentVal (RWDiffable s) q d)) -> RWDiffable s (a, b) (c, d) #

RealFrac' s => CartesianAgent (Differentiable s) Source # 

Methods

alg1to2 :: (Object (Differentiable s) a, ObjectPair (Differentiable s) b c) => (forall q. Object (Differentiable s) q => AgentVal (Differentiable s) q a -> (AgentVal (Differentiable s) q b, AgentVal (Differentiable s) q c)) -> Differentiable s a (b, c) #

alg2to1 :: (ObjectPair (Differentiable s) a b, Object (Differentiable s) c) => (forall q. Object (Differentiable s) q => AgentVal (Differentiable s) q a -> AgentVal (Differentiable s) q b -> AgentVal (Differentiable s) q c) -> Differentiable s (a, b) c #

alg2to2 :: (ObjectPair (Differentiable s) a b, ObjectPair (Differentiable s) c d) => (forall q. Object (Differentiable s) q => AgentVal (Differentiable s) q a -> AgentVal (Differentiable s) q b -> (AgentVal (Differentiable s) q c, AgentVal (Differentiable s) q d)) -> Differentiable s (a, b) (c, d) #

RealDimension s => Category (RWDiffable s) Source # 

Associated Types

type Object (RWDiffable s :: * -> * -> *) o :: Constraint #

Methods

id :: Object (RWDiffable s) a => RWDiffable s a a #

(.) :: (Object (RWDiffable s) a, Object (RWDiffable s) b, Object (RWDiffable s) c) => RWDiffable s b c -> RWDiffable s a b -> RWDiffable s a c #

RealFrac' s => Category (Differentiable s) Source # 

Associated Types

type Object (Differentiable s :: * -> * -> *) o :: Constraint #

RealDimension s => Cartesian (RWDiffable s) Source # 

Associated Types

type PairObjects (RWDiffable s :: * -> * -> *) a b :: Constraint #

type UnitObject (RWDiffable s :: * -> * -> *) :: * #

Methods

swap :: (ObjectPair (RWDiffable s) a b, ObjectPair (RWDiffable s) b a) => RWDiffable s (a, b) (b, a) #

attachUnit :: ((* ~ u) (UnitObject (RWDiffable s)), ObjectPair (RWDiffable s) a u) => RWDiffable s a (a, u) #

detachUnit :: ((* ~ u) (UnitObject (RWDiffable s)), ObjectPair (RWDiffable s) a u) => RWDiffable s (a, u) a #

regroup :: (ObjectPair (RWDiffable s) a b, ObjectPair (RWDiffable s) b c, ObjectPair (RWDiffable s) a (b, c), ObjectPair (RWDiffable s) (a, b) c) => RWDiffable s (a, (b, c)) ((a, b), c) #

regroup' :: (ObjectPair (RWDiffable s) a b, ObjectPair (RWDiffable s) b c, ObjectPair (RWDiffable s) a (b, c), ObjectPair (RWDiffable s) (a, b) c) => RWDiffable s ((a, b), c) (a, (b, c)) #

RealFrac' s => Cartesian (Differentiable s) Source # 

Associated Types

type PairObjects (Differentiable s :: * -> * -> *) a b :: Constraint #

type UnitObject (Differentiable s :: * -> * -> *) :: * #

Methods

swap :: (ObjectPair (Differentiable s) a b, ObjectPair (Differentiable s) b a) => Differentiable s (a, b) (b, a) #

attachUnit :: ((* ~ u) (UnitObject (Differentiable s)), ObjectPair (Differentiable s) a u) => Differentiable s a (a, u) #

detachUnit :: ((* ~ u) (UnitObject (Differentiable s)), ObjectPair (Differentiable s) a u) => Differentiable s (a, u) a #

regroup :: (ObjectPair (Differentiable s) a b, ObjectPair (Differentiable s) b c, ObjectPair (Differentiable s) a (b, c), ObjectPair (Differentiable s) (a, b) c) => Differentiable s (a, (b, c)) ((a, b), c) #

regroup' :: (ObjectPair (Differentiable s) a b, ObjectPair (Differentiable s) b c, ObjectPair (Differentiable s) a (b, c), ObjectPair (Differentiable s) (a, b) c) => Differentiable s ((a, b), c) (a, (b, c)) #

RealDimension s => HasAgent (RWDiffable s) Source # 

Associated Types

type AgentVal (RWDiffable s :: * -> * -> *) a v :: * #

Methods

alg :: (Object (RWDiffable s) a, Object (RWDiffable s) b) => (forall q. Object (RWDiffable s) q => AgentVal (RWDiffable s) q a -> AgentVal (RWDiffable s) q b) -> RWDiffable s a b #

($~) :: (Object (RWDiffable s) a, Object (RWDiffable s) b, Object (RWDiffable s) c) => RWDiffable s b c -> AgentVal (RWDiffable s) a b -> AgentVal (RWDiffable s) a c #

RealFrac' s => HasAgent (Differentiable s) Source # 

Associated Types

type AgentVal (Differentiable s :: * -> * -> *) a v :: * #

RealDimension s => EnhancedCat (RWDiffable s) (Differentiable s) Source # 

Methods

arr :: (Object (Differentiable s) b, Object (Differentiable s) c, Object (RWDiffable s) b, Object (RWDiffable s) c) => Differentiable s b c -> RWDiffable s b c #

RealDimension s => EnhancedCat ((->) LiftedRep LiftedRep) (Differentiable s) Source #