packages feed

dimensional 0.7 → 0.7.1

raw patch · 6 files changed

+32/−330 lines, 6 filesdep ~base

Dependency ranges changed: base

Files

Numeric/NumType.lhs view
@@ -34,7 +34,13 @@ type classes, phantom types, functional dependencies and undecidable instances (and possibly additional unidentified GHC extensions). -> {-# LANGUAGE UndecidableInstances, EmptyDataDecls #-}+> {-# LANGUAGE UndecidableInstances+>            , ScopedTypeVariables+>            , EmptyDataDecls+>            , FunctionalDependencies+>            , MultiParamTypeClasses+>            , FlexibleInstances +> #-}  > module Numeric.NumType  >   -- Basic classes (exported versions).
Numeric/Units/Dimensional.lhs view
@@ -46,8 +46,15 @@ Clients of the module are generally not required to use these extensions. -> {-# LANGUAGE UndecidableInstances, ScopedTypeVariables #-}->   -- Does 'ScopedTypeVariables' imply 'EmptyDataDecls'?+> {-# LANGUAGE UndecidableInstances+>            , ScopedTypeVariables+>            , EmptyDataDecls+>            , MultiParamTypeClasses+>            , FunctionalDependencies+>            , FlexibleInstances+>            , TypeSynonymInstances+>            , FlexibleContexts+> #-}  > module Numeric.Units.Dimensional  >       -- TODO discriminate exports, in particular Variants and Dims.
− Numeric/Units/Dimensional/CGS.lhs
@@ -1,320 +0,0 @@-Numeric.Dimensional.CGS -- CGS system of units-Bjorn Buckwalter, bjorn.buckwalter@gmail.com-License: BSD3--*** EXPERIMENTAL ***---= Introduction =--This module was prompted by an email from Chuck Blake[1]. He asked if-the Dimensional library could support other systems of units than-SI, in particular systems such as the centimeter-gram-second (CGS)-system where fractional exponents of dimensions occur. He also-wondered whether it was possible to convert quantities between-different systems while statically ensuring that a given conversion-was valid.--In this module we show that we can in a straight forward manner-support systems with rational exponents, provided that the rationals-that may be encountered are known a priori. As an example we provide-a rudimentary implementation of the CGS system. --We also show that we can indeed statically prohibit invalid conversions-between different systems.---= Caveats =--I'm ignorantly assuming that when working with the CGS (or MKS)-system you will only (meaningfully?) encounter half-exponents and-only of the length and mass dimensions. Of course, in other systems-other rational exponents may be encountered.--I am also assuming that the CGS system would not be employed when-working with temperature, amount or luminosity. This is evident in-the below type signatures where I have assumed zero extent in the-temperature, amount and luminosity dimensions. If this is incorrect-I would appreciate pointers to the CGS representation of these-dimensions.--Please correct and inform me if my assumptions are wrong! ---= Preliminaries =--> {-# LANGUAGE UndecidableInstances, ScopedTypeVariables #-}--> module Numeric.Units.Dimensional.CGS where--> import Prelude ( undefined, Num, Fractional, Floating, Show, recip, Double )-> import qualified Prelude-> import Numeric.Units.Dimensional hiding ( DLength, DMass, DTime, DElectricCurrent )-> import Numeric.Units.Dimensional.Quantities as SIQ-> import qualified Numeric.Units.Dimensional.SIUnits as SI-> import qualified Numeric.NumType as N-> import Numeric.NumType ( Neg2, Neg1, Zero, Pos, Pos1, Pos2, Pos3, NumType )-> import Numeric.NumType ( neg2, neg1, zero, pos1, pos2, pos3 )-> import Data.Maybe (catMaybes)- --= Dimensions =--Analogously with the SI we collect the base dimensions of the CGS-system in the data type 'CGSDim'.--> data CGSDim lh mh t--In the above 'lh' and 'mh' represent the number of half-exponents-of length and mass respectively while 't' represents the number of-whole-exponents. The base dimensions illustrate this.--> type DLength = CGSDim Pos2 Zero Zero-> type DMass   = CGSDim Zero Pos2 Zero-> type DTime   = CGSDim Zero Zero Pos1--We add a few non-base dimensions for the sake of example. Charge-is particularly interesting as it illustrates the need for-half-exponents as described in [2].--> type DElectricCurrent = CGSDim Pos3 Pos1 Neg2-> type DCharge = CGSDim Pos3 Pos1 Neg1---= 'Mul', 'Div', 'Pow' and 'Root' instances =--The 'Mul', 'Div', 'Pow' and 'Root' instances are strictly analogous-with the SI.--> instance ( N.Sum lh lh' lh''->          , N.Sum mh mh' mh''->          , N.Sum t  t'  t'' ) => Mul (CGSDim lh   mh   t) ->                                      (CGSDim lh'  mh'  t') ->                                      (CGSDim lh'' mh'' t'')--> instance ( N.Sum lh lh' lh''->          , N.Sum mh mh' mh''->          , N.Sum t  t'  t'' ) => Div (CGSDim lh'' mh'' t'') ->                                      (CGSDim lh'  mh'  t') ->                                      (CGSDim lh   mh   t)--> instance ( N.Mul lh x lh'->          , N.Mul mh x mh'->          , N.Mul t  x t' ) => Pow (CGSDim lh  mh  t) x ->                                   (CGSDim lh' mh' t')--> instance ( N.Div lh x lh'->          , N.Div mh x mh'->          , N.Div t  x t' ) => Root (CGSDim lh  mh  t) x ->                                    (CGSDim lh' mh' t')---= Units =--We define the base units of the system. By defining 'meter' with a-"scale" of 100 we get a scale of one for 'centi meter'.--> meter  :: Num a => Unit DLength a-> meter  = Dimensional 100-> gram   :: Num a => Unit DMass a-> gram   = Dimensional 1-> second :: Num a => Unit DTime a-> second = Dimensional 1--We continue by defining the CGS equivalents of the other base SI-units. Actually we limit ourselves to 'ampere' since I am not sure-if or how the SI base dimensions other than current are expressed-in CGS.--> ampere :: Floating a => Unit DElectricCurrent a-> ampere = prefix (recip 3.33564e-10) ((SI.centi meter ^ pos3) ^/ pos2 * gram ^/ pos2 * second ^ neg2)--We also define the preferred CGS unit for charge.--> franklin :: Floating a => Unit DCharge a -- Also known as "esu".-> franklin = gram ^/ pos2 * (SI.centi meter ^ pos3) ^/ pos2 / second---= Conversion from SI =--At some point we may wish to convert an SI quantity to a CGS quantity-or vice versa.--In order to convert a 'Quantity' from the SI system to the CGS-system we use the strategy of dividing the quantity by the SI base-unit and multiplying the resulting number (sans dimension) by the-equivalent CGS unit. To realize this strategy we must be able to-obtain the SI base unit and the equivalent CGS unit for a given-quantity. We start with the SI unit since it is trivial.--> unit_SI :: Num a => Quantity (Dim l m t i th n j) a -> Unit (Dim l m t i th n j) a-> unit_SI _ = Dimensional 1--(Perhaps the above function would be better defined in another-module.)--Obtaining the CGS unit corresponding to the SI base unit of a-Quantity isn't quite as trivial. The function body itself is-straight-forward enough, the hairy part is the type signature.--> unit_CGS :: forall a l m t i l2 m2 il it l' m' t'.->          ( Floating a->          , N.Mul Zero l Zero, N.Mul Pos2 l l2->          , N.Mul Zero m Zero, N.Mul Pos2 m m2->          , N.Mul Zero t Zero, N.Mul Pos1 t t->          , N.Sum l2 Zero l2->          , N.Sum Zero m2 m2,  N.Sum m2 Zero m2->          , N.Sum Zero t  t->          , N.Mul Pos3 i  il->          , N.Mul Pos1 i  i->          , N.Mul Neg2 i  it->          , N.Sum l2 il l'->          , N.Sum m2 i  m'->          , N.Sum t  it t'->          ) => Quantity (Dim l m t i Zero Zero Zero) a -> Unit (CGSDim l' m' t') a-> unit_CGS _ = meter        ^ (undefined :: l)->            * SI.kilo gram ^ (undefined :: m)->            * second       ^ (undefined :: t)->            * ampere       ^ (undefined :: i)--Note that since the base dimensions of the CGS are a subset of those-of the SI the mapping of types from SI to CGS is unambiguous.--Also note that complex as the type signature may be producing it is a-mostly mechanical process.--With the above two functions we can define the function that converts-a unit from the SI. We omit the type signature since it is hairy-but can be readily inferred.--> fromSI x = x /~ unit_SI  x *~ unit_CGS x---= Conversion to SI =--We use the same strategy to convert from CGS to SI. However, when-converting from CGS to SI there may be several valid SI dimensionalities-for any given CGS dimensionality. We will handle this ambiguity by-requiring the user to specify the desired type (except when it is-inferable) of the resulting quantity.  For example:--] toSI (3.2 *~ centi meter) :: Length Double--In order to do this we must employ lexically scoped type variables-and provide the hairy type signature for the 'toSI' function.--> toSI :: forall a l m t i l2 m2 il it l' m' t'.->          ( Floating a->          , N.Mul Zero l Zero, N.Mul Pos2 l l2->          , N.Mul Zero m Zero, N.Mul Pos2 m m2->          , N.Mul Zero t Zero, N.Mul Pos1 t t->          , N.Sum l2 Zero l2->          , N.Sum Zero m2 m2,  N.Sum m2 Zero m2->          , N.Sum Zero t  t->          , N.Mul Pos3 i  il->          , N.Mul Pos1 i  i->          , N.Mul Neg2 i  it->          , N.Sum l2 il l'->          , N.Sum m2 i  m'->          , N.Sum t  it t'->          ) => Quantity (CGSDim l' m' t') a -> Quantity (Dim l m t i Zero Zero Zero) a-> toSI x = x /~ unit_CGS (undefined :: Quantity (Dim l m t i Zero Zero Zero) a)->            *~ unit_SI  (undefined :: Quantity (Dim l m t i Zero Zero Zero) a)--Again, the type signature is complex but deriving it is a mechanical-process.---= 'Show' instance =--We round off by writing 'Show' instance for 'CGSDim' analogous to-that of 'Dim'.--Out of laziness we use the notation "sqrt(cm)" to represent halves-of integral dimensions. Nothing is technically keeping us from doing-a better job here.--> instance forall lh mh t.->     ( NumType lh->     , NumType mh->     , NumType t->     ) => Show (CGSDim lh mh t) where->     show _ = (Prelude.unwords Prelude.. catMaybes)->              [ dimUnit "sqrt(cm)" (undefined :: lh)->              , dimUnit "sqrt(g)"  (undefined :: mh)->              , dimUnit "s"        (undefined :: t)->              ]---= Examples =--Let us try the Coulomb attraction example from [2]. We start by-performing the calculation in the SI.--> q_si  = 1.6021773e-19 *~ SI.coulomb -- Elementary charge in SI.-> r_si  = 0.1 *~ SI.nano SI.meter     -- Distance in SI-> f_si  = q_si ^ pos2 / (_4 * pi * e0 * r_si ^ pos2) ->   where ->       e0 = 8.8541878e-12 *~ (SI.ampere * SI.second / (SI.volt * SI.meter)) --The same calculation in the CGS system.--> q_cgs = fromSI q_si -- Elementary charge in CGS.-> r_cgs = fromSI r_si -- Distance in CGS-> f_cgs = q_cgs ^ pos2 / r_cgs ^ pos2--Inspecting the values in GHCi shows us that the results are consistent-(within reasonable accuracy) with [2].--  *Numeric.Dimensional.CGS> f_si-  2.3070794737101255e-8 m kg s^-2-  *Numeric.Dimensional.CGS> f_cgs -  2.30708078598602e-3 sqrt(cm)^2 sqrt(g)^2 s^-2--To convert from CGS to SI we must specify the type of the SI 'Quantity'.--> f_si' = toSI f_cgs :: SIQ.Force Double--  *Numeric.Dimensional.CGS> f_si'-  2.3070807859860202e-8 m kg s^-2--We follow up with another conversion example demonstrating the-ambiguity in the conversion from CGS to SI.--> c     = 1 *~ SI.farad -- A SI capacitance.-> c_cgs = fromSI c      -- Capacitance has dimensionality L in CGS.-> c'    = toSI c_cgs :: SIQ.Capacitance Double-> c''   = toSI c_cgs :: Length Double--  *Numeric.Dimensional.CGS> c-  1.0 m^-2 kg^-1 s^4 A^2-  *Numeric.Dimensional.CGS> c_cgs-  8.98755691740885e11 sqrt(cm)^2-  *Numeric.Dimensional.CGS> c'-  1.0 m^-2 kg^-1 s^4 A^2-  *Numeric.Dimensional.CGS> c''-  8.98755691740885e9 m---= Future work =--This is a very rudimentary implementation. To make it more practical-a significant number of quantities and units, in particularly those-commonly used with the CGS, would need to be added. In the mean-time all units defined for the SI can be used with the CGS by-applying 'fromSI' to quantities defined from the SI units.--If anyone is willing to add quantities/units (or other enhancements)-I will happily to accept patches. Personally I do not expect to use-this module and therefore do not intend to invest much more time-in it. If the module has other users I might reconsider.--And of course, another direction of future work is to define-additional systems (e.g. natural, relativistic) using this module-as a template. I imagine this should be fairly straight forward.---= References =--[1] http://code.google.com/p/dimensional/wiki/ChuckBlake20070611-[2] http://www.tf.uni-kiel.de/matwis/amat/mw1_ge/kap_2/basics/b2_1_14.html
Numeric/Units/Dimensional/Extensible.lhs view
@@ -26,7 +26,13 @@ Similarly with 'Numeric.Dimensional' this module requires GHC 6.6 or later. -> {-# LANGUAGE UndecidableInstances, ScopedTypeVariables #-}+> {-# LANGUAGE UndecidableInstances+>            , ScopedTypeVariables+>            , EmptyDataDecls+>            , MultiParamTypeClasses+>            , FunctionalDependencies+>            , FlexibleInstances+> #-}  > module Numeric.Units.Dimensional.Extensible ( DExt, showDExt ) where 
Numeric/Units/Dimensional/NonSI.lhs view
@@ -48,8 +48,9 @@ > inch, foot :: Fractional a => Unit DLength a > inch = prefix 2.54 (centi meter) > foot = prefix 12 inch     -- 0.3048 m-> poundMass :: Fractional a => Unit DMass a+> poundMass, ounce :: Fractional a => Unit DMass a > poundMass = prefix 0.45359237 (kilo gram)+> ounce     = prefix 28.349523 gram  In order to relate pounds mass to pounds force we define the questionable unit 'gee' (G) as the gravitational acceleration at@@ -63,10 +64,12 @@  Other (non inch-pound) units. -> bar :: (Fractional a) => Unit DPressure a-> bar = prefix 1.0e5 pascal > revolution :: (Floating a) => Unit DOne a > revolution = prefix 360 degree+> bar :: (Fractional a) => Unit DPressure a+> bar = prefix 1.0e5 pascal+> teaspoon :: (Fractional a) => Unit DVolume a+> teaspoon = prefix 5 (milli liter)   = References =
dimensional.cabal view
@@ -1,5 +1,5 @@ Name:                dimensional-Version:             0.7+Version:             0.7.1 License:             BSD3 License-File:        LICENSE Copyright:           Bjorn Buckwalter 2006-2007@@ -26,7 +26,7 @@                      Numeric.Units.Dimensional.Quantities,                      Numeric.Units.Dimensional.SIUnits,                      Numeric.Units.Dimensional.NonSI,-                     Numeric.Units.Dimensional.Extensible,-                     Numeric.Units.Dimensional.CGS+                     Numeric.Units.Dimensional.Extensible+                     --Numeric.Units.Dimensional.CGS ghc-options:         -O