{-# OPTIONS -fno-implicit-prelude #-} module Main where import Number.Complex((+:), (-:), ) import qualified Number.Complex as Complex import Number.Physical as Value import Number.SI as SIValue -- units import Number.SI.Unit as SIUnit -- unit prefixes (pico, nano, micro, milli, centi, deci, deca, hecto, kilo, mega, giga, tera, peta) import Number.OccasionallyScalarExpression as Expr import qualified Number.Positional.Check as Real import qualified Number.FixedPoint.Check as FixedPoint import qualified Number.ResidueClass.Func as ResidueClass import qualified Number.Peano as Peano import qualified MathObj.Polynomial as Polynomial import qualified MathObj.LaurentPolynomial as LaurentPolynomial import qualified MathObj.PowerSeries as PowerSeries import qualified MathObj.PowerSeries.Example as PowerSeriesExample import qualified MathObj.PartialFraction as PartialFraction import qualified Algebra.PrincipalIdealDomain as PID import qualified Algebra.Field as Field import qualified Algebra.ZeroTestable as ZeroTestable import qualified Algebra.Indexable as Indexable import Data.List (genericTake, genericLength) import PreludeBase import NumericPrelude {- * Physical units -} -- some shorthands for common usage type SIDouble = SIValue.T Double Double type SIComplex = SIValue.T Double (Complex.T Double) {- this advice seems not to be targeted to ghc's interactive mode default (SIDouble) -} test :: [SIDouble] test = let lengthScales = map (\n->10^-n*meter) [-10..6] areaScales = map (\n->10^-n*meter^2) [-10..6] in lengthScales ++ map recip lengthScales ++ areaScales ++ map recip areaScales ++ map ((meter*gramm/second)^-) [-5..5] ++ take 16 (iterate (10*) (10e-10*meter/gramm)) ++ [1/meter^2, 1/meter, meter, meter^2, second, hertz, meter*second, second/meter, meter/second, 1/meter/second, volt/meter,newton/meter, gramm] testComplex :: SIComplex testComplex = (2 :: Double) *> (SIValue.fromScalarSingle (3+:4)*milli*second) testMagnitude :: SIDouble testMagnitude = SIValue.lift (Value.lift Complex.magnitude) testComplex testExpr :: Expr.T Double SIDouble testExpr = sin (5 / (3+1) * fromValue meter) testPrefixes :: [SIDouble] testPrefixes = [pico, nano, micro, milli, centi, deci, deca, hecto, kilo, mega, giga, tera, peta] {- * Reals -} testReal :: String testReal = Real.defltShow (sqrt 2 + log 2 * pi) testComplexReal :: Complex.T Real.T testComplexReal = exp (0 +: pi) + exp (0 -: pi) showReal :: Real.T -> String showReal = Real.defltShow {- * Fixed point numbers -} testFixedPoint :: String testFixedPoint = FixedPoint.defltShow (sqrt 2 + log 2 * pi) showFixedPoint :: FixedPoint.T -> String showFixedPoint = FixedPoint.defltShow {- * Residue classes -} testResidueClass :: Integer testResidueClass = ResidueClass.concrete 7 (5*3/2) polyResidueClass :: (ZeroTestable.C a, Field.C a) => [a] -> ResidueClass.T (Polynomial.T a) polyResidueClass = ResidueClass.fromRepresentative . polynomial {- That's strange: The residue class implementation should constantly compute mod and thus should be much faster. I assume that this is an effect of missing sharing. The functions which represent a residue class are shared, but not their values. *Main> mod (3^3000000) 2 :: Integer 1 (2.47 secs, 24541080 bytes) *Main> ResidueClass.concrete 2 (3^3000000) :: Integer 1 (7.33 secs, 515047072 bytes) -} {- * Polynomials and power series -} polynomial :: [a] -> Polynomial.T a polynomial = Polynomial.fromCoeffs powerSeries :: [a] -> PowerSeries.T a powerSeries = PowerSeries.fromCoeffs laurentPolynomial :: Int -> [a] -> LaurentPolynomial.T a laurentPolynomial = LaurentPolynomial.fromShiftCoeffs tanSeries :: PowerSeries.T Rational tanSeries = powerSeries PowerSeriesExample.tan {- * Partial fractions -} partialFraction :: (PID.C a, Indexable.C a) => [a] -> a -> PartialFraction.T a partialFraction = PartialFraction.fromFactoredFraction {- | An example from wavelet theory: lifting coefficients of the CDF wavelet family. -} cdfFraction :: PartialFraction.T (Polynomial.T Rational) cdfFraction = partialFraction (map polynomial [[-4,1],[0,1],[4,1]]) (product (map polynomial [[-2,1],[2,1]])) {- | The same example with different notation, that relies on numerical literals being used for polynomials. -} cdfFractionNum :: PartialFraction.T (Polynomial.T Rational) cdfFractionNum = let x = polynomial [0,1] in partialFraction [x-4,x,x+4] ((x-2)*(x+2)) {- * Peano numbers -} testPeano :: Peano.T testPeano = minimum [Peano.infinity, 2, Peano.infinity, 4] testPeanoList :: [Char] testPeanoList = genericTake (genericLength (repeat 'a') :: Peano.T) ['a'..'z'] main :: IO () main = print test