-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | An experimental alternative hierarchy of numeric type classes -- -- Revisiting the Numeric Classes -- -- The Prelude for Haskell 98 offers a well-considered set of numeric -- classes which covers the standard numeric types (Integer, -- Int, Rational, Float, Double, -- Complex) quite well. But they offer limited extensibility and -- have a few other flaws. In this proposal we will revisit these -- classes, addressing the following concerns: -- -- -- -- In specifying the semantics of type classes, I will state laws as -- follows: -- --
--   (a + b) + c === a + (b + c)
--   
-- -- The intended meaning is extensional equality: The rest of the program -- should behave in the same way if one side is replaced with the other. -- Unfortunately, the laws are frequently violated by standard instances; -- the law above, for instance, fails for Float: -- --
--   (1e20 + (-1e20)) + 1.0  = 1.0
--    1e20 + ((-1e20) + 1.0) = 0.0
--   
-- -- For inexact number types like floating point types, thus these laws -- should be interpreted as guidelines rather than absolute rules. In -- particular, the compiler is not allowed to use them for optimization. -- Unless stated otherwise, default definitions should also be taken as -- laws. -- -- Thanks to Brian Boutel, Joe English, William Lee Irwin II, Marcin -- Kowalczyk, Ketil Malde, Tom Schrijvers, Ken Shan, and Henning -- Thielemann for helpful comments. -- -- Usage: -- -- Write modules in the following style: -- --
--   [-# NoImplicitPrelude #-]
--   module MyModule where
--   
--   ... various specific imports ...
--   
--   import NumericPrelude
--   
-- -- Importing NumericPrelude is almost the same as -- --
--   import NumericPrelude.Numeric
--   import NumericPrelude.Base   .
--   
-- -- Instead of the NoImplicitPrelude pragma you could also write -- import Prelude () but this will yield problems with numeric -- literals. -- -- Scope & Limitations/TODO: -- -- -- -- Additional standard libraries might include Enum, IEEEFloat (including -- the bulk of the functions in Haskell 98's RealFloat class), -- VectorSpace, Ratio, and Lattice. @package numeric-prelude @version 0.2 -- | An alternative type class for Ord which allows an ordering for -- dictionaries like Data.Map and Data.Set independently -- from the ordering with respect to a magnitude. module Algebra.Indexable -- | Definition of an alternative ordering of objects independent from a -- notion of magnitude. For an application see -- MathObj.PartialFraction. class (Eq a) => C a compare :: (C a) => a -> a -> Ordering -- | If the type has already an Ord instance it is certainly the -- most easiest to define compare to be equal to Ord's -- compare. ordCompare :: (Ord a) => a -> a -> Ordering -- | Lift compare implementation from a wrapped object. liftCompare :: (C b) => (a -> b) -> a -> a -> Ordering -- | Wrap an indexable object such that it can be used in Data.Map -- and Data.Set. data ToOrd a toOrd :: a -> ToOrd a fromOrd :: ToOrd a -> a instance (Eq a) => Eq (ToOrd a) instance (Show a) => Show (ToOrd a) instance (C a) => Ord (ToOrd a) instance C Integer instance (C a) => C [a] instance (C a, C b) => C (a, b) -- | We already have the dynamically checked physical units provided by -- Number.Physical and the statically checked ones of the -- dimensional package of Buckwalter, which require -- multi-parameter type classes with functional dependencies. -- -- Here we provide a poor man's approach: The units are presented by type -- terms. There is no canonical form and thus the type checker can not -- automatically check for equal units. However, if two unit terms -- represent the same unit, then you can tell the type checker to rewrite -- one into the other. -- -- You can add more dimensions by introducing more types of class -- C. -- -- This approach is not entirely safe because you can write your own -- flawed rewrite rules. It is however more safe than with no units at -- all. module Algebra.DimensionTerm class (Show a) => C a noValue :: (C a) => a data Scalar Scalar :: Scalar data Mul a b Mul :: Mul a b data Recip a Recip :: Recip a type Sqr a = Mul a a appPrec :: Int scalar :: Scalar mul :: (C a, C b) => a -> b -> Mul a b recip :: (C a) => a -> Recip a (%*%) :: (C a, C b) => a -> b -> Mul a b (%/%) :: (C a, C b) => a -> b -> Mul a (Recip b) applyLeftMul :: (C u0, C u1, C v) => (u0 -> u1) -> Mul u0 v -> Mul u1 v applyRightMul :: (C u0, C u1, C v) => (u0 -> u1) -> Mul v u0 -> Mul v u1 applyRecip :: (C u0, C u1) => (u0 -> u1) -> Recip u0 -> Recip u1 commute :: (C u0, C u1) => Mul u0 u1 -> Mul u1 u0 associateLeft :: (C u0, C u1, C u2) => Mul u0 (Mul u1 u2) -> Mul (Mul u0 u1) u2 associateRight :: (C u0, C u1, C u2) => Mul (Mul u0 u1) u2 -> Mul u0 (Mul u1 u2) recipMul :: (C u0, C u1) => Recip (Mul u0 u1) -> Mul (Recip u0) (Recip u1) mulRecip :: (C u0, C u1) => Mul (Recip u0) (Recip u1) -> Recip (Mul u0 u1) identityLeft :: (C u) => Mul Scalar u -> u identityRight :: (C u) => Mul u Scalar -> u cancelLeft :: (C u) => Mul (Recip u) u -> Scalar cancelRight :: (C u) => Mul u (Recip u) -> Scalar invertRecip :: (C u) => Recip (Recip u) -> u doubleRecip :: (C u) => u -> Recip (Recip u) recipScalar :: Recip Scalar -> Scalar -- | This class allows defining instances that are exclusively for -- Scalar dimension. You won't want to define instances by -- yourself. class (C dim) => IsScalar dim toScalar :: (IsScalar dim) => dim -> Scalar fromScalar :: (IsScalar dim) => Scalar -> dim data Length Length :: Length data Time Time :: Time data Mass Mass :: Mass data Charge Charge :: Charge data Angle Angle :: Angle data Temperature Temperature :: Temperature data Information Information :: Information length :: Length time :: Time mass :: Mass charge :: Charge angle :: Angle temperature :: Temperature information :: Information type Frequency = Recip Time frequency :: Frequency data Voltage Voltage :: Voltage type VoltageAnalytical = Mul (Mul (Sqr Length) Mass) (Recip (Mul (Sqr Time) Charge)) voltage :: Voltage unpackVoltage :: Voltage -> VoltageAnalytical packVoltage :: VoltageAnalytical -> Voltage instance C Voltage instance Show Voltage instance C Information instance C Temperature instance C Angle instance C Charge instance C Mass instance C Time instance C Length instance Show Information instance Show Temperature instance Show Angle instance Show Charge instance Show Mass instance Show Time instance Show Length instance IsScalar Scalar instance (C a) => C (Recip a) instance (C a, C b) => C (Mul a b) instance C Scalar instance (Show a) => Show (Recip a) instance (Show a, Show b) => Show (Mul a b) instance Show Scalar module NumericPrelude.Elementwise -- | A reader monad for the special purpose of defining instances of -- certain operations on tuples and records. It does not add any new -- functionality to the common Reader monad, but it restricts the -- functions to the required ones and exports them from one module. That -- is you do not have to import both Control.Monad.Trans.Reader and -- Control.Applicative. The type also tells the user, for what the Reader -- monad is used. We can more easily replace or extend the implementation -- when needed. newtype T v a Cons :: (v -> a) -> T v a run :: T v a -> v -> a with :: a -> T v a element :: (v -> a) -> T v a run2 :: T (x, y) a -> x -> y -> a run3 :: T (x, y, z) a -> x -> y -> z -> a run4 :: T (x, y, z, w) a -> x -> y -> z -> w -> a run5 :: T (x, y, z, u, w) a -> x -> y -> z -> u -> w -> a instance Applicative (T v) instance Functor (T v) -- | Define common properties that can be used e.g. for automated tests. -- Cf. to Test.QuickCheck.Utils. module Algebra.Laws commutative :: (Eq a) => (b -> b -> a) -> b -> b -> Bool associative :: (Eq a) => (a -> a -> a) -> a -> a -> a -> Bool leftIdentity :: (Eq a) => (b -> a -> a) -> b -> a -> Bool rightIdentity :: (Eq a) => (a -> b -> a) -> b -> a -> Bool identity :: (Eq a) => (a -> a -> a) -> a -> a -> Bool leftZero :: (Eq a) => (a -> a -> a) -> a -> a -> Bool rightZero :: (Eq a) => (a -> a -> a) -> a -> a -> Bool zero :: (Eq a) => (a -> a -> a) -> a -> a -> Bool leftInverse :: (Eq a) => (b -> b -> a) -> (b -> b) -> a -> b -> Bool rightInverse :: (Eq a) => (b -> b -> a) -> (b -> b) -> a -> b -> Bool inverse :: (Eq a) => (b -> b -> a) -> (b -> b) -> a -> b -> Bool leftDistributive :: (Eq a) => (a -> b -> a) -> (a -> a -> a) -> b -> a -> a -> Bool rightDistributive :: (Eq a) => (b -> a -> a) -> (a -> a -> a) -> b -> a -> a -> Bool homomorphism :: (Eq a) => (b -> a) -> (b -> b -> b) -> (a -> a -> a) -> b -> b -> Bool rightCascade :: (Eq a) => (b -> b -> b) -> (a -> b -> a) -> a -> b -> b -> Bool leftCascade :: (Eq a) => (b -> b -> b) -> (b -> a -> a) -> a -> b -> b -> Bool -- | The only point of this module is to reexport items that we want from -- the standard Prelude. module NumericPrelude.Base -- | module MathObj.Permutation -- | There are quite a few way we could represent elements of permutation -- groups: the images in a row, a list of the cycles, et.c. All of these -- differ highly in how complex various operations end up being. class C p domain :: (C p, Ix i) => p i -> (i, i) apply :: (C p, Ix i) => p i -> i -> i inverse :: (C p, Ix i) => p i -> p i module MathObj.Permutation.Table type T i = Array i i fromFunction :: (Ix i) => (i, i) -> (i -> i) -> T i toFunction :: (Ix i) => T i -> (i -> i) fromPermutation :: (Ix i, C p) => p i -> T i fromCycles :: (Ix i) => (i, i) -> [[i]] -> T i identity :: (Ix i) => (i, i) -> T i cycle :: (Ix i) => [i] -> T i -> T i inverse :: (Ix i) => T i -> T i compose :: (Ix i) => T i -> T i -> T i -- | Extremely nave algorithm to generate a list of all elements in a -- group. Should be replaced by a Schreier-Sims system if this code is -- ever used for anything bigger than .. say .. groups of order 512 or -- so. choose :: Set a -> Maybe (a, Set a) closure :: (Ix i) => [T i] -> [T i] closureSlow :: (Ix i) => [T i] -> [T i] module Algebra.Additive -- | Additive a encapsulates the notion of a commutative group, specified -- by the following laws: -- --
--          a + b === b + a
--    (a + b) + c === a + (b + c)
--       zero + a === a
--   a + negate a === 0
--   
-- -- Typical examples include integers, dollars, and vectors. -- -- Minimal definition: +, zero, and (negate or -- '(-)') class C a zero :: (C a) => a (+) :: (C a) => a -> a -> a (-) :: (C a) => a -> a -> a negate :: (C a) => a -> a -- | subtract is (-) with swapped operand order. This is -- the operand order which will be needed in most cases of partial -- application. subtract :: (C a) => a -> a -> a -- | Sum up all elements of a list. An empty list yields zero. -- -- This function is inappropriate for number types like Peano. Maybe we -- should make sum a method of Additive. This would also make -- lengthLeft and lengthRight superfluous. sum :: (C a) => [a] -> a -- | Sum up all elements of a non-empty list. This avoids including a zero -- which is useful for types where no universal zero is available. sum1 :: (C a) => [a] -> a -- | Instead of baking the add operation into the element function, we -- could use higher rank types and pass a generic uncurry (+) to -- the run function. We do not do so in order to stay Haskell 98 at least -- for parts of NumericPrelude. elementAdd :: (C x) => (v -> x) -> T (v, v) x elementSub :: (C x) => (v -> x) -> T (v, v) x elementNeg :: (C x) => (v -> x) -> T v x -- |
--   addPair :: (Additive.C a, Additive.C b) => (a,b) -> (a,b) -> (a,b)
--   addPair = Elem.run2 $ Elem.with (,) <*>.+  fst <*>.+  snd
--   
(<*>.+) :: (C x) => T (v, v) (x -> a) -> (v -> x) -> T (v, v) a (<*>.-) :: (C x) => T (v, v) (x -> a) -> (v -> x) -> T (v, v) a (<*>.-$) :: (C x) => T v (x -> a) -> (v -> x) -> T v a propAssociative :: (Eq a, C a) => a -> a -> a -> Bool propCommutative :: (Eq a, C a) => a -> a -> Bool propIdentity :: (Eq a, C a) => a -> Bool propInverse :: (Eq a, C a) => a -> Bool instance (Integral a) => C (Ratio a) instance (C v) => C (b -> v) instance (C v) => C [v] instance (C v0, C v1, C v2) => C (v0, v1, v2) instance (C v0, C v1) => C (v0, v1) instance C Word64 instance C Word32 instance C Word16 instance C Word8 instance C Word instance C Int64 instance C Int32 instance C Int16 instance C Int8 instance C Int instance C Double instance C Float instance C Integer module Algebra.ZeroTestable -- | Maybe the naming should be according to Algebra.Unit: Algebra.Zero as -- module name, and query as method name. class C a isZero :: (C a) => a -> Bool -- | Checks if a number is the zero element. This test is not possible for -- all C types, since e.g. a function type does not belong to Eq. -- isZero is possible for some types where (==zero) fails because there -- is no unique zero. Examples are vector (the length of the zero vector -- is unknown), physical values (the unit of a zero quantity is unknown), -- residue class (the modulus is unknown). defltIsZero :: (Eq a, C a) => a -> Bool instance (C v) => C [v] instance (C v0, C v1, C v2) => C (v0, v1, v2) instance (C v0, C v1) => C (v0, v1) instance C Word64 instance C Word32 instance C Word16 instance C Word8 instance C Word instance C Int64 instance C Int32 instance C Int16 instance C Int8 instance C Int instance C Double instance C Float instance C Integer module Algebra.Ring -- | Ring encapsulates the mathematical structure of a (not necessarily -- commutative) ring, with the laws -- --
--   a * (b * c) === (a * b) * c
--       one * a === a
--       a * one === a
--   a * (b + c) === a * b + a * c
--   
-- -- Typical examples include integers, polynomials, matrices, and -- quaternions. -- -- Minimal definition: *, (one or fromInteger) class (C a) => C a (*) :: (C a) => a -> a -> a one :: (C a) => a fromInteger :: (C a) => Integer -> a (^) :: (C a) => a -> Integer -> a sqr :: (C a) => a -> a product :: (C a) => [a] -> a product1 :: (C a) => [a] -> a scalarProduct :: (C a) => [a] -> [a] -> a propAssociative :: (Eq a, C a) => a -> a -> a -> Bool propLeftDistributive :: (Eq a, C a) => a -> a -> a -> Bool propRightDistributive :: (Eq a, C a) => a -> a -> a -> Bool propLeftIdentity :: (Eq a, C a) => a -> Bool propRightIdentity :: (Eq a, C a) => a -> Bool propPowerCascade :: (Eq a, C a) => a -> Integer -> Integer -> Property propPowerProduct :: (Eq a, C a) => a -> Integer -> Integer -> Property propPowerDistributive :: (Eq a, C a) => Integer -> a -> a -> Property -- | Commutativity need not be satisfied by all instances of C. propCommutative :: (Eq a, C a) => a -> a -> Bool instance (Integral a) => C (Ratio a) instance C Word64 instance C Word32 instance C Word16 instance C Word8 instance C Word instance C Int64 instance C Int32 instance C Int16 instance C Int8 instance C Int instance C Double instance C Float instance C Integer module Algebra.Differential -- | differentiate is a general differentation operation It must -- fulfill the Leibnitz condition -- --
--   differentiate (x * y) == differentiate x * y + x * differentiate y
--   
-- -- Unfortunately, this scheme cannot be easily extended to more than two -- variables, e.g. MathObj.PowerSeries2. class (C a) => C a differentiate :: (C a) => a -> a module Algebra.IntegralDomain -- | IntegralDomain corresponds to a commutative ring, where a -- mod b picks a canonical element of the equivalence class -- of a in the ideal generated by b. div and -- mod satisfy the laws -- --
--                           a * b === b * a
--   (a `div` b) * b + (a `mod` b) === a
--                 (a+k*b) `mod` b === a `mod` b
--                       0 `mod` b === 0
--   
-- -- Typical examples of IntegralDomain include integers and -- polynomials over a field. Note that for a field, there is a canonical -- instance defined by the above rules; e.g., -- --
--   instance IntegralDomain.C Rational where
--       divMod a b =
--          if isZero b
--            then (undefined,a)
--            else (a\/b,0)
--   
-- -- It shall be noted, that div, mod, divMod have a -- parameter order which is unfortunate for partial application. But it -- is adapted to mathematical conventions, where the operators are used -- in infix notation. -- -- Minimal definition: divMod or (div and mod) class (C a) => C a div :: (C a) => a -> a -> a mod :: (C a) => a -> a -> a divMod :: (C a) => a -> a -> (a, a) -- | Allows division by zero. If the divisor is zero, then the divident is -- returned as remainder. divModZero :: (C a, C a) => a -> a -> (a, a) divides :: (C a, C a) => a -> a -> Bool sameResidueClass :: (C a, C a) => a -> a -> a -> Bool -- | Returns the result of the division, if divisible. Otherwise undefined. safeDiv :: (C a, C a) => a -> a -> a even :: (C a, C a) => a -> Bool odd :: (C a, C a) => a -> Bool -- | decomposeVarPositional [b0,b1,b2,...] x decomposes x -- into a positional representation with mixed bases x0 + b0*(x1 + -- b1*(x2 + b2*x3)) E.g. decomposeVarPositional (repeat 10) 123 -- == [3,2,1] decomposeVarPositional :: (C a, C a) => [a] -> a -> [a] decomposeVarPositionalInf :: (C a) => [a] -> a -> [a] propInverse :: (Eq a, C a, C a) => a -> a -> Property propMultipleDiv :: (Eq a, C a, C a) => a -> a -> Property propMultipleMod :: (Eq a, C a, C a) => a -> a -> Property propProjectAddition :: (Eq a, C a, C a) => a -> a -> a -> Property propProjectMultiplication :: (Eq a, C a, C a) => a -> a -> a -> Property propUniqueRepresentative :: (Eq a, C a, C a) => a -> a -> a -> Property propZeroRepresentative :: (Eq a, C a, C a) => a -> Property propSameResidueClass :: (Eq a, C a, C a) => a -> a -> a -> Property instance C Word64 instance C Word32 instance C Word16 instance C Word8 instance C Word instance C Int64 instance C Int32 instance C Int16 instance C Int8 instance C Int instance C Integer -- | Will be used in order to generate type classes for generic algebras. -- An algebra is a vector space that also is a monoid. Should we use the -- Monoid class from base library despite its unfortunate method name -- mappend? module Algebra.Monoid -- | We expect a monoid to adher to associativity and the identity behaving -- decently. Nothing more, really. class C a idt :: (C a) => a (<*>) :: (C a) => a -> a -> a cumulate :: (C a) => [a] -> a instance (C a) => C (Sum a) instance (C a) => C (Product a) instance C (Last a) instance C (First a) instance C (Endo a) instance (C a) => C (Dual a) instance C Any instance C All -- | A type class for non-negative numbers. Prominent instances are -- Number.NonNegative.T and Number.Peano.T numbers. -- This class cannot do any checks, but it let you show to the user what -- arguments your function expects. Thus you must define class instances -- with care. In fact many standard functions (take, '(!!)', ...) -- should have this type class constraint. module Algebra.NonNegative -- | Instances of this class must ensure non-negative values. We cannot -- enforce this by types, but the type class constraint -- NonNegative.C avoids accidental usage of types which allow -- for negative numbers. -- -- The Monoid superclass contributes a zero and an addition. class (Ord a, C a) => C a split :: (C a) => a -> a -> (a, (Bool, a)) -- | Default implementation for wrapped types of Ord and Num -- class. splitDefault :: (Ord b, C b) => (a -> b) -> (b -> a) -> a -> a -> (a, (Bool, a)) -- |
--   x -| y == max 0 (x-y)
--   
-- -- The default implementation is not efficient, because it compares the -- values and then subtracts, again, if safe. max 0 (x-y) is -- more elegant and efficient but not possible in the general case, since -- x-y may already yield a negative number. (-|) :: (C a) => a -> a -> a zero :: (C a) => a add :: (C a) => a -> a -> a sum :: (C a) => [a] -> a module Algebra.Units -- | This class lets us deal with the units in a ring. isUnit tells -- whether an element is a unit. The other operations let us canonically -- write an element as a unit times another element. Two elements a, b of -- a ring R are _associates_ if a=b*u for a unit u. For an element a, we -- want to write it as a=b*u where b is an associate of a. The map -- (a->b) is called StandardAssociate by Gap, -- unitCanonical by Axiom, and canAssoc by DoCon. The map -- (a->u) is called canInv by DoCon and -- unitNormal(x).unit by Axiom. -- -- The laws are -- --
--    stdAssociate x * stdUnit x === x
--      stdUnit x * stdUnitInv x === 1
--   isUnit u ==> stdAssociate x === stdAssociate (x*u)
--   
-- -- Currently some algorithms assume -- --
--   stdAssociate(x*y) === stdAssociate x * stdAssociate y
--   
-- -- Minimal definition: isUnit and (stdUnit or -- stdUnitInv) and optionally stdAssociate class (C a) => C a isUnit :: (C a) => a -> Bool stdAssociate :: (C a) => a -> a stdUnitInv :: (C a) => a -> a stdUnit :: (C a) => a -> a intQuery :: (Integral a, C a) => a -> Bool intAssociate :: (Integral a, C a, C a) => a -> a intStandard :: (Integral a, C a, C a) => a -> a intStandardInverse :: (Integral a, C a, C a) => a -> a propComposition :: (Eq a, C a) => a -> Bool propInverseUnit :: (Eq a, C a) => a -> Bool propUniqueAssociate :: (Eq a, C a) => a -> a -> Property propAssociateProduct :: (Eq a, C a) => a -> a -> Bool instance C Int64 instance C Int32 instance C Int16 instance C Int8 instance C Integer instance C Int module Algebra.PrincipalIdealDomain -- | A principal ideal domain is a ring in which every ideal (the set of -- multiples of some generating set of elements) is principal: That is, -- every element can be written as the multiple of some generating -- element. gcd a b gives a generator for the ideal generated by -- a and b. The algorithm above works whenever mod -- x y is smaller (in a suitable sense) than both x and -- y; otherwise the algorithm may run forever. -- -- Laws: -- --
--   divides x (lcm x y)
--   x `gcd` (y `gcd` z) == (x `gcd` y) `gcd` z
--   gcd x y * z == gcd (x*z) (y*z)
--   gcd x y * lcm x y == x * y
--   
-- -- (etc: canonical) -- -- Minimal definition: * nothing, if the standard Euclidean algorithm -- work * if extendedGCD is implemented customly, gcd and -- lcm make use of it class (C a, C a) => C a extendedGCD :: (C a) => a -> a -> (a, (a, a)) gcd :: (C a) => a -> a -> a lcm :: (C a) => a -> a -> a euclid :: (C a, C a) => (a -> a -> a) -> a -> a -> a extendedEuclid :: (C a, C a) => (a -> a -> (a, a)) -> a -> a -> (a, (a, a)) -- | Compute the greatest common divisor for multiple numbers by repeated -- application of the two-operand-gcd. extendedGCDMulti :: (C a) => [a] -> (a, [a]) -- | A variant with small coefficients. -- -- Just (a,b) = diophantine z x y means a*x+b*y = z. It -- is required that gcd(y,z) divides x. diophantine :: (C a) => a -> a -> a -> Maybe (a, a) -- | Like diophantine, but a is minimal with respect to the -- measure function of the Euclidean algorithm. diophantineMin :: (C a) => a -> a -> a -> Maybe (a, a) diophantineMulti :: (C a) => a -> [a] -> Maybe [a] -- | Not efficient enough, because GCD/LCM is computed twice. chineseRemainder :: (C a) => (a, a) -> (a, a) -> Maybe (a, a) -- | For Just (b,n) = chineseRemainder [(a0,m0), (a1,m1), ..., -- (an,mn)] and all x with x = b mod n the -- congruences x=a0 mod m0, x=a1 mod m1, ..., x=an mod mn are -- fulfilled. chineseRemainderMulti :: (C a) => [(a, a)] -> Maybe (a, a) propMaximalDivisor :: (C a) => a -> a -> a -> Property propGCDDiophantine :: (Eq a, C a) => a -> a -> Bool propExtendedGCDMulti :: (Eq a, C a) => [a] -> Bool propDiophantine :: (Eq a, C a) => a -> a -> a -> a -> Bool propDiophantineMin :: (Eq a, C a) => a -> a -> a -> a -> Bool propDiophantineMulti :: (Eq a, C a) => [(a, a)] -> Bool propDiophantineMultiMin :: (Eq a, C a) => [(a, a)] -> Bool propChineseRemainder :: (Eq a, C a) => a -> a -> [a] -> Property propDivisibleGCD :: (C a) => a -> a -> Bool propDivisibleLCM :: (C a) => a -> a -> Bool propGCDIdentity :: (Eq a, C a) => a -> Bool propGCDCommutative :: (Eq a, C a) => a -> a -> Bool propGCDAssociative :: (Eq a, C a) => a -> a -> a -> Bool propGCDHomogeneous :: (Eq a, C a) => a -> a -> a -> Bool propGCD_LCM :: (Eq a, C a) => a -> a -> Bool instance C Int64 instance C Int32 instance C Int16 instance C Int8 instance C Int instance C Integer module MathObj.Monoid -- | It is only a monoid for non-negative numbers. -- --
--   idt <*> GCD (-2) = GCD 2
--   
-- -- Thus, use this Monoid only for non-negative numbers! newtype GCD a GCD :: a -> GCD a runGCD :: GCD a -> a newtype LCM a LCM :: a -> LCM a runLCM :: LCM a -> a -- | Nothing is the largest element. newtype Min a Min :: Maybe a -> Min a runMin :: Min a -> Maybe a -- | Nothing is the smallest element. newtype Max a Max :: Maybe a -> Max a runMax :: Max a -> Maybe a instance (Show a) => Show (Max a) instance (Eq a) => Eq (Max a) instance (Show a) => Show (Min a) instance (Eq a) => Eq (Min a) instance (Show a) => Show (LCM a) instance (Eq a) => Eq (LCM a) instance (Show a) => Show (GCD a) instance (Eq a) => Eq (GCD a) instance (Ord a) => C (Max a) instance (Ord a) => C (Min a) instance (C a) => C (LCM a) instance (C a) => C (GCD a) module Algebra.RightModule class (C a, C b) => C a b (<*) :: (C a b) => b -> a -> b -- | Abstraction of vectors module Algebra.Vector -- | A Module over a ring satisfies: -- --
--   a *> (b + c) === a *> b + a *> c
--   (a * b) *> c === a *> (b *> c)
--   (a + b) *> c === a *> c + b *> c
--   
class C v zero :: (C v, C a) => v a (<+>) :: (C v, C a) => v a -> v a -> v a (*>) :: (C v, C a) => a -> v a -> v a -- | We need a Haskell 98 type class which provides equality test for -- Vector type constructors. class Eq v eq :: (Eq v, Eq a) => v a -> v a -> Bool functorScale :: (Functor v, C a) => a -> v a -> v a -- | Compute the linear combination of a list of vectors. linearComb :: (C a, C v) => [a] -> [v a] -> v a propCascade :: (C v, Eq v, C a, Eq a) => a -> a -> v a -> Bool propRightDistributive :: (C v, Eq v, C a, Eq a) => a -> v a -> v a -> Bool propLeftDistributive :: (C v, Eq v, C a, Eq a) => a -> a -> v a -> Bool instance Eq [] instance C ((->) b) instance C [] -- | The generic case of a k-algebra generated by a monoid. module MathObj.Algebra newtype T a b Cons :: (Map a b) -> T a b zipWith :: (Ord a) => (b -> b -> b) -> (T a b -> T a b -> T a b) mulMonomial :: (C a, C b) => (a, b) -> (a, b) -> (a, b) monomial :: a -> b -> (T a b) instance (Eq a, Eq b) => Eq (T a b) instance (Show a, Show b) => Show (T a b) instance (Ord a, C a, C b) => C (T a b) instance (Ord a) => C (T a) instance (Ord a, C b) => C (T a b) instance Functor (T a) module Algebra.Absolute -- | This is the type class of a ring with a notion of an absolute value, -- satisfying the laws -- --
--                        a * b === b * a
--   a /= 0  =>  abs (signum a) === 1
--             abs a * signum a === a
--   
-- -- Minimal definition: abs, signum. -- -- If the type is in the Ord class we expect abs = -- absOrd and signum = signumOrd and we expect the -- following laws to hold: -- --
--      a + (max b c) === max (a+b) (a+c)
--   negate (max b c) === min (negate b) (negate c)
--      a * (max b c) === max (a*b) (a*c) where a >= 0
--           absOrd a === max a (-a)
--   
-- -- We do not require Ord as superclass since we also want to have -- Number.Complex as instance. abs for complex numbers -- alone may have an inappropriate type, because it does not reflect that -- the absolute value is a real number. You might prefer -- Number.Complex.magnitude. This type class is intended for -- unifying algorithms that work for both real and complex numbers. Note -- the similarity to Algebra.Units: abs plays the role of -- stdAssociate and signum plays the role of -- stdUnit. -- -- Actually, since abs can be defined using max and -- negate we could relax the superclasses to Additive and -- Ord if his class would only contain signum. class (C a, C a) => C a abs :: (C a) => a -> a signum :: (C a) => a -> a absOrd :: (C a, Ord a) => a -> a signumOrd :: (C a, Ord a) => a -> a instance C Word64 instance C Word32 instance C Word16 instance C Word8 instance C Word instance C Int64 instance C Int32 instance C Int16 instance C Int8 instance C Int instance C Double instance C Float instance C Integer -- | Ratios of mathematical objects. module Number.Ratio data T a (:%) :: !a -> !a -> T a numerator :: T a -> !a denominator :: T a -> !a (%) :: (C a) => a -> a -> T a type Rational = T Integer fromValue :: (C a) => a -> T a scale :: (C a) => a -> T a -> T a -- | similar to Algebra.RealRing.splitFraction split :: (C a) => T a -> (a, T a) -- | This is an alternative show method that is more user-friendly but also -- potentially more ambigious. showsPrecAuto :: (Eq a, C a, Show a) => Int -> T a -> String -> String -- | Necessary when mixing NumericPrelude.Numeric Rationals with Prelude98 -- Rationals toRational98 :: (Integral a, C a) => T a -> Ratio a instance (Eq a) => Eq (T a) instance (Num a, C a, C a) => Fractional (T a) instance (Num a, C a, C a) => Num (T a) instance (Random a, C a, C a) => Random (T a) instance (Storable a, C a) => Storable (T a) instance (Arbitrary a, C a, C a) => Arbitrary (T a) instance (Show a, C a) => Show (T a) instance (Read a, C a) => Read (T a) instance (C a, C a) => C (T a) instance (Ord a, C a) => C (T a) instance (Ord a, C a) => Ord (T a) instance (C a, C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) module Algebra.Field -- | Field again corresponds to a commutative ring. Division is partially -- defined and satisfies -- --
--   not (isZero b)  ==>  (a * b) / b === a
--   not (isZero a)  ==>  a * recip a === one
--   
-- -- when it is defined. To safely call division, the program must take -- type-specific action; e.g., the following is appropriate in many -- cases: -- --
--   safeRecip :: (Integral a, Eq a, Field.C a) => a -> Maybe a
--   safeRecip x =
--       let (q,r) = one `divMod` x
--       in  toMaybe (isZero r) q
--   
-- -- Typical examples include rationals, the real numbers, and rational -- functions (ratios of polynomial functions). An instance should be -- typically declared only if most elements are invertible. -- -- Actually, we have also used this type class for non-fields containing -- lots of units, e.g. residue classes with respect to non-primes and -- power series. So the restriction not (isZero a) must be -- better isUnit a. -- -- Minimal definition: recip or (/) class (C a) => C a (/) :: (C a) => a -> a -> a recip :: (C a) => a -> a fromRational' :: (C a) => Rational -> a (^-) :: (C a) => a -> Integer -> a -- | Needed to work around shortcomings in GHC. fromRational :: (C a) => Rational -> a -- | the restriction on the divisor should be isUnit a instead of -- not (isZero a) propDivision :: (Eq a, C a, C a) => a -> a -> Property propReciprocal :: (Eq a, C a, C a) => a -> Property instance (Integral a) => C (Ratio a) instance (C a) => C (T a) instance C Double instance C Float module Algebra.ToRational -- | This class allows lossless conversion from any representation of a -- rational to the fixed Rational type. "Lossless" means - don't -- do any rounding. For rounding see Algebra.RealRing. With the -- instances for Float and Double we acknowledge that these -- types actually represent rationals rather than (approximated) real -- numbers. However, this contradicts to the -- Algebra.Transcendental class. -- -- Laws that must be satisfied by instances: -- --
--   fromRational' . toRational === id
--   
class (C a) => C a toRational :: (C a) => a -> Rational -- | It should hold -- --
--   realToField = fromRational' . toRational
--   
-- -- but it should be much more efficient for particular pairs of types, -- such as converting Float to Double. This achieved by -- optimizer rules. realToField :: (C a, C b) => a -> b instance C Word64 instance C Word32 instance C Word16 instance C Word8 instance C Word instance C Int64 instance C Int32 instance C Int16 instance C Int8 instance C Int instance C Double instance C Float instance C Integer -- | Generally before using quot and rem, think twice. In -- most cases divMod and friends are the right choice, because -- they fulfill more of the wanted properties. On some systems -- quot and rem are more efficient and if you only use -- positive numbers, you may be happy with them. But we cannot warrant -- the efficiency advantage. -- -- See also: Daan Leijen: Division and Modulus for Computer Scientists -- http://www.cs.uu.nl/%7Edaan/download/papers/divmodnote-letter.pdf, -- http://www.haskell.org/pipermail/haskell-cafe/2007-August/030394.html module Algebra.RealIntegral -- | Remember that divMod does not specify exactly what a -- quot b should be, mainly because there is no sensible way -- to define it in general. For an instance of Algebra.RealIntegral.C -- a, it is expected that a quot b will round -- towards 0 and a Prelude.div b will round towards -- minus infinity. -- -- Minimal definition: nothing required class (C a, Ord a, C a) => C a quot :: (C a) => a -> a -> a rem :: (C a) => a -> a -> a quotRem :: (C a) => a -> a -> (a, a) instance C Word64 instance C Word32 instance C Word16 instance C Word8 instance C Word instance C Int64 instance C Int32 instance C Int16 instance C Int8 instance C Int instance C Integer module Algebra.ToInteger -- | The two classes C and Algebra.ToRational.C exist to -- allow convenient conversions, primarily between the built-in types. -- They should satisfy -- --
--   fromInteger .  toInteger === id
--    toRational .  toInteger === toRational
--   
-- -- Conversions must be lossless, that is, they do not round in any way. -- For rounding see Algebra.RealRing. With the instances for -- Float and Double we acknowledge that these types -- actually represent rationals rather than (approximated) real numbers. -- However, this contradicts to the Algebra.Transcendental.C -- instance. class (C a, C a) => C a toInteger :: (C a) => a -> Integer fromIntegral :: (C a, C b) => a -> b -- | A prefix function of '(Algebra.Ring.^)' with a parameter order that -- fits the needs of partial application and function composition. It has -- generalised exponent. -- -- See: Argument order of expNat on -- http://www.haskell.org/pipermail/haskell-cafe/2006-September/018022.html ringPower :: (C a, C b) => b -> a -> a -- | A prefix function of '(Algebra.Field.^-)'. It has a generalised -- exponent. fieldPower :: (C a, C b) => b -> a -> a instance (C a, C a) => C (T a) instance C Word64 instance C Word32 instance C Word16 instance C Word8 instance C Word instance C Int64 instance C Int32 instance C Int16 instance C Int8 instance C Int instance C Integer module Algebra.Algebraic -- | Minimal implementation: root or '(^/)'. class (C a) => C a sqrt :: (C a) => a -> a root :: (C a) => Integer -> a -> a (^/) :: (C a) => a -> Rational -> a genericRoot :: (C a, C b) => b -> a -> a power :: (C a, C b) => b -> a -> a propSqrSqrt :: (Eq a, C a) => a -> Bool propPowerCascade :: (Eq a, C a) => a -> Rational -> Rational -> Bool propPowerProduct :: (Eq a, C a) => a -> Rational -> Rational -> Bool propPowerDistributive :: (Eq a, C a) => Rational -> a -> a -> Bool instance C Double instance C Float module Algebra.Transcendental -- | Transcendental is the type of numbers supporting the elementary -- transcendental functions. Examples include real numbers, complex -- numbers, and computable reals represented as a lazy list of rational -- approximations. -- -- Note the default declaration for a superclass. See the comments below, -- under Instance declaractions for superclasses. -- -- The semantics of these operations are rather ill-defined because of -- branch cuts, etc. -- -- Minimal complete definition: pi, exp, log, sin, cos, asin, acos, atan class (C a) => C a pi :: (C a) => a exp :: (C a) => a -> a log :: (C a) => a -> a logBase :: (C a) => a -> a -> a (**) :: (C a) => a -> a -> a sin :: (C a) => a -> a tan :: (C a) => a -> a cos :: (C a) => a -> a asin :: (C a) => a -> a atan :: (C a) => a -> a acos :: (C a) => a -> a sinh :: (C a) => a -> a tanh :: (C a) => a -> a cosh :: (C a) => a -> a asinh :: (C a) => a -> a atanh :: (C a) => a -> a acosh :: (C a) => a -> a (^?) :: (C a) => a -> a -> a propExpLog :: (Eq a, C a) => a -> Bool propLogExp :: (Eq a, C a) => a -> Bool propExpNeg :: (Eq a, C a) => a -> Bool propLogRecip :: (Eq a, C a) => a -> Bool propExpProduct :: (Eq a, C a) => a -> a -> Bool propExpLogPower :: (Eq a, C a) => a -> a -> Bool propLogSum :: (Eq a, C a) => a -> a -> Bool propPowerCascade :: (Eq a, C a) => a -> a -> a -> Bool propPowerProduct :: (Eq a, C a) => a -> a -> a -> Bool propPowerDistributive :: (Eq a, C a) => a -> a -> a -> Bool propTrigonometricPythagoras :: (Eq a, C a) => a -> Bool propSinPeriod :: (Eq a, C a) => a -> Bool propCosPeriod :: (Eq a, C a) => a -> Bool propTanPeriod :: (Eq a, C a) => a -> Bool propSinAngleSum :: (Eq a, C a) => a -> a -> Bool propCosAngleSum :: (Eq a, C a) => a -> a -> Bool propSinDoubleAngle :: (Eq a, C a) => a -> Bool propCosDoubleAngle :: (Eq a, C a) => a -> Bool propSinSquare :: (Eq a, C a) => a -> Bool propCosSquare :: (Eq a, C a) => a -> Bool instance C Double instance C Float -- | Abstraction of modules module Algebra.Module -- | A Module over a ring satisfies: -- --
--   a *> (b + c) === a *> b + a *> c
--   (a * b) *> c === a *> (b *> c)
--   (a + b) *> c === a *> c + b *> c
--   
class (C a, C v) => C a v (*>) :: (C a v) => a -> v -> v (<*>.*>) :: (C a x) => T (a, v) (x -> c) -> (v -> x) -> T (a, v) c -- | Compute the linear combination of a list of vectors. -- -- ToDo: Should it use NumericPrelude.List.zipWithMatch ? linearComb :: (C a v) => [a] -> [v] -> v -- | This function can be used to define any C as a module over -- Integer. -- -- Better move to Algebra.Additive? integerMultiply :: (C a, C v) => a -> v -> v propCascade :: (Eq v, C a v) => v -> a -> a -> Bool propRightDistributive :: (Eq v, C a v) => a -> v -> v -> Bool propLeftDistributive :: (Eq v, C a v) => v -> a -> a -> Bool instance (C a v) => C a (c -> v) instance (C a v) => C a [v] instance (C a b0, C a b1, C a b2) => C a (b0, b1, b2) instance (C a b0, C a b1) => C a (b0, b1) instance (C a) => C Integer (T a) instance (C a) => C (T a) (T a) instance C Integer Integer instance C Int Int instance C Double Double instance C Float Float module Algebra.VectorSpace class (C a, C a b) => C a b instance (C a b) => C a (c -> b) instance (C a b) => C a [b] instance (C a b0, C a b1, C a b2) => C a (b0, b1, b2) instance (C a b0, C a b1) => C a (b0, b1) instance (C a) => C (T a) (T a) instance C Double Double instance C Float Float module Algebra.DivisibleSpace -- | DivisibleSpace is used for free one-dimensional vector spaces. It -- satisfies -- --
--   (a </> b) *> b = a
--   
-- -- Examples include dollars and kilometers. class (C a b) => C a b () :: (C a b) => b -> b -> a -- | Abstraction of bases of finite dimensional modules module Algebra.ModuleBasis -- | It must hold: -- --
--   Module.linearComb (flatten v `asTypeOf` [a]) (basis a) == v
--   dimension a v == length (flatten v `asTypeOf` [a])
--   
class (C a v) => C a v basis :: (C a v) => a -> [v] flatten :: (C a v) => v -> [a] dimension :: (C a v) => a -> v -> Int propFlatten :: (Eq v, C a v) => a -> v -> Bool propDimension :: (C a v) => a -> v -> Bool instance (C a v0, C a v1, C a v2) => C a (v0, v1, v2) instance (C a v0, C a v1) => C a (v0, v1) instance (C a) => C (T a) (T a) instance C Integer Integer instance C Int Int instance C Double Double instance C Float Float -- | Some functions that are counterparts of functions from -- Data.List using NumericPrelude.Numeric type classes. They are -- distinct in that they check for valid arguments, e.g. the length -- argument of take must be at most the length of the input list. -- However, since many Haskell programs rely on the absence of such -- checks, we did not make these the default implementations as in -- NumericPrelude.List.Generic. module NumericPrelude.List.Checked -- | Taken number of elements must be at most the length of the list, -- otherwise the end of the list is undefined. take :: (C n) => n -> [a] -> [a] -- | Dropped number of elements must be at most the length of the list, -- otherwise the end of the list is undefined. drop :: (C n) => n -> [a] -> [a] -- | Split position must be at most the length of the list, otherwise the -- end of the first list and the second list are undefined. splitAt :: (C n) => n -> [a] -> ([a], [a]) -- | The index must be smaller than the length of the list, otherwise the -- result is undefined. (!!) :: (C n) => [a] -> n -> a -- | Zip two lists which must be of the same length. This is checked only -- lazily, that is unequal lengths are detected only if the list is -- evaluated completely. But it is more strict than zipWithPad -- undefined f since the latter one may succeed on unequal length -- list if f is lazy. zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] -- | Functions that are counterparts of the generic functions in -- Data.List using NumericPrelude.Numeric type classes. For input -- arguments we use the restrictive ToInteger constraint, -- although in principle RealRing would be enough. However we -- think that take 0.5 xs is rather a bug than a feature, thus -- we forbid fractional types. On the other hand fractional types as -- result can be quite handy, e.g. in average xs = sum xs / length -- xs. module NumericPrelude.List.Generic -- | The index must be smaller than the length of the list, otherwise the -- result is undefined. (!!) :: (C n) => [a] -> n -> a -- | Left associative length computation that is appropriate for types like -- Integer. lengthLeft :: (C n) => [a] -> n -- | Right associative length computation that is appropriate for types -- like Peano number. lengthRight :: (C n) => [a] -> n replicate :: (C n) => n -> a -> [a] take :: (C n) => n -> [a] -> [a] drop :: (C n) => n -> [a] -> [a] splitAt :: (C n) => n -> [a] -> ([a], [a]) findIndex :: (C n) => (a -> Bool) -> [a] -> Maybe n elemIndex :: (C n, Eq a) => a -> [a] -> Maybe n findIndices :: (C n) => (a -> Bool) -> [a] -> [n] elemIndices :: (C n, Eq a) => a -> [a] -> [n] module Algebra.RealRing -- | Minimal complete definition: splitFraction or floor -- -- There are probably more laws, but some laws are -- --
--   splitFraction x === (fromInteger (floor x), fraction x)
--   fromInteger (floor x) + fraction x === x
--   floor x       <= x       x <  floor x + 1
--   ceiling x - 1 <  x       x <= ceiling x
--   0 <= fraction x          fraction x < 1
--   
-- --
--               - ceiling x === floor (-x)
--                truncate x === signum x * floor (abs x)
--    ceiling (toRational x) === ceiling x :: Integer
--   truncate (toRational x) === truncate x :: Integer
--      floor (toRational x) === floor x :: Integer
--   
-- -- The new function fraction doesn't return the integer part of -- the number. This also removes a type ambiguity if the integer part is -- not needed. -- -- Many people will associate rounding with fractional numbers, and thus -- they are surprised about the superclass being Ring not -- Field. The reason is that all of these methods can be defined -- exclusively with functions from Ord and Ring. The -- implementations of genericFloor and other functions demonstrate -- that. They implement power-of-two-algorithms like the one for finding -- the number of digits of an Integer in FixedPoint-fractions -- module. They are even reasonably efficient. -- -- I am still uncertain whether it was a good idea to add instances for -- Integer and friends, since calling floor or -- fraction on an integer may well indicate a bug. The rounding -- functions are just the identity function and fraction is -- constant zero. However, I decided to associate our class with -- Ring rather than Field, after I found myself using -- repeated subtraction and testing rather than just calling -- fraction, just in order to get the constraint (Ring a, -- Ord a) that was more general than (RealField a). -- -- For the results of the rounding functions we have chosen the -- constraint Ring instead of ToInteger, since this is -- more flexible to use, but it still signals to the user that only -- integral numbers can be returned. This is so, because the plain -- Ring class only provides zero, one and -- operations that allow to reach all natural numbers but not more. -- -- As an aside, let me note the similarities between splitFraction -- x and divMod x 1 (if that were defined). In particular, -- it might make sense to unify the rounding modes somehow. -- -- The new methods fraction and splitFraction differ from -- Prelude.properFraction semantics. They always round to -- floor. This means that the fraction is always non-negative and -- is always smaller than 1. This is more useful in practice and can be -- generalised to more than real numbers. Since every T -- denominator type supports divMod, every T can provide -- fraction and splitFraction, e.g. fractions of -- polynomials. However the Ring constraint for the ''integral'' -- part of splitFraction is too weak in order to generate -- polynomials. After all, I am uncertain whether this would be useful or -- not. -- -- Can there be a separate class for fraction, -- splitFraction, floor and ceiling since they do -- not need reals and their ordering? -- -- We might also add a round method, that rounds 0.5 always up or always -- down. This is much more efficient in inner loops and is acceptable or -- even preferable for many applications. class (C a, Ord a) => C a splitFraction :: (C a, C b) => a -> (b, a) fraction :: (C a) => a -> a ceiling :: (C a, C b) => a -> b floor :: (C a, C b) => a -> b truncate :: (C a, C b) => a -> b round :: (C a, C b) => a -> b -- | This function rounds to the closest integer. For fraction x == -- 0.5 it rounds away from zero. This function is not the result of -- an ingenious mathematical insight, but is simply a kind of rounding -- that is the fastest on IEEE floating point architectures. roundSimple :: (C a, C b) => a -> b fastSplitFraction :: (RealFrac a, C a, C b) => (a -> Int) -> (Int -> a) -> a -> (b, a) fixSplitFraction :: (C a, C b, Ord a) => (b, a) -> (b, a) fastFraction :: (RealFrac a, C a) => (a -> a) -> a -> a preludeFraction :: (RealFrac a, C a) => a -> a fixFraction :: (C a, Ord a) => a -> a splitFractionInt :: (C a, Ord a) => (a -> Int) -> (Int -> a) -> a -> (Int, a) floorInt :: (C a, Ord a) => (a -> Int) -> (Int -> a) -> a -> Int ceilingInt :: (C a, Ord a) => (a -> Int) -> (Int -> a) -> a -> Int roundInt :: (C a, Ord a) => (a -> Int) -> (Int -> a) -> a -> Int roundSimpleInt :: (C a, C a, Ord a) => (a -> Int) -> (Int -> a) -> a -> Int -- | TODO: Should be moved to a continued fraction module. approxRational :: (C a, C a) => a -> a -> Rational powersOfTwo :: (C a) => [a] pairsOfPowersOfTwo :: (C a, C b) => [(a, b)] -- | The generic rounding functions need a number of operations -- proportional to the number of binary digits of the integer portion. If -- operations like multiplication with two and comparison need time -- proportional to the number of binary digits, then the overall rounding -- requires quadratic time. genericFloor :: (Ord a, C a, C b) => a -> b genericCeiling :: (Ord a, C a, C b) => a -> b genericTruncate :: (Ord a, C a, C b) => a -> b genericRound :: (Ord a, C a, C b) => a -> b genericFraction :: (Ord a, C a) => a -> a genericSplitFraction :: (Ord a, C a, C b) => a -> (b, a) genericPosFloor :: (Ord a, C a, C b) => a -> b genericPosCeiling :: (Ord a, C a, C b) => a -> b genericHalfPosFloorDigits :: (Ord a, C a, C b) => a -> ((a, b), [Bool]) genericPosRound :: (Ord a, C a, C b) => a -> b genericPosFraction :: (Ord a, C a) => a -> a genericPosSplitFraction :: (Ord a, C a, C b) => a -> (b, a) -- | Needs linear time with respect to the number of digits. -- -- This and other functions using OrderDecision like floor where -- argument and result are the same may be moved to a new module. decisionPosFraction :: (C a, C a) => a -> a decisionPosFractionSqrTime :: (C a, C a) => a -> a instance C Double instance C Float instance C Integer instance C Int instance (C a, C a) => C (T a) module Algebra.RealField -- | This is a convenient class for common types that both form a field and -- have a notion of ordering by magnitude. class (C a, C a) => C a instance (C a, C a) => C (T a) instance C Double instance C Float module Algebra.RealTranscendental -- | This class collects all functions for _scalar_ floating point numbers. -- E.g. computing atan2 for complex floating numbers makes -- certainly no sense. class (C a, C a) => C a atan2 :: (C a) => a -> a -> a instance C Double instance C Float module NumericPrelude.Numeric -- | add and subtract elements (+) :: (C a) => a -> a -> a (-) :: (C a) => a -> a -> a -- | inverse with respect to + negate :: (C a) => a -> a -- | zero element of the vector space zero :: (C a) => a -- | subtract is (-) with swapped operand order. This is -- the operand order which will be needed in most cases of partial -- application. subtract :: (C a) => a -> a -> a -- | Sum up all elements of a list. An empty list yields zero. -- -- This function is inappropriate for number types like Peano. Maybe we -- should make sum a method of Additive. This would also make -- lengthLeft and lengthRight superfluous. sum :: (C a) => [a] -> a -- | Sum up all elements of a non-empty list. This avoids including a zero -- which is useful for types where no universal zero is available. sum1 :: (C a) => [a] -> a isZero :: (C a) => a -> Bool (*) :: (C a) => a -> a -> a one :: (C a) => a fromInteger :: (C a) => Integer -> a -- | The exponent has fixed type Integer in order to avoid an -- arbitrarily limitted range of exponents, but to reduce the need for -- the compiler to guess the type (default type). In practice the -- exponent is most oftenly fixed, and is most oftenly 2. Fixed -- exponents can be optimized away and thus the expensive computation of -- Integers doesn't matter. The previous solution used a -- Algebra.ToInteger.C constrained type and the exponent was -- converted to Integer before computation. So the current solution is -- not less efficient. -- -- A variant of ^ with more flexibility is provided by -- Algebra.Core.ringPower. (^) :: (C a) => a -> Integer -> a -- | A prefix function of '(Algebra.Ring.^)' with a parameter order that -- fits the needs of partial application and function composition. It has -- generalised exponent. -- -- See: Argument order of expNat on -- http://www.haskell.org/pipermail/haskell-cafe/2006-September/018022.html ringPower :: (C a, C b) => b -> a -> a sqr :: (C a) => a -> a product :: (C a) => [a] -> a product1 :: (C a) => [a] -> a div :: (C a) => a -> a -> a mod :: (C a) => a -> a -> a divMod :: (C a) => a -> a -> (a, a) divides :: (C a, C a) => a -> a -> Bool even :: (C a, C a) => a -> Bool odd :: (C a, C a) => a -> Bool (/) :: (C a) => a -> a -> a recip :: (C a) => a -> a fromRational' :: (C a) => Rational -> a (^-) :: (C a) => a -> Integer -> a -- | A prefix function of '(Algebra.Field.^-)'. It has a generalised -- exponent. fieldPower :: (C a, C b) => b -> a -> a -- | Needed to work around shortcomings in GHC. fromRational :: (C a) => Rational -> a (^/) :: (C a) => a -> Rational -> a sqrt :: (C a) => a -> a pi :: (C a) => a exp :: (C a) => a -> a log :: (C a) => a -> a logBase :: (C a) => a -> a -> a (**) :: (C a) => a -> a -> a (^?) :: (C a) => a -> a -> a sin :: (C a) => a -> a cos :: (C a) => a -> a tan :: (C a) => a -> a asin :: (C a) => a -> a acos :: (C a) => a -> a atan :: (C a) => a -> a sinh :: (C a) => a -> a cosh :: (C a) => a -> a tanh :: (C a) => a -> a asinh :: (C a) => a -> a acosh :: (C a) => a -> a atanh :: (C a) => a -> a abs :: (C a) => a -> a signum :: (C a) => a -> a quot :: (C a) => a -> a -> a rem :: (C a) => a -> a -> a quotRem :: (C a) => a -> a -> (a, a) splitFraction :: (C a, C b) => a -> (b, a) fraction :: (C a) => a -> a truncate :: (C a, C b) => a -> b round :: (C a, C b) => a -> b ceiling :: (C a, C b) => a -> b floor :: (C a, C b) => a -> b -- | TODO: Should be moved to a continued fraction module. approxRational :: (C a, C a) => a -> a -> Rational atan2 :: (C a) => a -> a -> a -- | Lossless conversion from any representation of a rational to -- Rational toRational :: (C a) => a -> Rational toInteger :: (C a) => a -> Integer fromIntegral :: (C a, C b) => a -> b isUnit :: (C a) => a -> Bool stdAssociate :: (C a) => a -> a stdUnit :: (C a) => a -> a stdUnitInv :: (C a) => a -> a -- | Compute the greatest common divisor and solve a respective Diophantine -- equation. -- --
--   (g,(a,b)) = extendedGCD x y ==>
--        g==a*x+b*y   &&  g == gcd x y
--   
-- -- TODO: This method is not appropriate for the PID class, because there -- are rings like the one of the multivariate polynomials, where for all -- x and y greatest common divisors of x and y exist, but they cannot be -- represented as a linear combination of x and y. TODO: The definition -- of extendedGCD does not return the canonical associate. extendedGCD :: (C a) => a -> a -> (a, (a, a)) -- | The Greatest Common Divisor is defined by: -- --
--   gcd x y == gcd y x
--   divides z x && divides z y ==> divides z (gcd x y)   (specification)
--   divides (gcd x y) x
--   
gcd :: (C a) => a -> a -> a -- | Least common multiple lcm :: (C a) => a -> a -> a euclid :: (C a, C a) => (a -> a -> a) -> a -> a -> a extendedEuclid :: (C a, C a) => (a -> a -> (a, a)) -> a -> a -> (a, (a, a)) type Rational = T Integer (%) :: (C a) => a -> a -> T a numerator :: T a -> a denominator :: T a -> a -- | Arbitrary-precision integers. data Integer :: * -- | A fixed-precision integer type with at least the range [-2^29 .. -- 2^29-1]. The exact range for a given implementation can be -- determined by using Prelude.minBound and Prelude.maxBound from the -- Prelude.Bounded class. data Int :: * -- | Single-precision floating point numbers. It is desirable that this -- type be at least equal in range and precision to the IEEE -- single-precision type. data Float :: * -- | Double-precision floating point numbers. It is desirable that this -- type be at least equal in range and precision to the IEEE -- double-precision type. data Double :: * -- | scale a vector by a scalar (*>) :: (C a v) => a -> v -> v module Algebra.Lattice class C a up :: (C a) => a -> a -> a dn :: (C a) => a -> a -> a max :: (C a) => a -> a -> a min :: (C a) => a -> a -> a abs :: (C a, C a) => a -> a propUpCommutative :: (Eq a, C a) => a -> a -> Bool propDnCommutative :: (Eq a, C a) => a -> a -> Bool propUpAssociative :: (Eq a, C a) => a -> a -> a -> Bool propDnAssociative :: (Eq a, C a) => a -> a -> a -> Bool propUpDnDistributive :: (Eq a, C a) => a -> a -> a -> Bool propDnUpDistributive :: (Eq a, C a) => a -> a -> a -> Bool instance (C a, C b) => C (a, b) instance C Bool instance (Ord a, C a) => C (T a) instance C Integer module NumericPrelude max :: (C a) => a -> a -> a min :: (C a) => a -> a -> a abs :: (C a, C a) => a -> a -- | Abstraction of normed vector spaces module Algebra.NormedSpace.Euclidean -- | Helper class for C that does not need an algebraic type -- a. -- -- Minimal definition: normSqr class (C a, C a v) => Sqr a v normSqr :: (Sqr a v) => v -> a -- | Default definition for normSqr that is based on Foldable -- class. normSqrFoldable :: (Sqr a v, Foldable f) => f v -> a -- | Default definition for normSqr that is based on Foldable -- class and the argument vector has at least one component. normSqrFoldable1 :: (Sqr a v, Foldable f, Functor f) => f v -> a -- | A vector space equipped with an Euclidean or a Hilbert norm. -- -- Minimal definition: norm class (Sqr a v) => C a v norm :: (C a v) => v -> a defltNorm :: (C a, Sqr a v) => v -> a instance (C a, Sqr a v) => C a [v] instance (Sqr a v) => Sqr a [v] instance (C a, Sqr a v0, Sqr a v1, Sqr a v2) => C a (v0, v1, v2) instance (Sqr a v0, Sqr a v1, Sqr a v2) => Sqr a (v0, v1, v2) instance (C a, Sqr a v0, Sqr a v1) => C a (v0, v1) instance (Sqr a v0, Sqr a v1) => Sqr a (v0, v1) instance (C a, C a) => Sqr (T a) (T a) instance C Integer Integer instance Sqr Integer Integer instance C Int Int instance Sqr Int Int instance C Double Double instance Sqr Double Double instance C Float Float instance Sqr Float Float -- | Abstraction of normed vector spaces module Algebra.NormedSpace.Maximum class (C a, C a v) => C a v norm :: (C a v) => v -> a -- | Default definition for norm that is based on Foldable -- class. normFoldable :: (C a v, Foldable f) => f v -> a -- | Default definition for norm that is based on Foldable -- class and the argument vector has at least one component. normFoldable1 :: (C a v, Foldable f, Functor f) => f v -> a instance (Ord a, C a v) => C a [v] instance (Ord a, C a v0, C a v1, C a v2) => C a (v0, v1, v2) instance (Ord a, C a v0, C a v1) => C a (v0, v1) instance (C a, C a, C a) => C (T a) (T a) instance C Integer Integer instance C Int Int instance C Double Double instance C Float Float -- | Abstraction of normed vector spaces module Algebra.NormedSpace.Sum -- | The super class is only needed to state the laws v == zero == -- norm v == zero norm (scale x v) == abs x * norm v norm (u+v) <= -- norm u + norm v class (C a, C a v) => C a v norm :: (C a v) => v -> a -- | Default definition for norm that is based on Foldable -- class. normFoldable :: (C a v, Foldable f) => f v -> a -- | Default definition for norm that is based on Foldable -- class and the argument vector has at least one component. normFoldable1 :: (C a v, Foldable f, Functor f) => f v -> a instance (C a, C a v) => C a [v] instance (C a, C a v0, C a v1, C a v2) => C a (v0, v1, v2) instance (C a, C a v0, C a v1) => C a (v0, v1) instance (C a, C a) => C (T a) (T a) instance C Integer Integer instance C Int Int instance C Double Double instance C Float Float -- | DiscreteMap was originally intended as a type class that unifies Map -- and Array. One should be able to simply choose between - Map for -- sparse arrays - Array for full arrays. -- -- However, the Edison package provides the class AssocX which already -- exists for that purpose. -- -- Currently I use this module for some numeric instances of Data.Map. module MathObj.DiscreteMap -- | Remove all zero values from the map. strip :: (Ord i, Eq v, C v) => Map i v -> Map i v instance (Ord i, Eq a, Eq v, C a v) => C a (Map i v) instance (Ord i, Eq a, Eq v, C a, Sqr a v) => C a (Map i v) instance (Ord i, Eq a, Eq v, Sqr a v) => Sqr a (Map i v) instance (Ord i, Eq a, Eq v, C a v) => C a (Map i v) instance (Ord i, Eq a, Eq v, C a v) => C a (Map i v) instance (Ord i, Eq a, Eq v, C a v) => C a (Map i v) instance (Ord i) => C (Map i) instance (Ord i, Eq v, C v) => C (Map i v) -- | Routines and abstractions for Matrices and basic linear algebra over -- fields or rings. -- -- We stick to simple Int indices. Although advanced indices would be -- nice e.g. for matrices with sub-matrices, this is not easily -- implemented since arrays do only support a lower and an upper bound -- but no additional parameters. -- -- ToDo: - Matrix inverse, determinant module MathObj.Matrix -- | A matrix is a twodimensional array, indexed by integers. data T a type Dimension = Int format :: (Show a) => T a -> String -- | Transposition of matrices is just transposition in the sense of -- Data.List. transpose :: T a -> T a rows :: T a -> [[a]] columns :: T a -> [[a]] fromRows :: Dimension -> Dimension -> [[a]] -> T a fromColumns :: Dimension -> Dimension -> [[a]] -> T a fromList :: Dimension -> Dimension -> [a] -> T a dimension :: T a -> (Dimension, Dimension) numRows :: T a -> Dimension numColumns :: T a -> Dimension zipWith :: (a -> b -> c) -> T a -> T b -> T c zero :: (C a) => Dimension -> Dimension -> T a one :: (C a) => Dimension -> T a diagonal :: (C a) => [a] -> T a scale :: (C a) => a -> T a -> T a random :: (RandomGen g, Random a) => Dimension -> Dimension -> g -> (T a, g) randomR :: (RandomGen g, Random a) => Dimension -> Dimension -> (a, a) -> g -> (T a, g) instance (Eq a) => Eq (T a) instance (Ord a) => Ord (T a) instance (Read a) => Read (T a) instance (C a b) => C a (T b) instance C T instance Functor T instance (C a) => C (T a) instance (C a) => C (T a) instance (Show a) => Show (T a) -- | Implementation of partial fractions. Useful e.g. for fractions of -- integers and fractions of polynomials. -- -- For the considered ring the prime factorization must be unique. module MathObj.PartialFraction -- | Cons z (indexMapFromList [(x0,[y00,y01]), (x1,[y10]), -- (x2,[y20,y21,y22])]) represents the partial fraction z + -- y00x0 + y01x0^2 + y10x1 + y20x2 + y21x2^2 + -- y22x2^3 The denominators x0, x1, x2, ... must be -- irreducible, but we can't check this in general. It is also not enough -- to have relatively prime denominators, because when adding two partial -- fraction representations there might concur denominators that have -- non-trivial common divisors. data T a Cons :: a -> (Map (ToOrd a) [a]) -> T a -- | Unchecked construction. fromFractionSum :: (C a) => a -> [(a, [a])] -> T a toFractionSum :: (C a) => T a -> (a, [(a, [a])]) appPrec :: Int toFraction :: (C a) => T a -> T a -- | PrincipalIdealDomain.C is not really necessary here and only -- due to invokation of toFraction. toFactoredFraction :: (C a) => T a -> ([a], a) -- | PrincipalIdealDomain.C is not really necessary here and only -- due to invokation of %. multiToFraction :: (C a) => a -> [a] -> T a hornerRev :: (C a) => a -> [a] -> a -- | fromFactoredFraction x y computes the partial fraction -- representation of y % product x, where the elements of -- x must be irreducible. The function transforms the factors -- into their standard form with respect to unit factors. -- -- There are more direct methods for special cases like polynomials over -- rational numbers where the denominators are linear factors. fromFactoredFraction :: (C a, C a) => [a] -> a -> T a fromFactoredFractionAlt :: (C a, C a) => [a] -> a -> T a -- | The list of denominators must contain equal elements. Sorry for this -- hack. multiFromFraction :: (C a) => [a] -> a -> (a, [a]) fromValue :: a -> T a -- | A normalization step which separates the integer part from the leading -- fraction of each sub-list. reduceHeads :: (C a) => T a -> T a -- | Cf. Number.Positional carryRipple :: (C a) => a -> [a] -> (a, [a]) -- | A normalization step which reduces all elements in sub-lists modulo -- their denominators. Zeros might be the result, that must be remove -- with removeZeros. normalizeModulo :: (C a) => T a -> T a -- | Remove trailing zeros in sub-lists because if lists are converted to -- fractions by multiToFraction we must be sure that the -- denominator of the (cancelled) fraction is indeed the stored power of -- the irreducible denominator. Otherwise mulFrac leads to wrong -- results. removeZeros :: (C a, C a) => T a -> T a zipWith :: (C a) => (a -> a -> a) -> ([a] -> [a] -> [a]) -> (T a -> T a -> T a) -- | Transforms a product of two partial fractions into a sum of two -- fractions. The denominators must be at least relatively prime. Since -- T requires irreducible denominators, these are also relatively -- prime. -- -- Example: mulFrac (1%6) (1%4) fails because of the common -- divisor 2. mulFrac :: (C a) => T a -> T a -> (a, a) mulFrac' :: (C a) => T a -> T a -> (T a, T a) -- | Works always but simply puts the product into the last fraction. mulFracStupid :: (C a) => T a -> T a -> ((T a, T a), T a) -- | Also works if the operands share a non-trivial divisor. However the -- results are quite arbitrary. mulFracOverlap :: (C a) => T a -> T a -> ((T a, T a), T a) -- | Expects an irreducible denominator as associate in standard form. scaleFrac :: (C a, C a) => T a -> T a -> T a scaleInt :: (C a, C a) => a -> T a -> T a mul :: (C a, C a) => T a -> T a -> T a mulFast :: (C a, C a) => T a -> T a -> T a indexMapMapWithKey :: (a -> b -> c) -> Map (ToOrd a) b -> Map (ToOrd a) c indexMapToList :: Map (ToOrd a) b -> [(a, b)] indexMapFromList :: (C a) => [(a, b)] -> Map (ToOrd a) b -- | Apply a function on a specific element if it exists, and another -- function to the rest of the map. mapApplySplit :: (Ord a) => a -> (c -> c -> c) -> (b -> c) -> (Map a b -> Map a c) -> Map a b -> Map a c instance (Eq a) => Eq (T a) instance (C a, C a) => C (T a) instance (C a, C a, C a) => C (T a) instance (Show a) => Show (T a) -- | Permutation of Integers represented by cycles. module MathObj.Permutation.CycleList type Cycle i = [i] type T i = [Cycle i] fromFunction :: (Ix i) => (i, i) -> (i -> i) -> T i cycleRightAction :: (Eq i) => i -> Cycle i -> i cycleLeftAction :: (Eq i) => Cycle i -> i -> i cycleAction :: (Eq i) => [i] -> i -> i cycleOrbit :: (Ord i) => Cycle i -> i -> [i] -- | Right (left?) group action on the Integers. Close to, but not the same -- as the module action in Algebra.Module. (*>) :: (Eq i) => T i -> i -> i cyclesOrbit :: (Ord i) => T i -> i -> [i] orbit :: (Ord i) => (i -> i) -> i -> [i] -- | candidates for Utility ? takeUntilRepetition :: (Ord a) => [a] -> [a] takeUntilRepetitionSlow :: (Eq a) => [a] -> [a] choose :: Set a -> Maybe a keepEssentials :: T i -> T i isEssential :: Cycle i -> Bool inverse :: T i -> T i module MathObj.Permutation.CycleList.Check -- | We shall make a little bit of a hack here, enabling us to use additive -- or multiplicative syntax for groups as we wish by simply instantiating -- Num with both operations corresponding to the group operation of the -- permutation group we're studying -- -- There are quite a few way we could represent elements of permutation -- groups: the images in a row, a list of the cycles, et.c. All of these -- differ highly in how complex various operations end up being. newtype Cycle i Cycle :: [i] -> Cycle i cycle :: Cycle i -> [i] data T i Cons :: (i, i) -> [Cycle i] -> T i range :: T i -> (i, i) cycles :: T i -> [Cycle i] -- | Does not check whether the input values are in range. fromCycles :: (i, i) -> [[i]] -> T i toCycles :: T i -> [[i]] toTable :: (Ix i) => T i -> T i fromTable :: (Ix i) => T i -> T i errIncompat :: a liftCmpTable2 :: (Ix i) => (T i -> T i -> a) -> T i -> T i -> a liftTable2 :: (Ix i) => (T i -> T i -> T i) -> T i -> T i -> T i closure :: (Ix i) => [T i] -> [T i] instance (Read i) => Read (Cycle i) instance (Eq i) => Eq (Cycle i) instance (Ix i) => C (T i) instance (Ix i) => Ord (T i) instance (Ix i) => Eq (T i) instance (Show i) => Show (T i) instance (Show i) => Show (Cycle i) instance C T -- | This module implements polynomial functions on plain lists. We use -- such functions in order to implement methods of other datatypes. -- -- The module organization differs from that of ResidueClass: -- Here the Polynomial module exports the type that fits to the -- NumericPrelude type classes, whereas in ResidueClass the -- sub-modules export various flavors of them. module MathObj.Polynomial.Core -- | Horner's scheme for evaluating a polynomial in a ring. horner :: (C a) => a -> [a] -> a -- | Horner's scheme for evaluating a polynomial in a module. hornerCoeffVector :: (C a v) => a -> [v] -> v hornerArgVector :: (C a v, C v) => v -> [a] -> v -- | It's also helpful to put a polynomial in canonical form. -- normalize strips leading coefficients that are zero. normalize :: (C a) => [a] -> [a] -- | Multiply by the variable, used internally. shift :: (C a) => [a] -> [a] unShift :: [a] -> [a] equal :: (Eq a, C a) => [a] -> [a] -> Bool add :: (C a) => [a] -> [a] -> [a] sub :: (C a) => [a] -> [a] -> [a] negate :: (C a) => [a] -> [a] scale :: (C a) => a -> [a] -> [a] collinear :: (Eq a, C a) => [a] -> [a] -> Bool tensorProduct :: (C a) => [a] -> [a] -> [[a]] tensorProductAlt :: (C a) => [a] -> [a] -> [[a]] -- | mul is fast if the second argument is a short polynomial, -- MathObj.PowerSeries.** relies on that fact. mul :: (C a) => [a] -> [a] -> [a] mulShear :: (C a) => [a] -> [a] -> [a] mulShearTranspose :: (C a) => [a] -> [a] -> [a] divMod :: (C a, C a) => [a] -> [a] -> ([a], [a]) divModRev :: (C a, C a) => [a] -> [a] -> ([a], [a]) stdUnit :: (C a, C a) => [a] -> a progression :: (C a) => [a] differentiate :: (C a) => [a] -> [a] integrate :: (C a) => a -> [a] -> [a] -- | Integrates if it is possible to represent the integrated polynomial in -- the given ring. Otherwise undefined coefficients occur. integrateInt :: (C a, C a) => a -> [a] -> [a] mulLinearFactor :: (C a) => a -> [a] -> [a] alternate :: (C a) => [a] -> [a] -- | Polynomials and rational functions in a single indeterminate. -- Polynomials are represented by a list of coefficients. All non-zero -- coefficients are listed, but there may be extra '0's at the end. -- -- Usage: Say you have the ring of Integer numbers and you want to -- add a transcendental element x, that is an element, which -- does not allow for simplifications. More precisely, for all positive -- integer exponents n the power x^n cannot be -- rewritten as a sum of powers with smaller exponents. The element -- x must be represented by the polynomial [0,1]. -- -- In principle, you can have more than one transcendental element by -- using polynomials whose coefficients are polynomials as well. However, -- most algorithms on multi-variate polynomials prefer a different -- (sparse) representation, where the ordering of elements is not so -- fixed. -- -- If you want division, you need Number.Ratios of polynomials -- with coefficients from a Algebra.Field. -- -- You can also compute with an algebraic element, that is an element -- which satisfies an algebraic equation like x^3-x-1==0. -- Actually, powers of x with exponents above 3 can be -- simplified, since it holds x^3==x+1. You can perform these -- computations with Number.ResidueClass of polynomials, where the -- divisor is the polynomial equation that determines x. If the -- polynomial is irreducible (in our case x^3-x-1 cannot be -- written as a non-trivial product) then the residue classes also allow -- unrestricted division (except by zero, of course). That is, using -- residue classes of polynomials you can work with roots of polynomial -- equations without representing them by radicals (powers with -- fractional exponents). It is well-known, that roots of polynomials of -- degree above 4 may not be representable by radicals. module MathObj.Polynomial data T a fromCoeffs :: [a] -> T a coeffs :: T a -> [a] degree :: (C a) => T a -> Maybe Int showsExpressionPrec :: (Show a, C a, C a) => Int -> String -> T a -> String -> String const :: a -> T a evaluate :: (C a) => T a -> a -> a -- | Here the coefficients are vectors, for example the coefficients are -- real and the coefficents are real vectors. evaluateCoeffVector :: (C a v) => T v -> a -> v -- | Here the argument is a vector, for example the coefficients are -- complex numbers or square matrices and the coefficents are reals. evaluateArgVector :: (C a v, C v) => T a -> v -> v collinear :: (Eq a, C a) => T a -> T a -> Bool integrate :: (C a) => a -> T a -> T a -- | compose is the functional composition of polynomials. -- -- It fulfills eval x . eval y == eval (compose x y) compose :: (C a) => T a -> T a -> T a fromRoots :: (C a) => [a] -> T a reverse :: (C a) => T a -> T a translate :: (C a) => a -> T a -> T a dilate :: (C a) => a -> T a -> T a shrink :: (C a) => a -> T a -> T a instance (C a, Eq a, Show a, C a) => Fractional (T a) instance (C a, Eq a, Show a, C a) => Num (T a) instance (Arbitrary a, C a) => Arbitrary (T a) instance (C a) => C (T a) instance (C a, C a) => C (T a) instance (C a, C a) => C (T a) instance (C a, C a) => C (T a) instance (C a) => C (T a) instance (C a, C a b) => C a (T b) instance (C a b) => C a (T b) instance C T instance (C a) => C (T a) instance (C a) => C (T a) instance (C a, C a) => C (T a) instance (Eq a, C a) => Eq (T a) instance (Show a) => Show (T a) instance Functor T module MathObj.PowerSeries.Core evaluate :: (C a) => [a] -> a -> a evaluateCoeffVector :: (C a v) => [v] -> a -> v evaluateArgVector :: (C a v, C v) => [a] -> v -> v approximate :: (C a) => [a] -> a -> [a] approximateCoeffVector :: (C a v) => [v] -> a -> [v] approximateArgVector :: (C a v, C v) => [a] -> v -> [v] -- | For the series of a real function f compute the series for -- x -> f (-x) alternate :: (C a) => [a] -> [a] -- | For the series of a real function f compute the series for -- x -> (f x + f (-x)) / 2 holes2 :: (C a) => [a] -> [a] -- | For the series of a real function f compute the real series -- for x -> (f (i*x) + f (-i*x)) / 2 holes2alternate :: (C a) => [a] -> [a] sub :: (C a) => [a] -> [a] -> [a] add :: (C a) => [a] -> [a] -> [a] negate :: (C a) => [a] -> [a] scale :: (C a) => a -> [a] -> [a] mul :: (C a) => [a] -> [a] -> [a] stripLeadZero :: (C a) => [a] -> [a] -> ([a], [a]) divMod :: (C a, C a) => [a] -> [a] -> ([a], [a]) -- | Divide two series where the absolute term of the divisor is non-zero. -- That is, power series with leading non-zero terms are the units in the -- ring of power series. -- -- Knuth: Seminumerical algorithms divide :: (C a) => [a] -> [a] -> [a] -- | Divide two series also if the divisor has leading zeros. divideStripZero :: (C a, C a) => [a] -> [a] -> [a] progression :: (C a) => [a] recipProgression :: (C a) => [a] differentiate :: (C a) => [a] -> [a] integrate :: (C a) => a -> [a] -> [a] -- | We need to compute the square root only of the first term. That is, if -- the first term is rational, then all terms of the series are rational. sqrt :: (C a) => (a -> a) -> [a] -> [a] -- | Input series must start with non-zero term. pow :: (C a) => (a -> a) -> a -> [a] -> [a] -- | The first term needs a transcendent computation but the others do not. -- That's why we accept a function which computes the first term. -- --
--   (exp . x)' =   (exp . x) * x'
--   (sin . x)' =   (cos . x) * x'
--   (cos . x)' = - (sin . x) * x'
--   
exp :: (C a) => (a -> a) -> [a] -> [a] sinCos :: (C a) => (a -> (a, a)) -> [a] -> ([a], [a]) sinCosScalar :: (C a) => a -> (a, a) cos :: (C a) => (a -> (a, a)) -> [a] -> [a] sin :: (C a) => (a -> (a, a)) -> [a] -> [a] tan :: (C a) => (a -> (a, a)) -> [a] -> [a] -- | Input series must start with non-zero term. log :: (C a) => (a -> a) -> [a] -> [a] -- | Computes (log x)', that is x'/x derivedLog :: (C a) => [a] -> [a] atan :: (C a) => (a -> a) -> [a] -> [a] acos :: (C a) => (a -> a) -> (a -> a) -> [a] -> [a] asin :: (C a) => (a -> a) -> (a -> a) -> [a] -> [a] -- | Since the inner series must start with a zero, the first term is -- omitted in y. compose :: (C a) => [a] -> [a] -> [a] -- | Compose two power series where the outer series can be developed for -- any expansion point. To be more precise: The outer series must be -- expanded with respect to the leading term of the inner series. composeTaylor :: (C a) => (a -> [a]) -> [a] -> [a] -- | This function returns the series of the function in the form: (point -- of the expansion, power series) -- -- This is exceptionally slow and needs cubic run-time. inv :: (C a) => [a] -> (a, [a]) -- | Power series, either finite or unbounded. (zipWith does exactly the -- right thing to make it work almost transparently.) module MathObj.PowerSeries newtype T a Cons :: [a] -> T a coeffs :: T a -> [a] fromCoeffs :: [a] -> T a lift0 :: [a] -> T a lift1 :: ([a] -> [a]) -> (T a -> T a) lift2 :: ([a] -> [a] -> [a]) -> (T a -> T a -> T a) const :: a -> T a appPrec :: Int truncate :: Int -> T a -> T a -- | Evaluate (truncated) power series. evaluate :: (C a) => T a -> a -> a -- | Evaluate (truncated) power series. evaluateCoeffVector :: (C a v) => T v -> a -> v evaluateArgVector :: (C a v, C v) => T a -> v -> v -- | Evaluate approximations that is evaluate all truncations of the -- series. approximate :: (C a) => T a -> a -> [a] -- | Evaluate approximations that is evaluate all truncations of the -- series. approximateCoeffVector :: (C a v) => T v -> a -> [v] -- | Evaluate approximations that is evaluate all truncations of the -- series. approximateArgVector :: (C a v, C v) => T a -> v -> [v] -- | It fulfills evaluate x . evaluate y == evaluate (compose x y) -- compose :: (C a, C a) => T a -> T a -> T a instance (Ord a, C a) => Ord (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance (C a, C a) => C (T a) instance (C a) => C (T a) instance (C a, C a b) => C a (T b) instance (C a b) => C a (T b) instance C T instance (C a) => C (T a) instance (C a) => C (T a) instance (Eq a, C a) => Eq (T a) instance (Show a) => Show (T a) instance Functor T module MathObj.PowerSeries2.Core type T a = [[a]] lift0fromPowerSeries :: [T a] -> T a lift1fromPowerSeries :: ([T a] -> [T a]) -> (T a -> T a) lift2fromPowerSeries :: ([T a] -> [T a] -> [T a]) -> (T a -> T a -> T a) sub :: (C a) => T a -> T a -> T a add :: (C a) => T a -> T a -> T a negate :: (C a) => T a -> T a scale :: (C a) => a -> T a -> T a mul :: (C a) => T a -> T a -> T a divide :: (C a) => T a -> T a -> T a sqrt :: (C a) => (a -> a) -> T a -> T a swapVariables :: T a -> T a differentiate0 :: (C a) => T a -> T a differentiate1 :: (C a) => T a -> T a integrate0 :: (C a) => [a] -> T a -> T a integrate1 :: (C a) => [a] -> T a -> T a -- | Since the inner series must start with a zero, the first term is -- omitted in y. compose :: (C a) => [a] -> T a -> T a module MathObj.PowerSeries.Example recip :: (C a) => [a] sin :: (C a) => [a] cos :: (C a) => [a] log :: (C a) => [a] asin :: (C a) => [a] atan :: (C a) => [a] sqrt :: (C a) => [a] exp :: (C a) => [a] acos :: (C a) => [a] tan :: (C a, C a) => [a] cosh :: (C a) => [a] atanh :: (C a) => [a] sinh :: (C a) => [a] pow :: (C a) => a -> [a] recipExpl :: (C a) => [a] sinExpl :: (C a) => [a] cosExpl :: (C a) => [a] expExpl :: (C a) => [a] tanExplSieve :: (C a, C a) => [a] tanExpl :: (C a, C a) => [a] atanExpl :: (C a) => [a] sqrtExpl :: (C a) => [a] logExpl :: (C a) => [a] coshExpl :: (C a) => [a] atanhExpl :: (C a) => [a] sinhExpl :: (C a) => [a] powExpl :: (C a) => a -> [a] -- | Power series of error function (almost). More precisely erf = 2 / -- sqrt pi * integrate (x -> exp (-x^2)) , with erf 0 = -- 0. erf :: (C a) => [a] sinODE :: (C a) => [a] cosODE :: (C a) => [a] tanODE :: (C a) => [a] tanODESieve :: (C a) => [a] expODE :: (C a) => [a] recipCircle :: (C a) => [a] asinODE :: (C a) => [a] atanODE :: (C a) => [a] sqrtODE :: (C a) => [a] logODE :: (C a) => [a] acosODE :: (C a) => [a] coshODE :: (C a) => [a] atanhODE :: (C a) => [a] sinhODE :: (C a) => [a] powODE :: (C a) => a -> [a] -- | Lazy evaluation allows for the solution of differential equations in -- terms of power series. Whenever you can express the highest derivative -- of the solution as explicit expression of the lower derivatives where -- each coefficient of the solution series depends only on lower -- coefficients, the recursive algorithm will work. module MathObj.PowerSeries.DifferentialEquation -- | Example for a linear equation: Setup a differential equation for -- y with -- --
--   y   t = (exp (-t)) * (sin t)
--   y'  t = -(exp (-t)) * (sin t) + (exp (-t)) * (cos t)
--   y'' t = -2 * (exp (-t)) * (cos t)
--   
-- -- Thus the differential equation -- --
--   y'' = -2 * (y' + y)
--   
-- -- holds. -- -- The following function generates a power series for exp (-t) * sin -- t by solving the differential equation. solveDiffEq0 :: (C a) => [a] verifyDiffEq0 :: (C a) => [a] propDiffEq0 :: Bool -- | We are not restricted to linear equations! Let the solution be y with -- y t = (1-t)^-1 y' t = (1-t)^-2 y'' t = 2*(1-t)^-3 then it holds y'' = -- 2 * y' * y solveDiffEq1 :: (C a, C a) => [a] verifyDiffEq1 :: (C a, C a) => [a] propDiffEq1 :: Bool -- | Two-variate power series. module MathObj.PowerSeries2 -- | In order to handle both variables equivalently we maintain a list of -- coefficients for terms of the same total degree. That is -- --
--   eval [[a], [b,c], [d,e,f]] (x,y) ==
--      a + b*x+c*y + d*x^2+e*x*y+f*y^2
--   
-- -- Although the sub-lists are always finite and thus are more like -- polynomials than power series, division and square root computation -- are easier to implement for power series. newtype T a Cons :: T a -> T a coeffs :: T a -> T a isValid :: [[a]] -> Bool check :: [[a]] -> [[a]] fromCoeffs :: [[a]] -> T a fromPowerSeries0 :: (C a) => T a -> T a fromPowerSeries1 :: (C a) => T a -> T a lift0 :: T a -> T a lift1 :: (T a -> T a) -> (T a -> T a) lift2 :: (T a -> T a -> T a) -> (T a -> T a -> T a) const :: a -> T a appPrec :: Int instance (Ord a, C a) => Ord (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance C T instance (C a) => C (T a) instance (C a) => C (T a) instance (Eq a, C a) => Eq (T a) instance (Show a) => Show (T a) instance Functor T -- | This module computes power series for representing some means as -- generalized $f$-means. module MathObj.PowerSeries.Mean diffComp :: (C a) => [a] -> [a] -> [a] logarithmic :: (C a) => [a] elemSym3_2 :: (C a) => [a] quadratic :: (C a, Eq a) => [a] quadraticMVF :: (C a) => [a] quadraticDiff :: (C a, Eq a) => [a] quadratic2 :: (C a, Eq a) => T a quadraticDiff2 :: (C a, Eq a) => T a harmonicMVF :: (C a) => [a] harmonic2 :: (C a, Eq a) => T a harmonicDiff2 :: (C a, Eq a) => T a arithmeticMVF :: (C a) => [a] arithmetic2 :: (C a, Eq a) => T a arithmeticDiff2 :: (C a, Eq a) => T a geometricMVF :: (C a) => [a] geometric2 :: (C a, Eq a) => T a geometricDiff2 :: (C a, Eq a) => T a meanValueDiff2 :: (C a, Eq a) => T a -> [a] -> T a -- | For a multi-set of numbers, we describe a sequence of the sums of -- powers of the numbers in the set. These can be easily converted to -- polynomials and back. Thus they provide an easy way for computations -- on the roots of a polynomial. module MathObj.PowerSum newtype T a Cons :: [a] -> T a sums :: T a -> [a] lift0 :: [a] -> T a lift1 :: ([a] -> [a]) -> (T a -> T a) lift2 :: ([a] -> [a] -> [a]) -> (T a -> T a -> T a) const :: (C a) => a -> T a fromElemSym :: (Eq a, C a) => [a] -> [a] divOneFlip :: (Eq a, C a) => [a] -> [a] -> [a] fromElemSymDenormalized :: (C a, C a) => [a] -> [a] toElemSym :: (C a, C a) => [a] -> [a] toElemSymInt :: (C a, C a) => [a] -> [a] fromPolynomial :: (C a, C a) => T a -> [a] elemSymFromPolynomial :: (C a) => T a -> [a] binomials :: (C a) => [[a]] appPrec :: Int add :: (C a) => [a] -> [a] -> [a] mul :: (C a) => [a] -> [a] -> [a] pow :: Integer -> [a] -> [a] root :: (C a) => Integer -> [a] -> [a] approxSeries :: (C a b) => [b] -> [a] -> [b] propOp :: (Eq a, C a, C a) => ([a] -> [a] -> [a]) -> (a -> a -> a) -> [a] -> [a] -> [Bool] instance (C a, C a) => C (T a) instance (C a, C a) => C (T a) instance (C a v, C v) => C a (T v) instance (C a v, C v) => C a (T v) instance (C a) => C (T a) instance (C a) => C (T a) instance (Show a) => Show (T a) -- | Computations on the set of roots of a polynomial. These are -- represented as the list of their elementar symmetric terms. The -- difference between a polynomial and the list of elementar symmetric -- terms is the reversed order and the alternated signs. -- -- Cf. MathObj.PowerSum . module MathObj.RootSet newtype T a Cons :: [a] -> T a coeffs :: T a -> [a] lift0 :: [a] -> T a lift1 :: ([a] -> [a]) -> (T a -> T a) lift2 :: ([a] -> [a] -> [a]) -> (T a -> T a -> T a) const :: (C a) => a -> T a toPolynomial :: T a -> T a fromPolynomial :: T a -> T a toPowerSums :: (C a, C a) => [a] -> [a] fromPowerSums :: (C a, C a) => [a] -> [a] -- | cf. MathObj.Polynomial.mulLinearFactor addRoot :: (C a) => a -> [a] -> [a] fromRoots :: (C a) => [a] -> [a] liftPowerSum1Gen :: ([a] -> [a]) -> ([a] -> [a]) -> ([a] -> [a]) -> ([a] -> [a]) liftPowerSum2Gen :: ([a] -> [a]) -> ([a] -> [a]) -> ([a] -> [a] -> [a]) -> ([a] -> [a] -> [a]) liftPowerSum1 :: (C a, C a) => ([a] -> [a]) -> ([a] -> [a]) liftPowerSum2 :: (C a, C a) => ([a] -> [a] -> [a]) -> ([a] -> [a] -> [a]) liftPowerSumInt1 :: (C a, Eq a, C a) => ([a] -> [a]) -> ([a] -> [a]) liftPowerSumInt2 :: (C a, Eq a, C a) => ([a] -> [a] -> [a]) -> ([a] -> [a] -> [a]) appPrec :: Int add :: (C a, C a) => [a] -> [a] -> [a] addInt :: (C a, Eq a, C a) => [a] -> [a] -> [a] mul :: (C a, C a) => [a] -> [a] -> [a] mulInt :: (C a, Eq a, C a) => [a] -> [a] -> [a] pow :: (C a, C a) => Integer -> [a] -> [a] powInt :: (C a, Eq a, C a) => Integer -> [a] -> [a] instance (C a, C a) => C (T a) instance (C a, C a) => C (T a) instance (C a, C a) => C (T a) instance (C a, C a) => C (T a) instance (Show a) => Show (T a) module Number.ResidueClass sub :: (C a) => a -> a -> a -> a add :: (C a) => a -> a -> a -> a neg :: (C a) => a -> a -> a mul :: (C a) => a -> a -> a -> a -- | The division may be ambiguous. In this case an arbitrary quotient is -- returned. -- --
--   0:4 * 2:4 == 0/:4
--   2:4 * 2:4 == 0/:4
--   
divideMaybe :: (C a) => a -> a -> a -> Maybe a divide :: (C a) => a -> a -> a -> a recip :: (C a) => a -> a -> a -- | This number type is intended for tests of functions over fields, where -- the field elements need constant space. This way we can provide a -- Storable instance. For Rational this would not be possible. -- -- However, be aware that sums of non-zero elements may yield zero. Thus -- division is not always safe, where it is for rational numbers. module Number.GaloisField2p32m5 newtype T Cons :: Word32 -> T decons :: T -> Word32 appPrec :: Int base :: (C a) => a lift2 :: (Word64 -> Word64 -> Word64) -> (T -> T -> T) lift2Integer :: (Int64 -> Int64 -> Int64) -> (T -> T -> T) instance Eq T instance C T T instance C T instance C T instance C T instance Storable T instance Arbitrary T instance Show T -- | Define Transcendental functions on arbitrary fields. These functions -- are defined for only a few (in most cases only one) arguments, that's -- why discourage making these types instances of -- Algebra.Transcendental.C. But instances of -- Algebra.Transcendental.C can be useful when working with -- power series. If you intent to work with power series with -- Rational coefficients, you might consider using -- MathObj.PowerSeries.T (Number.PartiallyTranscendental.T -- Rational) instead of MathObj.PowerSeries.T Rational. module Number.PartiallyTranscendental data T a fromValue :: a -> T a toValue :: T a -> a instance (Eq a) => Eq (T a) instance (Ord a) => Ord (T a) instance (Show a) => Show (T a) instance (Num a) => Fractional (T a) instance (Num a) => Num (T a) instance (C a, Eq a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) module Number.ResidueClass.Check -- | The best solution seems to let modulus be part of the type. -- This could happen with a phantom type for modulus and a run -- function like Control.Monad.ST.runST. Then operations with -- non-matching moduli could be detected at compile time and zero -- and one could be generated with the correct modulus. An -- alternative trial can be found in module ResidueClassMaybe. data T a Cons :: !a -> !a -> T a modulus :: T a -> !a representative :: T a -> !a factorPrec :: Int -- | r /: m is the residue class containing r with -- respect to the modulus m (/:) :: (C a) => a -> a -> T a -- | Check if two residue classes share the same modulus isCompatible :: (Eq a) => T a -> T a -> Bool maybeCompatible :: (Eq a) => T a -> T a -> Maybe a fromRepresentative :: (C a) => a -> a -> T a lift1 :: (Eq a) => (a -> a -> a) -> T a -> T a lift2 :: (Eq a) => (a -> a -> a -> a) -> T a -> T a -> T a errIncompat :: a zero :: (C a) => a -> T a one :: (C a) => a -> T a fromInteger :: (C a) => a -> Integer -> T a instance (Eq a, C a) => C (T a) instance (Eq a, C a) => C (T a) instance (Eq a, C a) => C (T a) instance (C a) => C (T a) instance (Eq a) => Eq (T a) instance (Read a, C a) => Read (T a) instance (Show a) => Show (T a) module Number.ResidueClass.Maybe -- | Here we try to provide implementations for zero and one -- by making the modulus optional. We have to provide non-modulus -- operations for the cases where both operands have Nothing modulus. -- This is problematic since operations like '(/)' depend essentially on -- the modulus. -- -- A working version with disabled zero and one can be -- found ResidueClass. data T a Cons :: !Maybe a -> !a -> T a -- | the modulus can be Nothing to denote a generic constant like -- zero and one which could not be bound to a specific -- modulus so far modulus :: T a -> !Maybe a representative :: T a -> !a -- | r /: m is the residue class containing r with -- respect to the modulus m (/:) :: (C a) => a -> a -> T a matchMaybe :: Maybe a -> Maybe a -> Maybe a isCompatibleMaybe :: (Eq a) => Maybe a -> Maybe a -> Bool -- | Check if two residue classes share the same modulus isCompatible :: (Eq a) => T a -> T a -> Bool lift2 :: (Eq a) => (a -> a -> a -> a) -> (a -> a -> a) -> (T a -> T a -> T a) instance (Show a) => Show (T a) instance (Read a) => Read (T a) instance (Eq a, C a) => C (T a) instance (Eq a, C a) => C (T a) instance (Eq a, C a, C a) => Eq (T a) module Number.ResidueClass.Func -- | Here a residue class is a representative and the modulus is an -- argument. You cannot show a value of type T, you can only show -- it with respect to a concrete modulus. Values cannot be compared, -- because the comparison result depends on the modulus. newtype T a Cons :: (a -> a) -> T a concrete :: a -> T a -> a fromRepresentative :: (C a) => a -> T a lift0 :: (a -> a) -> T a lift1 :: (a -> a -> a) -> T a -> T a lift2 :: (a -> a -> a -> a) -> T a -> T a -> T a zero :: (C a) => T a one :: (C a) => T a fromInteger :: (C a) => Integer -> T a equal :: (Eq a) => a -> T a -> T a -> Bool legacyInstance :: a instance Show (T a) instance Eq (T a) instance (Num a, C a) => Num (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) module Number.ResidueClass.Reader -- | T is a Reader monad but does not need functional dependencies like -- that from the Monad Transformer Library. newtype T a b Cons :: (a -> b) -> T a b toFunc :: T a b -> a -> b concrete :: a -> T a b -> b fromRepresentative :: (C a) => a -> T a a getZero :: (C a) => T a a getOne :: (C a) => T a a fromInteger :: (C a) => Integer -> T a a getAdd :: (C a) => T a (a -> a -> a) getSub :: (C a) => T a (a -> a -> a) getNeg :: (C a) => T a (a -> a) getAdditiveVars :: (C a) => T a (a, a -> a -> a, a -> a -> a, a -> a) getMul :: (C a) => T a (a -> a -> a) getRingVars :: (C a) => T a (a, a -> a -> a) getDivide :: (C a) => T a (a -> a -> a) getRecip :: (C a) => T a (a -> a) getFieldVars :: (C a) => T a (a -> a -> a, a -> a) monadExample :: (C a) => T a [a] runExample :: [Integer] instance Monad (T a) -- | Abstract Physical Units module Number.Physical.Unit -- | A Unit.T is a sparse vector with integer entries Each map n->m -- means that the unit of the n-th dimension is given m times. -- -- Example: Let the quantity of length (meter, m) be the zeroth dimension -- and let the quantity of time (second, s) be the first dimension, then -- the composed unit m_s corresponds to the Map [(0,1),(1,-2)] -- -- In future I want to have more abstraction here, e.g. a type class from -- the Edison project that abstracts from the underlying implementation. -- Then one can easily switch between Arrays, Binary trees (like Map) and -- what know I. type T i = Map i Int -- | The neutral Unit.T scalar :: T i -- | Test for the neutral Unit.T isScalar :: T i -> Bool -- | Convert a List to sparse Map representation Example: [-1,0,-2] -> -- [(0,-1),(2,-2)] fromVector :: (Enum i, Ord i) => [Int] -> T i -- | Convert Map to a List toVector :: (Enum i, Ord i) => T i -> [Int] ratScale :: T Int -> T i -> T i ratScaleMaybe :: T Int -> T i -> Maybe (T i) ratScaleMaybe2 :: T Int -> T i -> Map i (Maybe Int) -- | Tools for creating a data base of physical units and for extracting -- data from it module Number.Physical.UnitDatabase type T i a = [UnitSet i a] data InitUnitSet i a InitUnitSet :: T i -> Bool -> [InitScale a] -> InitUnitSet i a initUnit :: InitUnitSet i a -> T i initIndependent :: InitUnitSet i a -> Bool initScales :: InitUnitSet i a -> [InitScale a] data InitScale a InitScale :: String -> a -> Bool -> Bool -> InitScale a initSymbol :: InitScale a -> String initMag :: InitScale a -> a initIsUnit :: InitScale a -> Bool initDefault :: InitScale a -> Bool -- | An entry for a unit and there scalings. data UnitSet i a UnitSet :: T i -> Bool -> Int -> Bool -> [Scale a] -> UnitSet i a unit :: UnitSet i a -> T i independent :: UnitSet i a -> Bool defScaleIx :: UnitSet i a -> Int -- | If True the symbols must be preceded with a /. Though it sounds -- like an attribute of Scale it must be the same for all scales and we -- need it to sort positive powered unitsets to the front of the list of -- unit components. reciprocal :: UnitSet i a -> Bool scales :: UnitSet i a -> [Scale a] -- | A common scaling for a unit. data Scale a Scale :: String -> a -> Scale a symbol :: Scale a -> String magnitude :: Scale a -> a extractOne :: [a] -> a initScale :: String -> a -> Bool -> Bool -> InitScale a initUnitSet :: T i -> Bool -> [InitScale a] -> InitUnitSet i a createScale :: InitScale a -> Scale a createUnitSet :: InitUnitSet i a -> UnitSet i a showableUnit :: InitUnitSet i a -> Maybe (InitUnitSet i a) -- | Raise all scales of a unit and the unit itself to the n-th power powerOfUnitSet :: (Ord i, C a) => Int -> UnitSet i a -> UnitSet i a powerOfScale :: (C a) => Int -> Scale a -> Scale a showExp :: Int -> String -- | Reorder the unit components in a way that the units with positive -- exponents lead the list. positiveToFront :: [UnitSet i a] -> [UnitSet i a] -- | Decompose a complex unit into common ones decompose :: (Ord i, C a) => T i -> T i a -> [UnitSet i a] findIndep :: (Eq i) => T i -> T i a -> Maybe (UnitSet i a) findClosest :: (Ord i, C a) => T i -> T i a -> UnitSet i a evalDist :: (Ord i, C a) => T i -> T i a -> [(UnitSet i a, Int)] findBestExp :: (Ord i) => T i -> T i -> (Int, Int) -- | Find the exponent that lead to minimal distance Since the list is -- infinite maximum will fail but the sequence is convex and thus -- we can abort when the distance stop falling findMinExp :: [(Int, Int)] -> (Int, Int) distLE :: (Int, Int) -> (Int, Int) -> Bool distances :: (Ord i) => T i -> [(Int, T i)] -> [(Int, Int)] listMultiples :: (T i -> T i) -> Int -> [(Int, T i)] instance (Show a) => Show (Scale a) instance (Show i, Show a) => Show (UnitSet i a) -- | Special physical units: SI unit system module Number.SI.Unit data Dimension Length :: Dimension Time :: Dimension Mass :: Dimension Charge :: Dimension Angle :: Dimension Temperature :: Dimension Information :: Dimension -- | Some common quantity classes. angularSpeed :: T Dimension length :: T Dimension distance :: T Dimension area :: T Dimension volume :: T Dimension time :: T Dimension frequency :: T Dimension speed :: T Dimension acceleration :: T Dimension mass :: T Dimension force :: T Dimension pressure :: T Dimension energy :: T Dimension power :: T Dimension charge :: T Dimension current :: T Dimension voltage :: T Dimension resistance :: T Dimension capacitance :: T Dimension temperature :: T Dimension information :: T Dimension dataRate :: T Dimension angle :: T Dimension fourth :: (C a) => a half :: (C a) => a threeFourth :: (C a) => a percent :: (C a) => a secondsPerHour :: (C a) => a secondsPerDay :: (C a) => a secondsPerYear :: (C a) => a meterPerInch :: (C a) => a meterPerFoot :: (C a) => a meterPerYard :: (C a) => a meterPerAstronomicUnit :: (C a) => a meterPerParsec :: (C a) => a accelerationOfEarthGravity :: (C a) => a k2 :: (C a) => a deg180 :: (C a) => a grad200 :: (C a) => a bytesize :: (C a) => a secondsPerMinute :: (C a) => a radPerGrad :: (C a) => a radPerDeg :: (C a) => a speedOfLight :: (C a) => a electronVolt :: (C a) => a calorien :: (C a) => a horsePower :: (C a) => a mach :: (C a) => a zepto :: (C a) => a atto :: (C a) => a femto :: (C a) => a pico :: (C a) => a nano :: (C a) => a micro :: (C a) => a milli :: (C a) => a centi :: (C a) => a deci :: (C a) => a one :: (C a) => a deca :: (C a) => a hecto :: (C a) => a kilo :: (C a) => a mega :: (C a) => a giga :: (C a) => a tera :: (C a) => a peta :: (C a) => a exa :: (C a) => a zetta :: (C a) => a yotta :: (C a) => a yocto :: (C a) => a -- | Common constants -- -- Conversion factors -- -- Physical constants -- -- Prefixes used for SI units -- -- UnitDatabase.T of units and their common scalings databaseShow :: (C a) => T Dimension a databaseRead :: (C a) => T Dimension a database :: (C a) => [InitUnitSet Dimension a] instance Eq Dimension instance Ord Dimension instance Enum Dimension instance Show Dimension -- | Complex numbers. module Number.Complex -- | Complex numbers are an algebraic type. data T a imaginaryUnit :: (C a) => T a fromReal :: (C a) => a -> T a -- | Construct a complex number from real and imaginary part. (+:) :: a -> a -> T a -- | Construct a complex number with negated imaginary part. (-:) :: (C a) => a -> a -> T a -- | Scale a complex number by a real number. scale :: (C a) => a -> T a -> T a -- | Exponential of a complex number with minimal type class constraints. exp :: (C a) => T a -> T a -- | Turn the point one quarter to the right. quarterLeft :: (C a) => T a -> T a quarterRight :: (C a) => T a -> T a -- | Form a complex number from polar components of magnitude and phase. fromPolar :: (C a) => a -> a -> T a -- | cis t is a complex value with magnitude 1 and -- phase t (modulo 2*pi). cis :: (C a) => a -> T a -- | Scale a complex number to magnitude 1. -- -- For a complex number z, abs z is a number -- with the magnitude of z, but oriented in the positive real -- direction, whereas signum z has the phase of -- z, but unit magnitude. signum :: (C a, C a) => T a -> T a signumNorm :: (C a, C a a, C a) => T a -> T a -- | The function toPolar takes a complex number and returns a -- (magnitude, phase) pair in canonical form: the magnitude is -- nonnegative, and the phase in the range (-pi, -- pi]; if the magnitude is zero, then so is the phase. toPolar :: (C a) => T a -> (a, a) magnitude :: (C a) => T a -> a magnitudeSqr :: (C a) => T a -> a -- | The phase of a complex number, in the range (-pi, -- pi]. If the magnitude is zero, then so is the phase. phase :: (C a, C a) => T a -> a -- | The conjugate of a complex number. conjugate :: (C a) => T a -> T a propPolar :: (C a) => T a -> Bool -- | We like to build the Complex Algebraic instance on top of the -- Algebraic instance of the scalar type. This poses no problem to -- sqrt. However, Number.Complex.root requires computing -- the complex argument which is a transcendent operation. In order to -- keep the type class dependencies clean for more sophisticated -- algebraic number types, we introduce a type class which actually -- performs the radix operation. class (C a) => Power a power :: (Power a) => Rational -> T a -> T a defltPow :: (C a) => Rational -> T a -> T a instance (Eq a) => Eq (T a) instance (C a, Eq a, Show a) => Fractional (T a) instance (C a, Eq a, Show a) => Num (T a) instance (C a, C a, Power a) => C (T a) instance (C a, C a, Power a) => C (T a) instance Power Double instance Power Float instance (C a) => C (T a) instance (Ord a, C a, C a) => C (T a) instance (Ord a, C a) => C (T a) instance (C a) => C (T a) instance (Ord a, C a v) => C a (T v) instance (C a, Sqr a b) => C a (T b) instance (Sqr a b) => Sqr a (T b) instance (C a, C a v) => C a (T v) instance (C a b) => C a (T b) instance (C a b) => C a (T b) instance C T instance (C a, C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance (Storable a) => Storable (T a) instance (Arbitrary a) => Arbitrary (T a) instance (Read a) => Read (T a) instance (Show a) => Show (T a) -- | There are several types of numbers where a subset of numbers can be -- considered as set of scalars. -- -- -- -- Of course this can be cascaded, e.g. a complex number with physical -- units can be converted to a scalar if there is both no imaginary part -- and no unit. -- -- This is somewhat similar to the multi-type classes NormedMax.C and -- friends. -- -- I hesitate to define an instance for lists to avoid the mess known of -- MatLab. But if you have an application where you think you need this -- instance definitely I'll think about that, again. module Algebra.OccasionallyScalar class C a v toScalar :: (C a v) => v -> a toMaybeScalar :: (C a v) => v -> Maybe a fromScalar :: (C a v) => a -> v toScalarDefault :: (C a v) => v -> a toScalarShow :: (C a v, Show v) => v -> a instance (Show v, C v, C v, C a v) => C a (T v) instance C Double Double instance C Float Float -- | Polynomials with negative and positive exponents. module MathObj.LaurentPolynomial -- | Polynomial including negative exponents data T a Cons :: Int -> [a] -> T a expon :: T a -> Int coeffs :: T a -> [a] const :: a -> T a (!) :: (C a) => T a -> Int -> a fromCoeffs :: [a] -> T a fromShiftCoeffs :: Int -> [a] -> T a fromPolynomial :: T a -> T a fromPowerSeries :: T a -> T a bounds :: T a -> (Int, Int) shift :: Int -> T a -> T a translate :: Int -> T a -> T a appPrec :: Int add :: (C a) => T a -> T a -> T a series :: (C a) => [T a] -> T a -- | Add lists of numbers respecting a relative shift between the starts of -- the lists. The shifts must be non-negative. The list of relative -- shifts is one element shorter than the list of summands. Infinitely -- many summands are permitted, provided that runs of zero shifts are all -- finite. -- -- We could add the lists either with foldl or with foldr, -- foldl would be straightforward, but more time consuming -- (quadratic time) whereas foldr is not so obvious but needs only linear -- time. -- -- (stars denote the coefficients, frames denote what is contained in the -- interim results) foldl sums this way: -- --
--   | | | *******************************
--   | | +--------------------------------
--   | |          ************************
--   | +----------------------------------
--   |                        ************
--   +------------------------------------
--   
-- -- I.e. foldl would use much time find the time differences by -- successive subtraction 1. -- -- foldr mixes this way: -- --
--   +--------------------------------
--   | *******************************
--   |      +-------------------------
--   |      | ************************
--   |      |           +-------------
--   |      |           | ************
--   
addShiftedMany :: (C a) => [Int] -> [[a]] -> [a] addShifted :: (C a) => Int -> [a] -> [a] -> [a] negate :: (C a) => T a -> T a sub :: (C a) => T a -> T a -> T a mul :: (C a) => T a -> T a -> T a div :: (C a, C a) => T a -> T a -> T a divExample :: T Rational -- | Two polynomials may be stored differently. This function checks -- whether two values of type LaurentPolynomial actually -- represent the same polynomial. equivalent :: (Eq a, C a) => T a -> T a -> Bool identical :: (Eq a) => T a -> T a -> Bool -- | Check whether a Laurent polynomial has only the absolute term, that -- is, it represents the constant polynomial. isAbsolute :: (C a) => T a -> Bool -- | p(z) -> p(-z) alternate :: (C a) => T a -> T a -- | p(z) -> p(1/z) reverse :: T a -> T a -- | p(exp(ix)) -> conjugate(p(exp(ix))) -- -- If you interpret (p*) as a linear operator on the space of -- Laurent polynomials, then (adjoint p *) is the adjoint -- operator. adjoint :: (C a) => T (T a) -> T (T a) instance (Eq a, C a) => Eq (T a) instance (C a, C a) => C (T a) instance (C a) => C (T a) instance (C a, C a b) => C a (T b) instance (C a b) => C a (T b) instance C T instance (C a) => C (T a) instance (Show a) => Show (T a) instance Functor T -- | Exact Real Arithmetic - Computable reals. Inspired by ''The most -- unreliable technique for computing pi.'' See also -- http://www.haskell.org/haskellwiki/Exact_real_arithmetic . module Number.Positional type T = (Exponent, Mantissa) type FixedPoint = (Integer, Mantissa) type Mantissa = [Digit] type Digit = Int type Exponent = Int type Basis = Int moveToZero :: Basis -> Digit -> (Digit, Digit) checkPosDigit :: Basis -> Digit -> Digit checkDigit :: Basis -> Digit -> Digit -- | Converts all digits to non-negative digits, that is the usual -- positional representation. However the conversion will fail when the -- remaining digits are all zero. (This cannot be improved!) nonNegative :: Basis -> T -> T -- | Requires, that no digit is (basis-1) or (1-basis). -- The leading digit might be negative and might be -basis or -- basis. nonNegativeMant :: Basis -> Mantissa -> Mantissa -- | May prepend a digit. compress :: Basis -> T -> T -- | Compress first digit. May prepend a digit. compressFirst :: Basis -> T -> T -- | Does not prepend a digit. compressMant :: Basis -> Mantissa -> Mantissa -- | Compress second digit. Sometimes this is enough to keep the digits in -- the admissible range. Does not prepend a digit. compressSecondMant :: Basis -> Mantissa -> Mantissa prependDigit :: Basis -> T -> T -- | Eliminate leading zero digits. This will fail for zero. trim :: T -> T -- | Trim until a minimum exponent is reached. Safe for zeros. trimUntil :: Exponent -> T -> T trimOnce :: T -> T -- | Accept a high leading digit for the sake of a reduced exponent. This -- eliminates one leading digit. Like pumpFirst but with exponent -- management. decreaseExp :: Basis -> T -> T -- | Merge leading and second digit. This is somehow an inverse of -- compressMant. pumpFirst :: Basis -> Mantissa -> Mantissa decreaseExpFP :: Basis -> (Exponent, FixedPoint) -> (Exponent, FixedPoint) pumpFirstFP :: Basis -> FixedPoint -> FixedPoint -- | Make sure that a number with absolute value less than 1 has a (small) -- negative exponent. Also works with zero because it chooses an -- heuristic exponent for stopping. negativeExp :: Basis -> T -> T fromBaseCardinal :: Basis -> Integer -> T fromBaseInteger :: Basis -> Integer -> T mantissaToNum :: (C a) => Basis -> Mantissa -> a mantissaFromCard :: (C a) => Basis -> a -> Mantissa mantissaFromInt :: (C a) => Basis -> a -> Mantissa mantissaFromFixedInt :: Basis -> Exponent -> Integer -> Mantissa fromBaseRational :: Basis -> Rational -> T -- | Split into integer and fractional part. toFixedPoint :: Basis -> T -> FixedPoint fromFixedPoint :: Basis -> FixedPoint -> T toDouble :: Basis -> T -> Double -- | cf. Numeric.floatToDigits fromDouble :: Basis -> Double -> T -- | Only return as much digits as are contained in Double. This will -- speedup further computations. fromDoubleApprox :: Basis -> Double -> T fromDoubleRough :: Basis -> Double -> T mantLengthDouble :: Basis -> Exponent liftDoubleApprox :: Basis -> (Double -> Double) -> T -> T liftDoubleRough :: Basis -> (Double -> Double) -> T -> T -- | Show a number with respect to basis 10^e. showDec :: Exponent -> T -> String showHex :: Exponent -> T -> String showBin :: Exponent -> T -> String showBasis :: Basis -> Exponent -> T -> String -- | Convert from a b basis representation to a b^e -- basis. -- -- Works well with every exponent. powerBasis :: Basis -> Exponent -> T -> T -- | Convert from a b^e basis representation to a b -- basis. -- -- Works well with every exponent. rootBasis :: Basis -> Exponent -> T -> T -- | Convert between arbitrary bases. This conversion is expensive -- (quadratic time). fromBasis :: Basis -> Basis -> T -> T fromBasisMant :: Basis -> Basis -> Mantissa -> Mantissa -- | The basis must be at least ***. Note: Equality cannot be asserted in -- finite time on infinite precise numbers. If you want to assert, that a -- number is below a certain threshold, you should not call this routine -- directly, because it will fail on equality. Better round the numbers -- before comparison. cmp :: Basis -> T -> T -> Ordering lessApprox :: Basis -> Exponent -> T -> T -> Bool trunc :: Exponent -> T -> T equalApprox :: Basis -> Exponent -> T -> T -> Bool -- | If all values are completely defined, then it holds -- --
--   if b then x else y == ifLazy b x y
--   
-- -- However if b is undefined, then it is at least known that the -- result is between x and y. ifLazy :: Basis -> Bool -> T -> T -> T -- |
--   mean2 b (x0,x1) (y0,y1)
--   
-- -- computes round ((x0.x1 + y0.y1)/2) , where x0.x1 -- and y0.y1 are positional rational numbers with respect to -- basis b mean2 :: Basis -> (Digit, Digit) -> (Digit, Digit) -> Digit withTwoMantissas :: Mantissa -> Mantissa -> a -> ((Digit, Mantissa) -> (Digit, Mantissa) -> a) -> a align :: Basis -> Exponent -> T -> T -- | Get the mantissa in such a form that it fits an expected exponent. -- -- x and (e, alignMant b e x) represent the same -- number. alignMant :: Basis -> Exponent -> T -> Mantissa absolute :: T -> T absMant :: Mantissa -> Mantissa fromLaurent :: T Int -> T toLaurent :: T -> T Int liftLaurent2 :: (T Int -> T Int -> T Int) -> (T -> T -> T) liftLaurentMany :: ([T Int] -> T Int) -> ([T] -> T) -- | Add two numbers but do not eliminate leading zeros. add :: Basis -> T -> T -> T sub :: Basis -> T -> T -> T neg :: Basis -> T -> T -- | Add at most basis summands. More summands will violate the -- allowed digit range. addSome :: Basis -> [T] -> T -- | Add many numbers efficiently by computing sums of sub lists with only -- little carry propagation. addMany :: Basis -> [T] -> T type Series = [(Exponent, T)] -- | Add an infinite number of numbers. You must provide a list of estimate -- of the current remainders. The estimates must be given as exponents of -- the remainder. If such an exponent is too small, the summation will be -- aborted. If exponents are too big, computation will become -- inefficient. series :: Basis -> Series -> T seriesPlain :: Basis -> Series -> T -- | Like splitAt, but it pads with zeros if the list is too short. -- This way it preserves length (fst (splitAtPadZero n xs)) == n -- splitAtPadZero :: Int -> Mantissa -> (Mantissa, Mantissa) splitAtMatchPadZero :: [()] -> Mantissa -> (Mantissa, Mantissa) -- | help showing series summands truncSeriesSummands :: Series -> Series scale :: Basis -> Digit -> T -> T scaleSimple :: Basis -> T -> T scaleMant :: Basis -> Digit -> Mantissa -> Mantissa mulSeries :: Basis -> T -> T -> Series -- | For obtaining n result digits it is mathematically sufficient to know -- the first (n+1) digits of the operands. However this implementation -- needs (n+2) digits, because of calls to compress in both -- scale and series. We should fix that. mul :: Basis -> T -> T -> T -- | Undefined if the divisor is zero - of course. Because it is impossible -- to assert that a real is zero, the routine will not throw an error in -- general. -- -- ToDo: Rigorously derive the minimal required magnitude of the leading -- divisor digit. divide :: Basis -> T -> T -> T divMant :: Basis -> Mantissa -> Mantissa -> Mantissa divMantSlow :: Basis -> Mantissa -> Mantissa -> Mantissa reciprocal :: Basis -> T -> T -- | Fast division for small integral divisors, which occur for instance in -- summands of power series. divIntMant :: Basis -> Int -> Mantissa -> Mantissa divIntMantInf :: Basis -> Int -> Mantissa -> Mantissa divInt :: Basis -> Digit -> T -> T sqrt :: Basis -> T -> T sqrtDriver :: Basis -> (Basis -> FixedPoint -> Mantissa) -> T -> T sqrtMant :: Basis -> Mantissa -> Mantissa -- | Square root. -- -- We need a leading digit of type Integer, because we have to collect up -- to 4 digits. This presentation can also be considered as -- FixedPoint. -- -- ToDo: Rigorously derive the minimal required magnitude of the leading -- digit of the root. -- -- Mathematically the nth digit of the square root depends -- roughly only on the first n digits of the input. This is -- because sqrt (1+eps) equalApprox 1 + eps/2. However -- this implementation requires 2*n input digits for emitting -- n digits. This is due to the repeated use of -- compressMant. It would suffice to fully compress only every -- basisth iteration (digit) and compress only the second -- leading digit in each iteration. -- -- Can the involved operations be made lazy enough to solve y = -- (x+frac)^2 by frac = (y-x^2-frac^2) / (2*x) ? sqrtFP :: Basis -> FixedPoint -> Mantissa sqrtNewton :: Basis -> T -> T -- | Newton iteration doubles the number of correct digits in every step. -- Thus we process the data in chunks of sizes of powers of two. This way -- we get fastest computation possible with Newton but also more -- dependencies on input than necessary. The question arises whether this -- implementation still fits the needs of computational reals. The input -- is requested as larger and larger chunks, and the input itself might -- be computed this way, e.g. a repeated square root. Requesting one -- digit too much, requires the double amount of work for the input -- computation, which in turn multiplies time consumption by a factor of -- four, and so on. -- -- Optimal fast implementation of one routine does not preserve fast -- computation of composed computations. -- -- The routine assumes, that the integer parts is at least b^2. sqrtFPNewton :: Basis -> FixedPoint -> Mantissa -- | List.inits is defined by inits = foldr (x ys -> [] : map (x:) -- ys) [[]] -- -- This is too strict for our application. -- --
--   Prelude> List.inits (0:1:2:undefined)
--   [[],[0],[0,1]*** Exception: Prelude.undefined
--   
-- -- The following routine is more lazy than inits and even lazier -- than Data.List.HT.inits from utility-ht package, but -- it is restricted to infinite lists. This degree of laziness is needed -- for sqrtFP. -- --
--   Prelude> lazyInits (0:1:2:undefined)
--   [[],[0],[0,1],[0,1,2],[0,1,2,*** Exception: Prelude.undefined
--   
lazyInits :: [a] -> [[a]] expSeries :: Basis -> T -> Series -- | Absolute value of argument should be below 1. expSmall :: Basis -> T -> T expSeriesLazy :: Basis -> T -> Series expSmallLazy :: Basis -> T -> T exp :: Basis -> T -> T intPower :: Basis -> Integer -> T -> T -> T -> T cardPower :: Basis -> Integer -> T -> T -> T -- | Residue estimates will only hold for exponents with absolute value -- below one. -- -- The computation is based on Int, thus the denominator should -- not be too big. (Say, at most 1000 for 1000000 digits.) -- -- It is not optimal to split the power into pure root and pure power -- (that means, with integer exponents). The root series can nicely -- handle all exponents, but for exponents above 1 the series summands -- rises at the beginning and thus make the residue estimate complicated. -- For powers with integer exponents the root series turns into the -- binomial formula, which is just a complicated way to compute a power -- which can also be determined by simple multiplication. powerSeries :: Basis -> Rational -> T -> Series powerSmall :: Basis -> Rational -> T -> T power :: Basis -> Rational -> T -> T root :: Basis -> Integer -> T -> T -- | Absolute value of argument should be below 1. cosSinhSmall :: Basis -> T -> (T, T) -- | Absolute value of argument should be below 1. cosSinSmall :: Basis -> T -> (T, T) -- | Like cosSinSmall but converges faster. It calls -- cosSinSmall with reduced arguments using the trigonometric -- identities cos (4*x) = 8 * cos x ^ 2 * (cos x ^ 2 - 1) + 1 sin -- (4*x) = 4 * sin x * cos x * (1 - 2 * sin x ^ 2) -- -- Note that the faster convergence is hidden by the overhead. -- -- The same could be achieved with a fourth power of a complex number. cosSinFourth :: Basis -> T -> (T, T) cosSin :: Basis -> T -> (T, T) tan :: Basis -> T -> T cot :: Basis -> T -> T lnSeries :: Basis -> T -> Series lnSmall :: Basis -> T -> T -- |
--   x' = x - (exp x - y) / exp x
--      = x + (y * exp (-x) - 1)
--   
-- -- First, the dependencies on low-significant places are currently much -- more than mathematically necessary. Check *Number.Positional> -- expSmall 1000 (-1,100 : replicate 16 0 ++ [undefined]) -- (0,[1,105,171,-82,76*** Exception: Prelude.undefined Every -- multiplication cut off two trailing digits. -- *Number.Positional> nest 8 (mul 1000 (-1,repeat 1)) (-1,100 : -- replicate 16 0 ++ [undefined]) (-9,[101,*** Exception: -- Prelude.undefined -- -- Possibly the dependencies of expSmall could be resolved by not -- computing mul immediately but computing mul series -- which are merged and subsequently added. But this would lead to an -- explosion of series. -- -- Second, even if the dependencies of all atomic operations are reduced -- to a minimum, the mathematical dependencies of the whole iteration -- function are less than the sums of the parts. Lets demonstrate this -- with the square root iteration. It is (1.4140 + 21.4140) -- 2 == 1.414213578500707 (1.4149 + 21.4149) 2 == -- 1.4142137288854335 That is, the digits 213 do not -- depend mathematically on x of 1.414x, but their -- computation depends. Maybe there is a glorious trick to reduce the -- computational dependencies to the mathematical ones. lnNewton :: Basis -> T -> T lnNewton' :: Basis -> T -> T ln :: Basis -> T -> T -- | This is an inverse of cosSin, also known as atan2 with -- flipped arguments. It's very slow because of the computation of sinus -- and cosinus. However, because it uses the atan2 implementation -- as estimator, the final application of arctan series should converge -- rapidly. -- -- It could be certainly accelerated by not using cosSin and its fiddling -- with pi. Instead we could analyse quadrants before calling atan2, then -- calling cosSinSmall immediately. angle :: Basis -> (T, T) -> T -- | Arcus tangens of arguments with absolute value less than 1 / sqrt -- 3. arctanSeries :: Basis -> T -> Series arctanSmall :: Basis -> T -> T -- | Efficient computation of Arcus tangens of an argument of the form -- 1/n. arctanStem :: Basis -> Int -> T -- | This implementation gets the first decimal place for free by calling -- the arcus tangens implementation for Doubles. arctan :: Basis -> T -> T -- | A classic implementation without ''cheating'' with floating point -- implementations. -- -- For x < 1 / sqrt 3 (1 / sqrt 3 == tan (pi/6)) use -- arctan power series. (sqrt 3 is approximately -- 19/11.) -- -- For x > sqrt 3 use arctan x = pi/2 - arctan (1/x) -- -- For other x use -- -- arctan x = pi/4 - 0.5*arctan ((1-x^2)/2*x) (which follows -- from arctan x + arctan y == arctan ((x+y) / (1-x*y)) which in -- turn follows from complex multiplication (1:+x)*(1:+y) == -- ((1-x*y):+(x+y)) -- -- If x is close to sqrt 3 or 1 / sqrt 3 the -- computation is quite inefficient. arctanClassic :: Basis -> T -> T zero :: T one :: T minusOne :: T eConst :: Basis -> T recipEConst :: Basis -> T piConst :: Basis -> T sliceVertPair :: [a] -> [(a, a)] -- | Quaternions module Number.Quaternion -- | Quaternions could be defined based on Complex numbers. However -- quaternions are often considered as real part and three imaginary -- parts. data T a fromReal :: (C a) => a -> T a -- | Construct a quaternion from real and imaginary part. (+::) :: a -> (a, a, a) -> T a -- | Let c be a unit quaternion, then it holds similarity c -- (0+::x) == toRotationMatrix c * x toRotationMatrix :: (C a) => T a -> Array (Int, Int) a fromRotationMatrix :: (C a) => Array (Int, Int) a -> T a -- | The rotation matrix must be normalized. (I.e. no rotation with -- scaling) The computed quaternion is not normalized. fromRotationMatrixDenorm :: (C a) => Array (Int, Int) a -> T a -- | Map a quaternion to complex valued 2x2 matrix, such that quaternion -- addition and multiplication is mapped to matrix addition and -- multiplication. The determinant of the matrix equals the squared -- quaternion norm (normSqr). Since complex numbers can be turned -- into real (orthogonal) matrices, a quaternion could also be converted -- into a real matrix. toComplexMatrix :: (C a) => T a -> Array (Int, Int) (T a) -- | Revert toComplexMatrix. fromComplexMatrix :: (C a) => Array (Int, Int) (T a) -> T a scalarProduct :: (C a) => (a, a, a) -> (a, a, a) -> a crossProduct :: (C a) => (a, a, a) -> (a, a, a) -> (a, a, a) -- | The conjugate of a quaternion. conjugate :: (C a) => T a -> T a -- | Scale a quaternion by a real number. scale :: (C a) => a -> T a -> T a norm :: (C a) => T a -> a -- | the same as NormedEuc.normSqr but with a simpler type class constraint normSqr :: (C a) => T a -> a -- | scale a quaternion into a unit quaternion normalize :: (C a) => T a -> T a -- | similarity mapping as needed for rotating 3D vectors -- -- It holds similarity (cos(a/2) +:: scaleImag (sin(a/2)) v) (0 +:: -- x) == (0 +:: y) where y results from rotating x -- around the axis v by the angle a. similarity :: (C a) => T a -> T a -> T a -- | Spherical Linear Interpolation -- -- Can be generalized to any transcendent Hilbert space. In fact, we -- should also include the real part in the interpolation. slerp :: (C a) => a -> (a, a, a) -> (a, a, a) -> (a, a, a) instance (Eq a) => Eq (T a) instance (C a b) => C a (T b) instance (C a b) => C a (T b) instance C T instance (C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance (C a, Sqr a b) => C a (T b) instance (Sqr a b) => Sqr a (T b) instance (Read a) => Read (T a) instance (Show a) => Show (T a) module MathObj.RefinementMask2 data T a coeffs :: T a -> [a] fromCoeffs :: [a] -> T a -- | Determine mask by Gauss elimination. -- -- R - alternating binomial coefficients L - differences of translated -- polynomials in columns -- -- p2 = L * R^(-1) * m -- -- R * L^(-1) * p2 = m fromPolynomial :: (C a) => T a -> T a -- | If the mask does not sum up to a power of 1/2 then the -- function returns Nothing. toPolynomial :: (C a) => T a -> Maybe (T a) toPolynomialFast :: (C a) => T a -> Maybe (T a) refinePolynomial :: (C a) => T a -> T a -> T a instance (Arbitrary a, C a) => Arbitrary (T a) instance (Show a) => Show (T a) instance Functor T -- | Fixed point numbers. They are implemented as ratios with fixed -- denominator. Many routines fail for some arguments. When they work, -- they can be useful for obtaining approximations of some constants. We -- have not paid attention to rounding errors and thus some of the -- trailing digits may be wrong. module Number.FixedPoint fromFloat :: (C a) => Integer -> a -> Integer -- | denominator conversion fromFixedPoint :: Integer -> Integer -> Integer -> Integer -- | very efficient because it can make use of the decimal output of -- show showPositionalDec :: Integer -> Integer -> String showPositionalHex :: Integer -> Integer -> String showPositionalBin :: Integer -> Integer -> String showPositionalBasis :: Integer -> Integer -> Integer -> String liftShowPosToInt :: (Integer -> String) -> (Integer -> String) toPositional :: Integer -> Integer -> Integer -> (Integer, [Integer]) add :: Integer -> Integer -> Integer -> Integer sub :: Integer -> Integer -> Integer -> Integer mul :: Integer -> Integer -> Integer -> Integer divide :: Integer -> Integer -> Integer -> Integer recip :: Integer -> Integer -> Integer magnitudes :: [Integer] sqrt :: Integer -> Integer -> Integer root :: Integer -> Integer -> Integer -> Integer evalPowerSeries :: [Rational] -> Integer -> Integer -> Integer sin :: Integer -> Integer -> Integer tan :: Integer -> Integer -> Integer cos :: Integer -> Integer -> Integer arctanSmall :: Integer -> Integer -> Integer arctan :: Integer -> Integer -> Integer piConst :: Integer -> Integer expSmall :: Integer -> Integer -> Integer eConst :: Integer -> Integer recipEConst :: Integer -> Integer exp :: Integer -> Integer -> Integer approxLogBase :: Integer -> Integer -> (Int, Integer) lnSmall :: Integer -> Integer -> Integer ln :: Integer -> Integer -> Integer -- | See Algebra.DimensionTerm. module Number.DimensionTerm newtype T u a Cons :: a -> T u a fromNumber :: a -> Scalar a toNumber :: Scalar a -> a fromNumberWithDimension :: (C u) => u -> a -> T u a toNumberWithDimension :: (C u) => u -> T u a -> a (&*&) :: (C u, C v, C a) => T u a -> T v a -> T (Mul u v) a (&/&) :: (C u, C v, C a) => T u a -> T v a -> T (Mul u (Recip v)) a mulToScalar :: (C u, C a) => T u a -> T (Recip u) a -> a divToScalar :: (C u, C a) => T u a -> T u a -> a cancelToScalar :: (C u) => T (Mul u (Recip u)) a -> a recip :: (C u, C a) => T u a -> T (Recip u) a unrecip :: (C u, C a) => T (Recip u) a -> T u a sqr :: (C u, C a) => T u a -> T (Sqr u) a sqrt :: (C u, C a) => T (Sqr u) a -> T u a abs :: (C u, C a) => T u a -> T u a absSignum :: (C u, C a) => T u a -> (T u a, a) (*&) :: (C u, C a) => a -> T u a -> T u a scale :: (C u, C a) => a -> T u a -> T u a rewriteDimension :: (C u, C v) => (u -> v) -> T u a -> T v a type Scalar a = T Scalar a type Length a = T Length a type Time a = T Time a type Mass a = T Mass a type Charge a = T Charge a type Angle a = T Angle a type Temperature a = T Temperature a type Information a = T Information a type Frequency a = T Frequency a type Voltage a = T Voltage a scalar :: a -> Scalar a length :: a -> Length a time :: a -> Time a mass :: a -> Mass a charge :: a -> Charge a frequency :: a -> Frequency a angle :: a -> Angle a temperature :: a -> Temperature a information :: a -> Information a voltage :: a -> Voltage a instance (Eq a) => Eq (T u a) instance (Ord a) => Ord (T u a) instance (C u, Random a) => Random (T u a) instance (IsScalar u, C a b) => C a (T u b) instance (IsScalar u, C a) => C (T u a) instance (IsScalar u, C a) => C (T u a) instance (C u, C a b) => C a (T u b) instance (C u, C a) => C (T u a) instance (C u, Show a) => Show (T u a) -- | Special physical units: SI unit system module Number.DimensionTerm.SI second :: (C a) => Time a minute :: (C a) => Time a hour :: (C a) => Time a day :: (C a) => Time a year :: (C a) => Time a hertz :: (C a) => Frequency a meter :: (C a) => Length a gramm :: (C a) => Mass a tonne :: (C a) => Mass a coulomb :: (C a) => Charge a volt :: (C a) => Voltage a kelvin :: (C a) => Temperature a bit :: (C a) => Information a byte :: (C a) => Information a inch :: (C a) => Length a foot :: (C a) => Length a yard :: (C a) => Length a astronomicUnit :: (C a) => Length a parsec :: (C a) => Length a yocto :: (C a) => a zepto :: (C a) => a atto :: (C a) => a femto :: (C a) => a pico :: (C a) => a nano :: (C a) => a micro :: (C a) => a milli :: (C a) => a centi :: (C a) => a deci :: (C a) => a one :: (C a) => a deca :: (C a) => a hecto :: (C a) => a kilo :: (C a) => a mega :: (C a) => a giga :: (C a) => a tera :: (C a) => a peta :: (C a) => a exa :: (C a) => a zetta :: (C a) => a yotta :: (C a) => a module Number.FixedPoint.Check data T Cons :: Integer -> Integer -> T denominator :: T -> Integer numerator :: T -> Integer cons :: Integer -> Integer -> T fromFloat :: (C a) => Integer -> a -> T fromInteger' :: Integer -> Integer -> T fromRational' :: Integer -> Rational -> T fromFloatBasis :: (C a) => Integer -> Int -> a -> T fromIntegerBasis :: Integer -> Int -> Integer -> T fromRationalBasis :: Integer -> Int -> Rational -> T -- | denominator conversion fromFixedPoint :: Integer -> T -> T lift0 :: Integer -> (Integer -> Integer) -> T lift1 :: (Integer -> Integer -> Integer) -> (T -> T) lift2 :: (Integer -> Integer -> Integer -> Integer) -> (T -> T -> T) commonDenominator :: Integer -> Integer -> a -> a appPrec :: Int defltDenominator :: Integer defltShow :: T -> String legacyInstance :: a instance Fractional T instance Num T instance C T instance C T instance Ord T instance Eq T instance C T instance C T instance C T instance C T instance C T instance C T instance Show T -- | A type for non-negative numbers. It performs a run-time check at -- construction time (i.e. at run-time) and is a member of the -- non-negative number type class Numeric.NonNegative.Class.C. module Number.NonNegative data T a :: * -> * -- | Convert a number to a non-negative number. If a negative number is -- given, an error is raised. fromNumber :: (Ord a, C a) => a -> T a fromNumberMsg :: (Ord a, C a) => String -> a -> T a -- | Convert a number to a non-negative number. A negative number will be -- replaced by zero. Use this function with care since it may hide bugs. fromNumberClip :: (Ord a, C a) => a -> T a -- | Wrap a number into a non-negative number without doing checks. This -- routine exists entirely for efficiency reasons and must be used only -- in cases where you are absolutely sure, that the input number is -- non-negative. fromNumberUnsafe :: a -> T a toNumber :: T a -> a type Int = T Int type Integer = T Integer type Float = T Float type Double = T Double type Ratio a = T (T a) type Rational = T Rational instance (Ord a, C a) => C (T a) instance (Ord a, C a) => C (T a) instance (C a) => C (T a) instance (C a, Ord a, C a) => C (T a) instance (Ord a, C a) => C (T a) instance (Ord a, C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance (Ord a, C a) => C (T a) instance (Ord a, C a) => C (T a) instance (Ord a, C a) => C (T a) instance (Ord a, C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) -- | A lazy number type, which is a generalization of lazy Peano numbers. -- Comparisons can be made lazy and thus computations are possible which -- are impossible with strict number types, e.g. you can compute let -- y = min (1+y) 2 in y. You can even work with infinite values. -- However, depending on the granularity, the memory consumption is -- higher than that for strict number types. This number type is of -- interest for the merge operation of event lists, which allows for -- co-recursive merges. module Number.NonNegativeChunky -- | A chunky non-negative number is a list of non-negative numbers. It -- represents the sum of the list elements. It is possible to represent a -- finite number with infinitely many chunks by using an infinite number -- of zeros. -- -- Note the following problems: -- -- Addition is commutative only for finite representations. E.g. let -- y = min (1+y) 2 in y is defined, let y = min (y+1) 2 in -- y is not. -- -- The type is equivalent to Numeric.NonNegative.Chunky. data T a fromChunks :: (C a) => [a] -> T a toChunks :: (C a) => T a -> [a] fromNumber :: (C a) => a -> T a toNumber :: (C a) => T a -> a fromChunky98 :: (C a, C a) => T a -> T a toChunky98 :: (C a, C a) => T a -> T a minMaxDiff :: (C a) => T a -> T a -> (T a, (Bool, T a)) -- | Remove zero chunks. normalize :: (C a) => T a -> T a isNull :: (C a) => T a -> Bool isPositive :: (C a) => T a -> Bool -- | divModLazy accesses the divisor in a lazy way. However this is only -- relevant if the dividend is smaller than the divisor. For large -- dividends the divisor will be accessed multiple times but since it is -- already fully evaluated it could also be strict. divModLazy :: (C a, C a) => T a -> T a -> (T a, T a) -- | This function has a strict divisor and maintains the chunk structure -- of the dividend at a smaller scale. divModStrict :: (C a, C a) => T a -> a -> (T a, a) instance (C a) => C (T a) instance (C a) => Monoid (T a) instance (C a, Eq a, Show a, C a) => Fractional (T a) instance (C a, Eq a, Show a, C a) => Num (T a) instance (C a, Arbitrary a) => Arbitrary (T a) instance (Show a) => Show (T a) instance (Ord a, C a, C a) => C (T a) instance (C a, C a) => C (T a) instance (C a, C a) => C (T a) instance (C a, C a) => C (T a) instance (C a, C a, C a) => C (T a) instance (C a, C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance (C a) => Ord (T a) instance (C a) => Eq (T a) -- | Lazy Peano numbers represent natural numbers inclusive infinity. Since -- they are lazily evaluated, they are optimally for use as number type -- of Data.List.genericLength et.al. module Number.Peano data T Zero :: T Succ :: T -> T infinity :: T err :: String -> String -> a add :: T -> T -> T sub :: T -> T -> T subNeg :: T -> T -> (Bool, T) mul :: T -> T -> T fromPosEnum :: (C a, Enum a) => a -> T toPosEnum :: (C a, Enum a) => T -> a -- | If all values are completely defined, then it holds -- --
--   if b then x else y == ifLazy b x y
--   
-- -- However if b is undefined, then it is at least known that the -- result is larger than min x y. ifLazy :: Bool -> T -> T -> T -- | cf. To how to find the shortest list in a list of lists efficiently, -- this means, also in the presence of infinite lists. -- http://www.haskell.org/pipermail/haskell-cafe/2006-October/018753.html argMinFull :: (T, a) -> (T, a) -> (T, a) -- | On equality the first operand is returned. argMin :: (T, a) -> (T, a) -> a argMinimum :: [(T, a)] -> a argMaxFull :: (T, a) -> (T, a) -> (T, a) -- | On equality the first operand is returned. argMax :: (T, a) -> (T, a) -> a argMaximum :: [(T, a)] -> a -- | x0 <= x1 && x1 <= x2 ... for possibly infinite -- numbers in finite lists. isAscendingFiniteList :: [T] -> Bool isAscendingFiniteNumbers :: [T] -> Bool toListMaybe :: a -> T -> [Maybe a] -- | In glue x y == (z,(b,r)) z represents min x -- y, r represents max x y - min x y, and -- x<=y == b. -- -- Cf. Numeric.NonNegative.Chunky glue :: T -> T -> (T, (Bool, T)) isAscending :: [T] -> Bool data Valuable a Valuable :: T -> a -> Valuable a costs :: Valuable a -> T value :: Valuable a -> a increaseCosts :: T -> Valuable a -> Valuable a -- | Compute '(&&)' with minimal costs. (&&~) :: Valuable Bool -> Valuable Bool -> Valuable Bool andW :: [Valuable Bool] -> Valuable Bool leW :: T -> T -> Valuable Bool isAscendingW :: [T] -> Valuable Bool legacyInstance :: a instance (Show a) => Show (Valuable a) instance (Eq a) => Eq (Valuable a) instance (Ord a) => Ord (Valuable a) instance Show T instance Read T instance Eq T instance Integral T instance Real T instance Num T instance Bounded T instance C T instance C T instance C T instance Ix T instance C T instance C T instance C T instance C T instance C T instance C T instance C T instance Ord T instance C T instance C T instance Enum T instance C T instance C T instance C T -- | Interface to Number.Positional which dynamically checks for -- equal bases. module Number.Positional.Check -- | The value Cons b e m represents the number b^e * (m!!0 / -- 1 + m!!1 / b + m!!2 / b^2 + ...). The interpretation of exponent -- is chosen such that floor (logBase b (Cons b e m)) == e. That -- is, it is good for multiplication and logarithms. (Because of the -- necessity to normalize the multiplication result, the alternative -- interpretation wouldn't be more complicated.) However for base -- conversions, roots, conversion to fixed point and working with the -- fractional part the interpretation b^e * (m!!0 / b + m!!1 / b^2 + -- m!!2 / b^3 + ...) would fit better. The digits in the mantissa -- range from 1-base to base-1. The representation is -- not unique and cannot be made unique in finite time. This way we avoid -- infinite carry ripples. data T Cons :: Int -> Int -> Mantissa -> T base :: T -> Int exponent :: T -> Int mantissa :: T -> Mantissa -- | Shift digits towards zero by partial application of carries. E.g. 1.8 -- is converted to 2.(-2) If the digits are in the range (1-base, -- base-1) the resulting digits are in the range -- ((1-base)2-2, (base-1)2+2). The result is still not -- unique, but may be useful for further processing. compress :: T -> T -- | perfect carry resolution, works only on finite numbers carry :: T -> T prependDigit :: Int -> T -> T lift0 :: (Int -> T) -> T lift1 :: (Int -> T -> T) -> T -> T lift2 :: (Int -> T -> T -> T) -> T -> T -> T commonBasis :: Basis -> Basis -> Basis fromBaseInteger :: Int -> Integer -> T fromBaseRational :: Int -> Rational -> T defltBaseRoot :: Basis defltBaseExp :: Exponent defltBase :: Basis defltShow :: T -> String legacyInstance :: a instance Show T instance Fractional T instance Num T instance Power T instance C T instance C T instance C T instance C T instance Ord T instance Eq T instance C T instance C T instance C T instance C T instance C T instance C T instance C T instance C T -- | Physical expressions track the operations made on physical values so -- we are able to give detailed information on how to resolve unit -- violations. module Number.OccasionallyScalarExpression -- | A value of type T stores information on how to resolve unit -- violations. The main application of the module are certainly -- Number.Physical type instances but in principle it can also be applied -- to other occasionally scalar types. data T a v Cons :: (Term a v) -> v -> T a v data Term a v Const :: Term a v Add :: (T a v) -> (T a v) -> Term a v Mul :: (T a v) -> (T a v) -> Term a v Div :: (T a v) -> (T a v) -> Term a v fromValue :: v -> T a v makeLine :: Int -> String -> String showUnitError :: (Show v) => Bool -> Int -> v -> T a v -> String lift :: (v -> v) -> (T a v -> T a v) fromScalar :: (Show v, C a v) => a -> T a v scalarMap :: (Show v, C a v) => (a -> a) -> (T a v -> T a v) scalarMap2 :: (Show v, C a v) => (a -> a -> a) -> (T a v -> T a v -> T a v) instance (C a v, Show v) => C a (T a v) instance (C a, C v, Show v, C a v) => C (T a v) instance (C a, C v, Show v, C a v) => C (T a v) instance (C v) => C (T a v) instance (C v) => C (T a v) instance (C v) => C (T a v) instance (C v) => C (T a v) instance (C v) => C (T a v) instance (Ord v) => Ord (T a v) instance (Eq v) => Eq (T a v) instance (Show v) => Show (T a v) -- | Numeric values combined with abstract Physical Units module Number.Physical -- | A Physics.Quantity.Value.T combines a numeric value with a physical -- unit. data T i a Cons :: (T i) -> a -> T i a -- | Construct a physical value from a numeric value and the full vector -- representation of a unit. quantity :: (Ord i, Enum i, C a) => [Int] -> a -> T i a fromScalarSingle :: a -> T i a -- | Test for the neutral Unit.T. Also a zero has a unit! isScalar :: T i a -> Bool -- | apply a function to the numeric value while preserving the unit lift :: (a -> b) -> T i a -> T i b lift2 :: (Eq i) => String -> (a -> b -> c) -> T i a -> T i b -> T i c lift2Maybe :: (Eq i) => (a -> b -> c) -> T i a -> T i b -> Maybe (T i c) lift2Gen :: (Eq i) => String -> (a -> b -> c) -> T i a -> T i b -> c errorUnitMismatch :: String -> a -- | Add two values if the units match, otherwise return Nothing addMaybe :: (Eq i, C a) => T i a -> T i a -> Maybe (T i a) -- | Subtract two values if the units match, otherwise return Nothing subMaybe :: (Eq i, C a) => T i a -> T i a -> Maybe (T i a) scale :: (Ord i, C a) => a -> T i a -> T i a ratPow :: (C a) => T Int -> T i a -> T i a ratPowMaybe :: (C a) => T Int -> T i a -> Maybe (T i a) fromRatio :: (C b, C a) => T a -> b instance Monad (T i) instance Functor (T i) instance (C a v) => C a (T i v) instance (Ord i, C a v) => C a (T i v) instance (Ord i, C a v) => C a (T i v) instance (Ord i) => C (T i) instance (Ord i, C a) => C (T i a) instance (Ord i, C a) => C (T i a) instance (Ord i, C a) => C (T i a) instance (Ord i, C a) => C (T i a) instance (Ord i, Ord a) => Ord (T i a) instance (Ord i, C a) => C (T i a) instance (Ord i, C a) => C (T i a) instance (Ord i, Enum i, Show a) => Show (T i a) instance (Eq i, Eq a) => Eq (T i a) instance (C v) => C (T a v) -- | Convert a physical value to a human readable string. module Number.Physical.Show mulPrec :: Int -- | Show the physical quantity in a human readable form with respect to a -- given unit data base. showNat :: (Ord i, Show v, C a, Ord a, C a v) => T i a -> T i v -> String -- | Returns the rescaled value as number and the unit as string. The value -- can be used re-scale connected values and display them under the label -- of the unit showSplit :: (Ord i, Show v, C a, Ord a, C a v) => T i a -> T i v -> (v, String) showScaled :: (Ord i, Show v, Ord a, C a, C a v) => v -> [UnitSet i a] -> (v, String) -- | Choose a scale where the number becomes handy and return the scaled -- number and the corresponding scale. chooseScale :: (Ord i, Show v, Ord a, C a, C a v) => v -> UnitSet i a -> (v, Scale a) showUnitPart :: Bool -> Bool -> Scale a -> String defScale :: UnitSet i v -> Scale v findCloseScale :: (Ord a, C a) => a -> [Scale a] -> Scale a -- | unused totalDefScale :: (C a) => T i a -> a -- | unused getUnit :: (C a) => String -> T i a -> T i a -- | Convert a human readable string to a physical value. module Number.Physical.Read mulPrec :: Int readsNat :: (Enum i, Ord i, Read v, C a v) => T i a -> Int -> ReadS (T i v) readUnitPart :: (Ord i, C a) => Map String (T i a) -> String -> (T i a, String) -- | This function could also return the value, but a list of pairs -- (String, Integer) is easier for testing. parseProduct :: Parser [(String, Integer)] parseProductTail :: Parser [(String, Integer)] parsePower :: Parser (String, Integer) ignoreSpace :: Parser a -> Parser a createDict :: T i a -> Map String (T i a) -- | Numerical values equipped with SI units. This is considered as the -- user front-end. module Number.SI newtype T a v Cons :: (PValue v) -> T a v type PValue v = T Dimension v lift :: (PValue v0 -> PValue v1) -> (T a v0 -> T a v1) lift2 :: (PValue v0 -> PValue v1 -> PValue v2) -> (T a v0 -> T a v1 -> T a v2) liftGen :: (PValue v -> x) -> (T a v -> x) lift2Gen :: (PValue v0 -> PValue v1 -> x) -> (T a v0 -> T a v1 -> x) scale :: (C v) => v -> T a v -> T a v fromScalarSingle :: v -> T a v showNat :: (Show v, C a, Ord a, C a v) => T Dimension a -> T a v -> String readsNat :: (Read v, C a v) => T Dimension a -> Int -> ReadS (T a v) quantity :: (C a, C v) => T Dimension -> v -> T a v second :: (C a, C v) => T a v minute :: (C a, C v) => T a v hour :: (C a, C v) => T a v day :: (C a, C v) => T a v year :: (C a, C v) => T a v meter :: (C a, C v) => T a v liter :: (C a, C v) => T a v gramm :: (C a, C v) => T a v tonne :: (C a, C v) => T a v newton :: (C a, C v) => T a v pascal :: (C a, C v) => T a v bar :: (C a, C v) => T a v joule :: (C a, C v) => T a v watt :: (C a, C v) => T a v kelvin :: (C a, C v) => T a v coulomb :: (C a, C v) => T a v ampere :: (C a, C v) => T a v volt :: (C a, C v) => T a v ohm :: (C a, C v) => T a v farad :: (C a, C v) => T a v bit :: (C a, C v) => T a v byte :: (C a, C v) => T a v baud :: (C a, C v) => T a v inch :: (C a, C v) => T a v foot :: (C a, C v) => T a v yard :: (C a, C v) => T a v astronomicUnit :: (C a, C v) => T a v parsec :: (C a, C v) => T a v mach :: (C a, C v) => T a v speedOfLight :: (C a, C v) => T a v electronVolt :: (C a, C v) => T a v calorien :: (C a, C v) => T a v horsePower :: (C a, C v) => T a v accelerationOfEarthGravity :: (C a, C v) => T a v hertz :: (C a, C v) => T a v legacyInstance :: a instance (Ord a, C a, C a v, Num v, C v) => Fractional (T a v) instance (Ord a, C a, C a v, Num v, C v) => Num (T a v) instance (C a, Ord a, C a v, Show v, C a v) => C a (T a v) instance (C a v) => C a (T b v) instance (C a v) => C a (T b v) instance C (T a) instance (C v) => C (T a v) instance (C v) => C (T a v) instance (C v) => C (T a v) instance (C v) => C (T a v) instance (Ord v) => Ord (T a v) instance (C v) => C (T a v) instance (C v) => C (T a v) instance (Read v, Ord a, C a, C a v) => Read (T a v) instance (Show v, Ord a, C a, C a v) => Show (T a v) instance (Eq v) => Eq (T a v) instance (C v) => C (T a v)