learn-physics 0.4.3 → 0.5
raw patch · 6 files changed
+130/−71 lines, 6 filesdep ~not-glossdep ~spatial-mathPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: not-gloss, spatial-math
API changes (from Hackage documentation)
- Physics.Learn: compositeSimpsonCrossedLineIntegral :: Int -> VectorField -> Curve -> Vec
- Physics.Learn: compositeSimpsonDottedLineIntegral :: Int -> VectorField -> Curve -> Double
- Physics.Learn: xyzFromPos :: Position -> Xyz Double
- Physics.Learn: xyzFromVec :: Vec -> Xyz Double
- Physics.Learn.Visual.VisTools: xyzFromPos :: Position -> Xyz Double
- Physics.Learn.Visual.VisTools: xyzFromVec :: Vec -> Xyz Double
+ Physics.Learn: arrow :: Point -> Point -> Picture
+ Physics.Learn: cartToPolar :: (Float, Float) -> (Float, Float)
+ Physics.Learn: polarToCart :: (Float, Float) -> (Float, Float)
+ Physics.Learn: thickArrow :: Float -> Point -> Point -> Picture
+ Physics.Learn: v3FromPos :: Position -> V3 Double
+ Physics.Learn: v3FromVec :: Vec -> V3 Double
+ Physics.Learn.Curve: compositeTrapezoidCrossedLineIntegral :: Int -> VectorField -> Curve -> Vec
+ Physics.Learn.Curve: compositeTrapezoidDottedLineIntegral :: Int -> VectorField -> Curve -> Double
+ Physics.Learn.Visual.VisTools: v3FromPos :: Position -> V3 Double
+ Physics.Learn.Visual.VisTools: v3FromVec :: Vec -> V3 Double
- Physics.Learn: (^*) :: (VectorSpace v, ~ * s (Scalar v)) => v -> s -> v
+ Physics.Learn: (^*) :: (VectorSpace v, (~) * s (Scalar v)) => v -> s -> v
- Physics.Learn: (^/) :: (VectorSpace v, ~ * s (Scalar v), Fractional s) => v -> s -> v
+ Physics.Learn: (^/) :: (VectorSpace v, (~) * s (Scalar v), Fractional s) => v -> s -> v
- Physics.Learn: magnitude :: (InnerSpace v, ~ * s (Scalar v), Floating s) => v -> s
+ Physics.Learn: magnitude :: (InnerSpace v, (~) * s (Scalar v), Floating s) => v -> s
- Physics.Learn.CarrotVec: (^*) :: (VectorSpace v, ~ * s (Scalar v)) => v -> s -> v
+ Physics.Learn.CarrotVec: (^*) :: (VectorSpace v, (~) * s (Scalar v)) => v -> s -> v
- Physics.Learn.CarrotVec: (^/) :: (VectorSpace v, ~ * s (Scalar v), Fractional s) => v -> s -> v
+ Physics.Learn.CarrotVec: (^/) :: (VectorSpace v, (~) * s (Scalar v), Fractional s) => v -> s -> v
- Physics.Learn.CarrotVec: magnitude :: (InnerSpace v, ~ * s (Scalar v), Floating s) => v -> s
+ Physics.Learn.CarrotVec: magnitude :: (InnerSpace v, (~) * s (Scalar v), Floating s) => v -> s
Files
- learn-physics.cabal +5/−5
- src/Physics/Learn.hs +15/−8
- src/Physics/Learn/Charge.hs +4/−4
- src/Physics/Learn/Curve.hs +38/−41
- src/Physics/Learn/Visual/VisTools.hs +13/−13
- src/Tests.hs +55/−0
learn-physics.cabal view
@@ -1,5 +1,5 @@ Name: learn-physics-Version: 0.4.3+Version: 0.5 Synopsis: Haskell code for learning physics Description: A library of functions for vector calculus, calculation of electric field, electric flux,@@ -11,8 +11,8 @@ Maintainer: Scott N. Walck <walck@lvc.edu> Category: Physics Build-type: Simple-Cabal-version: >=1.6-Tested-with: GHC == 7.6.3+Cabal-version: >=1.8+Tested-with: GHC == 7.8.2 Library Exposed-modules: Physics.Learn.Charge Physics.Learn.Current@@ -36,8 +36,8 @@ Physics.Learn.Visual.GlossTools Build-depends: base >= 4.2 && < 4.8, vector-space >= 0.8.4 && < 0.9,- not-gloss >= 0.5.0.4 && < 0.6,- spatial-math >= 0.1.7 && < 0.2,+ not-gloss >= 0.6 && < 0.7,+ spatial-math >= 0.2 && < 0.3, gloss >= 1.8 && < 1.9, gnuplot >= 0.5 && < 0.6 Hs-source-dirs: src
src/Physics/Learn.hs view
@@ -121,8 +121,6 @@ , simpleLineIntegral , dottedLineIntegral , crossedLineIntegral- , compositeSimpsonDottedLineIntegral- , compositeSimpsonCrossedLineIntegral -- ** Surfaces , Surface(..) , unitSphere@@ -162,9 +160,14 @@ , label , postscript , psFile+ -- ** Gloss library+ , polarToCart+ , cartToPolar+ , arrow+ , thickArrow -- ** Vis library- , xyzFromVec- , xyzFromPos+ , v3FromVec+ , v3FromPos , visVec , oneVector , displayVectorField@@ -249,8 +252,6 @@ , simpleLineIntegral , dottedLineIntegral , crossedLineIntegral- , compositeSimpsonDottedLineIntegral- , compositeSimpsonCrossedLineIntegral ) import Physics.Learn.Surface ( Surface(..)@@ -275,8 +276,8 @@ , volumeIntegral ) import Physics.Learn.Visual.VisTools- ( xyzFromVec- , xyzFromPos+ ( v3FromVec+ , v3FromPos , visVec , oneVector , displayVectorField@@ -325,4 +326,10 @@ ( label , postscript , psFile+ )+import Physics.Learn.Visual.GlossTools+ ( polarToCart+ , cartToPolar+ , arrow+ , thickArrow )
src/Physics/Learn/Charge.hs view
@@ -77,7 +77,7 @@ totalCharge :: ChargeDistribution -> Charge totalCharge (PointCharge q _) = q totalCharge (LineCharge lambda c) = simpleLineIntegral 1000 lambda c-totalCharge (SurfaceCharge sigma s) = surfaceIntegral 100 100 sigma s+totalCharge (SurfaceCharge sigma s) = surfaceIntegral 200 200 sigma s totalCharge (VolumeCharge rho v) = volumeIntegral 50 50 50 rho v totalCharge (MultipleCharges ds) = sum [totalCharge d | d <- ds] @@ -122,7 +122,7 @@ -> Surface -- ^ geometry of the surface charge -> VectorField -- ^ electric field (in V/m) eFieldFromSurfaceCharge sigma s r- = k *^ surfaceIntegral 100 100 integrand s+ = k *^ surfaceIntegral 200 200 integrand s where k = 9e9 -- 1 / (4 * pi * epsilon0) integrand r' = sigma r' *^ d ^/ magnitude d ** 3@@ -160,7 +160,7 @@ -- | The electric flux through a surface produced by a charge distribution. electricFlux :: Surface -> ChargeDistribution -> Double-electricFlux surf dist = dottedSurfaceIntegral 100 100 (eField dist) surf+electricFlux surf dist = dottedSurfaceIntegral 200 200 (eField dist) surf ------------------------ -- Electric Potential --@@ -209,7 +209,7 @@ -> Surface -- ^ geometry of the surface charge -> ScalarField -- ^ electric potential ePotFromSurfaceCharge sigma s r- = k *^ surfaceIntegral 100 100 integrand s+ = k *^ surfaceIntegral 200 200 integrand s where k = 9e9 -- 1 / (4 * pi * epsilon0) integrand r' = sigma r' / magnitude d
src/Physics/Learn/Curve.hs view
@@ -28,6 +28,8 @@ , simpleLineIntegral , dottedLineIntegral , crossedLineIntegral+ , compositeTrapezoidDottedLineIntegral+ , compositeTrapezoidCrossedLineIntegral , compositeSimpsonDottedLineIntegral , compositeSimpsonCrossedLineIntegral )@@ -68,12 +70,32 @@ } -- | A dotted line integral.+-- Convenience function for 'compositeSimpsonDottedLineIntegral'. dottedLineIntegral+ :: Int -- ^ number of half-intervals+ -- (one less than the number of function evaluations)+ -> VectorField -- ^ vector field+ -> Curve -- ^ curve to integrate over+ -> Double -- ^ scalar result+dottedLineIntegral = compositeSimpsonDottedLineIntegral++-- | Calculates integral vf x dl over curve.+-- Convenience function for 'compositeSimpsonCrossedLineIntegral'.+crossedLineIntegral+ :: Int -- ^ number of half-intervals+ -- (one less than the number of function evaluations)+ -> VectorField -- ^ vector field+ -> Curve -- ^ curve to integrate over+ -> Vec -- ^ vector result+crossedLineIntegral = compositeSimpsonCrossedLineIntegral++-- | A dotted line integral, performed in an unsophisticated way.+compositeTrapezoidDottedLineIntegral :: Int -- ^ number of intervals -> VectorField -- ^ vector field -> Curve -- ^ curve to integrate over -> Double -- ^ scalar result-dottedLineIntegral n vf (Curve f a b)+compositeTrapezoidDottedLineIntegral n vf (Curve f a b) = sum $ zipWith (<.>) aveVecs dls where dt = (b - a) / fromIntegral n@@ -82,13 +104,13 @@ aveVecs = zipWith average vecs (tail vecs) dls = zipWith displacement pts (tail pts) --- | Calculates integral vf x dl over curve.-crossedLineIntegral+-- | Calculates integral vf x dl over curve in an unsophisticated way.+compositeTrapezoidCrossedLineIntegral :: Int -- ^ number of intervals -> VectorField -- ^ vector field -> Curve -- ^ curve to integrate over -> Vec -- ^ vector result-crossedLineIntegral n vf (Curve f a b)+compositeTrapezoidCrossedLineIntegral n vf (Curve f a b) = sumV $ zipWith (><) aveVecs dls where dt = (b - a) / fromIntegral n@@ -113,35 +135,6 @@ aveVecs = zipWith average vecs (tail vecs) dls = zipWith displacement pts (tail pts) -{--lineIntegral :: (InnerSpace v, Scalar v ~ Double) => Double- -> (Vec -> v)- -> Curve- -> v-lineIntegral tol field (Curve f a b)- = let ca = f a- cb = f b- fielda = field ca- fieldb = field cb- val = average fielda fieldb ^* magnitude (cb ^-^ ca)- in evalInterval tol 1 20 field (Curve f a b) ca cb fielda fieldb val--evalInterval :: (InnerSpace v, Scalar v ~ Double) => Double -> Int -> Int- -> (Vec -> v) -> Curve -> Vec -> Vec -> v -> v -> v -> v-evalInterval tol level maxlevel field (Curve f a b) ca cb fielda fieldb val- = let t = (a + b) / 2- ct = f t- fieldt = field ct- vall = average fielda fieldt ^* magnitude (ct ^-^ ca)- valr = average fieldt fieldb ^* magnitude (cb ^-^ ct)- newval = vall ^+^ valr- in if magnitude (newval ^-^ val) < tol then- newval- else- evalInterval (tol/2) (level+1) maxlevel field (Curve f a t) ca ct fielda fieldt vall ^+^- evalInterval (tol/2) (level+1) maxlevel field (Curve f t b) ct cb fieldt fieldb valr--}- -- | Reparametrize a curve from 0 to 1. normalizeCurve :: Curve -> Curve normalizeCurve (Curve f a b)@@ -227,10 +220,12 @@ -- Quadratic approximation to curve. -- Composite strategy. -- Dotted line integral.-compositeSimpsonDottedLineIntegral :: Int -- ^ number of half-intervals (one less than the number of function evaluations- -> VectorField -- ^ vector field- -> Curve -- ^ curve to integrate over- -> Double -- ^ scalar result+compositeSimpsonDottedLineIntegral+ :: Int -- ^ number of half-intervals+ -- (one less than the number of function evaluations)+ -> VectorField -- ^ vector field+ -> Curve -- ^ curve to integrate over+ -> Double -- ^ scalar result compositeSimpsonDottedLineIntegral n vf (Curve c a b) = let nEven = 2 * div n 2 dt = (b - a) / fromIntegral nEven@@ -259,10 +254,12 @@ -- Quadratic approximation to curve. -- Composite strategy. -- Crossed line integral.-compositeSimpsonCrossedLineIntegral :: Int -- ^ number of half-intervals (one less than the number of function evaluations- -> VectorField -- ^ vector field- -> Curve -- ^ curve to integrate over- -> Vec -- ^ vector result+compositeSimpsonCrossedLineIntegral+ :: Int -- ^ number of half-intervals+ -- (one less than the number of function evaluations)+ -> VectorField -- ^ vector field+ -> Curve -- ^ curve to integrate over+ -> Vec -- ^ vector result compositeSimpsonCrossedLineIntegral n vf (Curve c a b) = let nEven = 2 * div n 2 dt = (b - a) / fromIntegral nEven
src/Physics/Learn/Visual/VisTools.hs view
@@ -3,8 +3,8 @@ -- | Some tools related to the not-gloss 3D graphics and animation library. module Physics.Learn.Visual.VisTools- ( xyzFromVec- , xyzFromPos+ ( v3FromVec+ , v3FromPos , visVec , oneVector , displayVectorField@@ -13,7 +13,7 @@ where import SpatialMath- ( Xyz(..)+ ( V3(..) , Euler(..) ) import Vis@@ -37,17 +37,17 @@ ( Curve(..) ) --- | Make an 'Xyz' object from a 'Vec'.-xyzFromVec :: Vec -> Xyz Double-xyzFromVec v = Xyz x y z+-- | Make a 'V3' object from a 'Vec'.+v3FromVec :: Vec -> V3 Double+v3FromVec v = V3 x y z where x = xComp v y = yComp v z = zComp v --- | Make an 'Xyz' object from a 'Position'.-xyzFromPos :: Position -> Xyz Double-xyzFromPos r = Xyz x y z+-- | Make a 'V3' object from a 'Position'.+v3FromPos :: Position -> V3 Double+v3FromPos r = V3 x y z where (x,y,z) = cartesianCoordinates r @@ -58,16 +58,16 @@ -> VectorField -- ^ vector field to display -> VisObject Double -- ^ the displayable object displayVectorField col unitsPerMeter samplePts field- = VisObjects [Trans (xyzFromPos r) $ visVec col (e ^/ unitsPerMeter) | r <- samplePts, let e = field r]+ = VisObjects [Trans (v3FromPos r) $ visVec col (e ^/ unitsPerMeter) | r <- samplePts, let e = field r] -- | A displayable VisObject for a curve. curveObject :: Color -> Curve -> VisObject Double curveObject color (Curve f a b)- = Line' [(xyzFromPos (f t), color) | t <- [a,a+(b-a)/1000..b]]+ = Line' [(v3FromPos (f t), color) | t <- [a,a+(b-a)/1000..b]] -- | Place a vector at a particular position. oneVector :: Color -> Position -> Vec -> VisObject Double-oneVector c r v = Trans (xyzFromPos r) $ visVec c v+oneVector c r v = Trans (v3FromPos r) $ visVec c v data Cart = Cart Double Double Double deriving (Show)@@ -85,7 +85,7 @@ -- | A VisObject arrow from a vector visVec :: Color -> Vec -> VisObject Double-visVec c v = rotZ phi $ rotY theta $ Arrow (r,20*r) (Xyz 0 0 1) c+visVec c v = rotZ phi $ rotY theta $ Arrow (r,20*r) (V3 0 0 1) c where x = xComp v y = yComp v
+ src/Tests.hs view
@@ -0,0 +1,55 @@+{-# OPTIONS_GHC -Wall #-}++module Main where++import Physics.Learn+import Test.QuickCheck++propGaussLaw1 :: (Double,Double,Double) -> Bool+propGaussLaw1 (x,y,z) = abs (eFlux - q/epsilon0) < 0.01+ where+ eFlux = fluxThroughLargeCenteredSphere (x,y,z) q+ epsilon0 = 1 / (4 * pi * 9e9)+ q = epsilon0++fluxThroughLargeCenteredSphere :: (Double,Double,Double) -> Double -> Double+fluxThroughLargeCenteredSphere (x,y,z) q+ = electricFlux (centeredSphere radius) (PointCharge q (cart x y z))+ where+ radius = 2 * sqrt(x*x + y*y + z*z) + 1++currentLoop :: Double -> Current -> CurrentDistribution+currentLoop radius i+ = LineCurrent i (Curve (\phi -> cyl radius phi 0) 0 (2*pi))++amperianLoop :: Double -> Curve+amperianLoop radius+ = Curve (\t -> cart (radius + radius * sin t) 0 (radius * cos t)) 0 (2*pi)++magCirculation :: Double -> Current -> Double+magCirculation radius i+ = dottedLineIntegral 20+ (bFieldFromCurrentLoop i (Curve (\phi -> cyl radius phi 0) 0 (2*pi)))+ (amperianLoop radius)++bFieldFromCurrentLoop :: Current -> Curve -> VectorField+bFieldFromCurrentLoop i c r+ = k *^ crossedLineIntegral 20 integrand c+ where+ k = 1e-7 -- mu0 / (4 * pi)+ integrand r' = (-i) *^ d ^/ magnitude d ** 3+ where+ d = displacement r' r++propAmpere1 :: Double -> Property+propAmpere1 radius+ = radius > 0 ==> abs (magCirculation radius i - 4*pi*1e-7 * i) < 0.01+ where+ i = 1 / (4*pi*1e-7)++main :: IO ()+main = putStrLn "Gauss's law test:" >>+ quickCheck propGaussLaw1 >>+ putStrLn "Ampere's law test:" >>+ quickCheck propAmpere1+