-- 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: -- --
-- (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. -- -- Scope & Limitations/TODO: * It might be desireable to split Ord up -- into Poset and Ord (a total ordering). This is not addressed here. -- --
-- 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. 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 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.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.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 [] 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.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 module Algebra.Real -- | This is the type class of an ordered ring, satisfying the laws -- --
-- a * b === b * a -- 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 ---- -- Note that abs is in a rather different place than it is in the Haskell -- 98 Prelude. In particular, -- --
-- abs :: Complex -> Complex ---- -- is not defined. To me, this seems to have the wrong type anyway; -- Complex.magnitude has the correct type. class (C a, C a, Ord a) => C a abs :: (C a) => a -> a signum :: (C 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 -- | A type class for non-negative numbers. Prominent instances are -- Numeric.NonNegative.Wrapper.T and peano numbers. This class cannot do -- any checks, but it let you show to the user what arguments your -- function expects. In fact many standard functions (take, -- '(!!)', ...) should have this type class constraint. Thus you must -- define class instances with care. 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. class (Ord a, C a) => C a (-|) :: (C a) => a -> a -> a -- | 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, 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.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 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 Int instance C Integer -- | 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) -- | 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.RealField.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 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 (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.RealField. 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 -- -- Laws that must be satisfied by instances: -- --
-- fromRational' . toRational === id --class (C a) => C a toRational :: (C a) => a -> Rational 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.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.RealField. 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 b, C a) => C a b (*>) :: (C a b) => a -> b -> b -- | Compute the linear combination of a list of vectors. -- -- ToDo: Should it use NumericPrelude.List.zipWithMatch ? linearComb :: (C a b) => [a] -> [b] -> b -- | This function can be used to define any C as a module over -- Integer. -- -- Better move to Algebra.Additive? integerMultiply :: (C a, C b) => a -> b -> b propCascade :: (Eq b, C a b) => b -> a -> a -> Bool propRightDistributive :: (Eq b, C a b) => a -> b -> b -> Bool propLeftDistributive :: (Eq b, C a b) => b -> a -> a -> Bool 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 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 -- | 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 module Algebra.RealField -- | Minimal complete definition: splitFraction or floor -- -- There are probably more laws, but some laws are -- --
-- (fromInteger.fst.splitFraction) a + (snd.splitFraction) a === a -- ceiling (toRational x) === ceiling x :: Integer -- truncate (toRational x) === truncate x :: Integer -- floor (toRational x) === floor x :: Integer ---- -- If there wouldn't be Real.C a and ToInteger.C b -- constraints, we could also use this class for splitting ratios of -- polynomials. -- -- As an aside, let me note the similarities between splitFraction -- x and x divMod 1 (if that were defined). In particular, -- it might make sense to unify the rounding modes somehow. -- -- IEEEFloat-specific calls are removed here (cf. Prelude.RealFloat) so -- probably nobody will actually use this default definition. -- -- Henning: 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. -- -- 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 -- ''integral'' part would not be of type class C. -- -- Can there be a separate class for fraction, -- splitFraction, floor and ceiling since they do -- not need reals and their ordering? class (C a, C 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 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 -- | TODO: Should be moved to a continued fraction module. approxRational :: (C a, C a) => a -> a -> Rational instance C Double instance C Float instance (C a, C a) => C (T a) 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 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 module NumericPrelude -- | 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. 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 -- | scale a vector by a scalar (*>) :: (C a b) => a -> b -> b 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 -- | Abstraction of normed vector spaces module Algebra.NormedSpace.Euclidean -- | A vector space equipped with an Euclidean or a Hilbert norm. -- -- Minimal definition: normSqr class (C a, C a v) => Sqr a v normSqr :: (Sqr a v) => v -> a 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 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 (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 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. module MathObj.Matrix -- | A matrix is a twodimensional array of ring elements, indexed by -- integers. data T a Cons :: (Array (Integer, Integer) a) -> T a -- | 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]] fromList :: Integer -> Integer -> [a] -> T a dimension :: T a -> (Integer, Integer) numRows :: T a -> Integer numColumns :: T a -> Integer zipWith :: (a -> b -> c) -> T a -> T b -> T c zeroMatrix :: (C a) => Integer -> Integer -> T a -- | What more do we need from our matrix class? We have addition, -- subtraction and multiplication, and thus composition of generic -- free-module-maps. We're going to want to solve linear equations with -- or without fields underneath, so we're going to want an implementation -- of the Gaussian algorithm as well as most probably Smith normal form. -- Determinants are cool, and these are to be calculated either with the -- Gaussian algorithm or some other goodish method. -- -- We'll want generic linear equation solving, returning one solution, -- any solution really, or nothing. Basically, this is asking for the -- preimage of a given vector over the given map, so -- -- a_11 x_1 + .. + a_1n x_n = y_1 ... a_m1 x_1 + .. + a_mn a_n = y_m -- -- has really x_1,...,x_n as a preimage of the vector y_1,..,y_m under -- the map (a_ij), since obviously y_1,..,y_m = (a_ij) x_1,..,x_n -- -- So, generic linear equation solving boils down to the function preimage :: (C a) => T a -> T a -> Maybe (T a) 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 (C a, 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 -- | 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] 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 -- | 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 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] -- | 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 -- | Multiply by the variable, used internally. shift :: (C a) => [a] -> [a] unShift :: [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] scale :: (C a) => a -> [a] -> [a] divMod :: (C a, C a) => [a] -> [a] -> ([a], [a]) tensorProduct :: (C a) => [a] -> [a] -> [[a]] tensorProductAlt :: (C a) => [a] -> [a] -> [[a]] mulShear :: (C a) => [a] -> [a] -> [a] mulShearTranspose :: (C a) => [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] fromRoots :: (C a) => [a] -> T a alternate :: (C a) => [a] -> [a] reverse :: (C 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 -- | 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. eval :: (C a) => [a] -> a -> a evaluate :: (C a) => T a -> a -> a -- | Evaluate (truncated) power series. evalCoeffVector :: (C a v) => [v] -> a -> v evaluateCoeffVector :: (C a v) => T v -> a -> v evalArgVector :: (C a v, C v) => [a] -> v -> v evaluateArgVector :: (C a v, C v) => T a -> v -> v -- | Evaluate approximations that is evaluate all truncations of the -- series. approx :: (C a) => [a] -> a -> [a] approximate :: (C a) => T a -> a -> [a] -- | Evaluate approximations that is evaluate all truncations of the -- series. approxCoeffVector :: (C a v) => [v] -> a -> [v] approximateCoeffVector :: (C a v) => T v -> a -> [v] -- | Evaluate approximations that is evaluate all truncations of the -- series. approxArgVector :: (C a v, C v) => [a] -> v -> [v] approximateArgVector :: (C a v, C v) => T 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]) -- | 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] divMod :: (C a, C a) => [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] -- | It fulfills evaluate x . evaluate y == evaluate (compose x y) -- compose :: (C a, C a) => T a -> T a -> T a -- | Since the inner series must start with a zero, the first term is -- omitted in y. comp :: (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]) 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.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 :: Core a -> T a coeffs :: T a -> Core a type Core a = [[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 :: Core a -> T a lift1 :: (Core a -> Core a) -> (T a -> T a) lift2 :: (Core a -> Core a -> Core a) -> (T a -> T a -> T a) lift0fromPowerSeries :: [T a] -> Core a lift1fromPowerSeries :: ([T a] -> [T a]) -> (Core a -> Core a) lift2fromPowerSeries :: ([T a] -> [T a] -> [T a]) -> (Core a -> Core a -> Core a) const :: a -> T a appPrec :: Int sub :: (C a) => Core a -> Core a -> Core a add :: (C a) => Core a -> Core a -> Core a negate :: (C a) => Core a -> Core a scale :: (C a) => a -> Core a -> Core a mul :: (C a) => Core a -> Core a -> Core a divide :: (C a) => Core a -> Core a -> Core a sqrt :: (C a) => (a -> a) -> Core a -> Core a swapVariables :: Core a -> Core a differentiate0 :: (C a) => Core a -> Core a differentiate1 :: (C a) => Core a -> Core a integrate0 :: (C a) => [a] -> Core a -> Core a integrate1 :: (C a) => [a] -> Core a -> Core a -- | Since the inner series must start with a zero, the first term is -- omitted in y. comp :: (C a) => [a] -> Core a -> Core a 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) => Core a quadraticDiff2 :: (C a, Eq a) => Core a harmonicMVF :: (C a) => [a] harmonic2 :: (C a, Eq a) => Core a harmonicDiff2 :: (C a, Eq a) => Core a arithmeticMVF :: (C a) => [a] arithmetic2 :: (C a, Eq a) => Core a arithmeticDiff2 :: (C a, Eq a) => Core a geometricMVF :: (C a) => [a] geometric2 :: (C a, Eq a) => Core a geometricDiff2 :: (C a, Eq a) => Core a meanValueDiff2 :: (C a, Eq a) => Core a -> [a] -> Core 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 MyPrelude max :: (C a) => a -> a -> a min :: (C a) => a -> a -> a abs :: (C a, C a) => a -> a -- | 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 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 -- | 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 (T a) instance (C a) => C (T a) instance (C a) => C (T a) instance (C a) => C (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. -- --
-- | | | ******************************* -- | | +-------------------------------- -- | | ************************ -- | +---------------------------------- -- | ************ -- +------------------------------------ ---- -- 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 scale :: (C a) => a -> [a] -> [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(i x)) -> conjugate(p(exp(i x))) -- -- 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 -- | 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 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 -- | 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 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, 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 (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) -- | 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 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 -- | Remove zero chunks. normalize :: (C a) => T a -> T a isNull :: (C a) => T a -> Bool isPositive :: (C a) => T a -> Bool 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) -- | 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) -- | 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 -- | 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,r,b) 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, T, Bool) 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 Ord T instance Enum T instance C T instance C T instance C 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 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)] -- | 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 Ord T instance Eq T instance C T instance C T instance C T instance C T instance C T instance C T -- | 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 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 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) module Number.ResidueClass.Reader -- | T is a Reader monad but does not need functional dependencies like -- that from the Monad Template 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) -- | 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) -- | 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) -- | 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) -- | 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 -- | 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 -- | 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) -- | 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 -- | 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)