simple-vec3 0.2 → 0.3
raw patch · 9 files changed
+311/−349 lines, 9 filesdep ~QuickCheckdep ~basedep ~criterion
Dependency ranges changed: QuickCheck, base, criterion, simple-vec3, tasty, tasty-quickcheck, tasty-th, vector, vector-th-unbox
Files
- CHANGELOG.md +50/−0
- LICENSE +1/−1
- benchmark/Benchmark.hs +26/−71
- simple-vec3.cabal +34/−28
- src/Data/Vec3.hs +122/−38
- src/Data/Vec3/Tupled.hs +64/−0
- src/Data/Vec3/Unboxed.hs +0/−64
- src/Data/Vec3/Unboxed/Contiguous.hs +0/−133
- tests/Tests.hs +14/−14
+ CHANGELOG.md view
@@ -0,0 +1,50 @@+# Changelog++## [0.3] - 2018-02-18++### Added++- GHC 8.2.x support++### Changed++- `Data.Vec3.Unboxed.Contiguous` is now again `Data.Vec3.Unboxed`.+ `UVec3` was merged with `SVec3` and renamed to `CVec3`.++- `Data.Vec3.Unboxed` is now `Data.Vec3.Tupled` and renamed to+ `TVec3`.++- Benchmarks were reorganized to work well with Criterion group+ coloring++### Removed++- `SVec3` (merged into `CVec3`)++## [0.2] - 2016-10-14++### Added++- Tests++### Changed++- `Data.Vec3.Unboxed` is now `Data.Vec3.Unboxed.Contiguous`++- `Data.Vec3.TUnboxed` is now `Data.Vec3.Unboxed` and uses+ [vector-th-unbox][] to generate Unbox instance++## [0.1.0.1] - 2012-12-13++### Changed++- Benchmark is now an actual Cabal-friendly benchmark++## [0.1.0.0] - 2012-12-05++[0.3]: https://github.com/dzhus/simple-vec3/compare/0.2...0.3+[0.2]: https://github.com/dzhus/simple-vec3/compare/0.1.0.1...0.2+[0.1.0.1]: https://github.com/dzhus/simple-vec3/compare/0.1.0.0...0.1.0.1+[0.1.0.0]: https://github.com/dzhus/simple-vec3/tree/0.1.0.0++[vector-th-unbox]: https://hackage.haskell.org/package/vector-th-unbox
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2012, Dmitry Dzhus+Copyright (c) 2012-2018, Dmitry Dzhus All rights reserved.
benchmark/Benchmark.hs view
@@ -7,7 +7,6 @@ import Data.Vector.Unboxed as VU import Data.Vec3-import qualified Data.Vec3.Unboxed.Contiguous as C oXYZ :: (Double, Double, Double)@@ -19,11 +18,7 @@ n :: Int-n = 1000000---bigN :: Int-bigN = n * 10+n = 10000000 -- Access to whole elements@@ -50,86 +45,46 @@ dotM' e1 e2 = dotM e1 e2 m --- Note that source arrays are not forced in test functions.--tv :: VU.Vector UVec3-tv = VG.replicate n $ fromXYZ oXYZ---cv :: VU.Vector C.UVec3-cv = VG.replicate n $ fromXYZ oXYZ---sv :: VS.Vector SVec3-sv = VG.replicate n $ fromXYZ oXYZ---tv' :: VU.Vector UVec3-tv' = VG.replicate n $ fromXYZ oXYZ'---cv' :: VU.Vector C.UVec3-cv' = VG.replicate n $ fromXYZ oXYZ'+testNormalize :: (Vec3 a, VG.Vector v a) => v a -> Benchmarkable+testNormalize = whnf (VG.map normalize) -sv' :: VS.Vector SVec3-sv' = VG.replicate n $ fromXYZ oXYZ'-+-- Note that source arrays are not forced in test functions. -bsv :: VS.Vector SVec3-bsv = VG.replicate bigN $ fromXYZ oXYZ+csv :: VS.Vector CVec3+csv = VG.replicate n $ fromXYZ oXYZ -bcv :: VU.Vector C.UVec3-bcv = VG.replicate bigN $ fromXYZ oXYZ+cuv :: VU.Vector CVec3+cuv = VG.replicate n $ fromXYZ oXYZ -btv :: VU.Vector UVec3-btv = VG.replicate bigN $ fromXYZ oXYZ+tv :: VU.Vector TVec3+tv = VG.replicate n $ fromXYZ oXYZ -bsv' :: VS.Vector SVec3-bsv' = VG.replicate bigN $ fromXYZ oXYZ'+csv' :: VS.Vector CVec3+csv' = VG.replicate n $ fromXYZ oXYZ' -bcv' :: VU.Vector C.UVec3-bcv' = VG.replicate bigN $ fromXYZ oXYZ'+cuv' :: VU.Vector CVec3+cuv' = VG.replicate n $ fromXYZ oXYZ' -btv' :: VU.Vector UVec3-btv' = VG.replicate bigN $ fromXYZ oXYZ'+tv' :: VU.Vector TVec3+tv' = VG.replicate n $ fromXYZ oXYZ' main :: IO () main = defaultMain- [ bgroup "zipWith"- [ bench "SVec/Storable" $ testWhole sv sv'- , bench "UVec/Unboxed" $ testWhole tv tv'- , bench "UVec/Unboxed/Contiguous" $ testWhole cv cv'- ]- , bgroup "zipWith-by-x"- [ bench "SVec/Storable" $ testComp sv sv'- , bench "UVec/Unboxed" $ testComp tv tv'- , bench "UVec/Unboxed/Contiguous" $ testComp cv cv'- ]- , bgroup "zipWith-dotM"- [ bench "SVec/Storable" $ testDotM sv sv'- , bench "UVec/Unboxed" $ testDotM tv tv'- , bench "UVec/Unboxed/Contiguous" $ testDotM cv cv'- ]- , bgroup "zipWith 10M"- [ bench "SVec/Storable" $ testWhole bsv bsv'- , bench "UVec/Unboxed" $ testWhole btv btv'- , bench "UVec/Unboxed/Contiguous" $ testWhole bcv bcv'- ]- , bgroup "zipWith-by-x 10M"- [ bench "SVec/Storable" $ testComp bsv bsv'- , bench "UVec/Unboxed" $ testComp btv btv'- , bench "UVec/Unboxed/Contiguous" $ testComp bcv bcv'- ]- , bgroup "zipWith-dotM 10M"- [ bench "SVec/Storable" $ testDotM bsv bsv'- , bench "UVec/Unboxed" $ testDotM btv btv'- , bench "UVec/Unboxed/Contiguous" $ testDotM bcv bcv'- ]+ [ bgroup "CVec3/Storable" $ mkGroup csv csv'+ , bgroup "CVec3/Unboxed" $ mkGroup cuv cuv'+ , bgroup "TVec3/Unboxed" $ mkGroup tv tv' ]+ where+ mkGroup v1 v2 =+ [ bench "zipWith-add" $ testWhole v1 v2+ , bench "zipWith-by-x-add" $ testComp v1 v2+ , bench "zipWith-dotM" $ testDotM v1 v2+ , bench "normalize" $ testNormalize v1+ ]
simple-vec3.cabal view
@@ -1,17 +1,19 @@ name: simple-vec3-version: 0.2+version: 0.3 cabal-version: >=1.10 build-type: Simple license: BSD3 license-file: LICENSE-maintainer: <dima@dzhus.org>+maintainer: dima@dzhus.org homepage: https://github.com/dzhus/simple-vec3#readme bug-reports: https://github.com/dzhus/simple-vec3/issues synopsis: Three-dimensional vectors of doubles with basic operations description:- A class of 3-vectors with a set of basic methods for geometry operations on vectors and an associated matrix type. Instances are provided for use with "Data.Vector.Unboxed" and "Data.Vector.Storable" as container types.+ Simple three-dimensional vectors of doubles with basic vector and matrix operations, supporting "Data.Vector.Unboxed" and "Data.Vector.Storable". category: Math, Numerical author: Dmitry Dzhus+extra-source-files:+ CHANGELOG.md source-repository head type: git@@ -21,43 +23,47 @@ exposed-modules: Data.Vec3 Data.Vec3.Class- Data.Vec3.Unboxed- Data.Vec3.Unboxed.Contiguous build-depends:- base >=4.9.0.0 && <5,- QuickCheck >=2.8.2,- vector >=0.11.0.0,- vector-th-unbox >=0.2.1.6+ QuickCheck <2.11,+ base <5,+ vector <0.13,+ vector-th-unbox <0.3 default-language: Haskell2010 hs-source-dirs: src- ghc-options: -Wall+ other-modules:+ Data.Vec3.Tupled+ ghc-options: -Wall -Wcompat -O2 -test-suite pythia-recommender-test+test-suite simple-vec3-test type: exitcode-stdio-1.0 main-is: Tests.hs build-depends:- base >=4.9.0.0 && <5,- QuickCheck >=2.8.2,- vector >=0.11.0.0,- vector-th-unbox >=0.2.1.6,- simple-vec3 >=0.2,- tasty >=0.11.0.4,- tasty-quickcheck >=0.8.4,- tasty-th >=0.1.4+ QuickCheck <2.11,+ base <5,+ simple-vec3 -any,+ tasty <0.13,+ tasty-quickcheck <0.10,+ tasty-th <0.2,+ vector <0.13,+ vector-th-unbox <0.3 default-language: Haskell2010 hs-source-dirs: tests- ghc-options: -Wall+ other-modules:+ Paths_simple_vec3+ ghc-options: -Wall -Wcompat -O2 -benchmark simple-vec3-benchmark+benchmark simple-vec3-benchmark type: exitcode-stdio-1.0 main-is: Benchmark.hs build-depends:- base >=4.9.0.0 && <5,- QuickCheck >=2.8.2,- vector >=0.11.0.0,- vector-th-unbox >=0.2.1.6,- criterion >=1.1.1.0,- simple-vec3 >=0.2+ QuickCheck <2.11,+ base <5,+ criterion <1.3,+ simple-vec3 -any,+ vector <0.13,+ vector-th-unbox <0.3 default-language: Haskell2010 hs-source-dirs: benchmark- ghc-options: -Wall+ other-modules:+ Paths_simple_vec3+ ghc-options: -Wall -Wcompat -O2
src/Data/Vec3.hs view
@@ -5,43 +5,145 @@ 'Vec3' class and implementations. +The package provides two different implementations for 'Vec3' type+class, which differ in storage scheme. Benchmarks are included for+both. You most likely want to use 'CVec3' which is based on contiguous+storage scheme and offers the best performance.+ -} module Data.Vec3 ( Vec3(..)- , SVec3(..)- , UVec3(..)+ , CVec3(..)+ , TVec3(..) ) where -import Prelude hiding (reverse)+import Control.Monad import Foreign import Foreign.C.Types +import Data.Vector.Unboxed as VU+import Data.Vector.Generic as VG+import Data.Vector.Generic.Mutable as VGM+import Test.QuickCheck+ import Data.Vec3.Class-import Data.Vec3.Unboxed -import Test.QuickCheck+import Data.Vec3.Tupled --- | 'Vec3' implementation with 'Foreign.Storable.Storable' instance--- based on a single contiguous array storage scheme, suitable for use--- with "Data.Vector.Storable".------ 'Unbox' instance provides the required index transformations.+-- | 'Vec3' implementation with 'Data.Vector.Unboxed.Unbox' and+-- 'Data.Vector.Unboxed.Storable' instances based on a single+-- contiguous array storage scheme, suitable for use with+-- "Data.Vector.Unboxed" and "Data.Vector.Storable". -- -- @--- interface: [d1 x y z ; d2 x y z ...], length = N = M / 3+-- interface: [v1 x y z ; v2 x y z ...], length = N = M / 3 -- | | | | | |--- storage: [ d1x d2y d2z ; d2x d2y d2z ...], length = M+-- storage: [ v1x v2y v2z ; v2x v2y v2z ...], length = M -- @-data SVec3 = SVec3 !CDouble !CDouble !CDouble- deriving (Eq, Show)+--+-- This implementation has the best performance.+data CVec3 = CVec3 !Double !Double !Double+ deriving (Eq, Show) -instance Storable SVec3 where+instance Vec3 CVec3 where+ newtype Matrix CVec3 = UMatrix (CVec3, CVec3, CVec3)++ fromXYZ (x, y, z) = CVec3 x y z+ {-# INLINE fromXYZ #-}++ toXYZ (CVec3 x y z) = (x, y, z)+ {-# INLINE toXYZ #-}++ fromRows (r1, r2, r3) = UMatrix (r1, r2, r3)+ {-# INLINE fromRows #-}++ toRows (UMatrix (r1, r2, r3)) = (r1, r2, r3)+ {-# INLINE toRows #-}+++newtype instance VU.MVector s CVec3 = MV_CVec3 (VU.MVector s Double)+newtype instance VU.Vector CVec3 = V_CVec3 (VU.Vector Double)+++instance VGM.MVector VU.MVector CVec3 where+ basicInitialize (MV_CVec3 v) =+ VGM.basicInitialize v+ {-# INLINE basicInitialize #-}++ basicLength (MV_CVec3 v) =+ VGM.basicLength v `quot` 3+ {-# INLINE basicLength #-}++ basicUnsafeSlice s l (MV_CVec3 v) =+ MV_CVec3 $ VGM.basicUnsafeSlice (s * 3) (l * 3) v+ {-# INLINE basicUnsafeSlice #-}++ basicOverlaps (MV_CVec3 v1) (MV_CVec3 v2) =+ VGM.basicOverlaps v1 v2+ {-# INLINE basicOverlaps #-}++ basicUnsafeNew n =+ MV_CVec3 `liftM` VGM.basicUnsafeNew (n * 3)+ {-# INLINE basicUnsafeNew #-}++ basicUnsafeRead (MV_CVec3 v) i = do+ x <- VGM.basicUnsafeRead v j+ y <- VGM.basicUnsafeRead v (j + 1)+ z <- VGM.basicUnsafeRead v (j + 2)+ return $ CVec3 x y z+ where+ j = i * 3+ {-# INLINE basicUnsafeRead #-}++ basicUnsafeWrite (MV_CVec3 v) i (CVec3 x y z) =+ VGM.basicUnsafeWrite v j x >>+ VGM.basicUnsafeWrite v (j + 1) y >>+ VGM.basicUnsafeWrite v (j + 2) z+ where+ j = i * 3+ {-# INLINE basicUnsafeWrite #-}+++instance VG.Vector VU.Vector CVec3 where+ basicUnsafeFreeze (MV_CVec3 v) =+ V_CVec3 `liftM` VG.basicUnsafeFreeze v+ {-# INLINE basicUnsafeFreeze #-}++ basicUnsafeThaw (V_CVec3 v) =+ MV_CVec3 `liftM` VG.basicUnsafeThaw v+ {-# INLINE basicUnsafeThaw #-}++ basicLength (V_CVec3 v) = VG.basicLength v `quot` 3+ {-# INLINE basicLength #-}++ basicUnsafeSlice s l (V_CVec3 v) =+ V_CVec3 $ VG.basicUnsafeSlice (s * 3) (l * 3) v+ {-# INLINE basicUnsafeSlice #-}++ basicUnsafeIndexM (V_CVec3 v) i = do+ x <- VG.basicUnsafeIndexM v j+ y <- VG.basicUnsafeIndexM v (j + 1)+ z <- VG.basicUnsafeIndexM v (j + 2)+ return $ CVec3 x y z+ where+ j = i * 3+ {-# INLINE basicUnsafeIndexM #-}++ basicUnsafeCopy (MV_CVec3 mv) (V_CVec3 v)+ = VG.basicUnsafeCopy mv v+ {-# INLINE basicUnsafeCopy #-}+++instance Unbox CVec3+++instance Storable CVec3 where sizeOf _ = sizeOf (undefined :: CDouble) * 3 alignment _ = alignment (undefined :: CDouble) @@ -49,12 +151,12 @@ x <- peekElemOff q 0 y <- peekElemOff q 1 z <- peekElemOff q 2- return $ SVec3 x y z+ return $ CVec3 x y z where q = castPtr p {-# INLINE peek #-} - poke p (SVec3 x y z) = do+ poke p (CVec3 x y z) = do pokeElemOff q 0 x pokeElemOff q 1 y pokeElemOff q 2 z@@ -62,30 +164,12 @@ q = castPtr p {-# INLINE poke #-} --instance Vec3 SVec3 where- newtype Matrix SVec3 = SMatrix (SVec3, SVec3, SVec3)- deriving (Eq, Show)-- fromXYZ (x, y, z) = SVec3 (CDouble x) (CDouble y) (CDouble z)- {-# INLINE fromXYZ #-}-- toXYZ (SVec3 (CDouble x) (CDouble y) (CDouble z)) = (x, y, z)- {-# INLINE toXYZ #-}-- fromRows (r1, r2, r3) = SMatrix (r1, r2, r3)- {-# INLINE fromRows #-}-- toRows (SMatrix (r1, r2, r3)) = (r1, r2, r3)- {-# INLINE toRows #-}---instance Arbitrary SVec3 where+instance Arbitrary CVec3 where arbitrary = do x <- arbitrary y <- arbitrary z <- arbitrary return $ fromXYZ (x, y, z) - shrink (SVec3 (CDouble x) (CDouble y) (CDouble z)) =- map fromXYZ $ shrink (x, y, z)+ shrink (CVec3 x y z) =+ Prelude.map fromXYZ $ shrink (x, y, z)
+ src/Data/Vec3/Tupled.hs view
@@ -0,0 +1,64 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}++module Data.Vec3.Tupled+ ( TVec3(..)+ )++where++import Prelude++import Data.Vector.Unboxed.Deriving++import Data.Vec3.Class+++-- | 'Vec3' implementation with 'Data.Vector.Unboxed.Unbox' instance+-- based on default Unbox instance for tuples of arrays, which wraps a+-- vector of tuples as a tuple of vectors.+--+-- @+-- interface: [v1 (x, y, z); v2 (x, y, z) ...], length = N+-- | | | | | |+-- storage(x): [v1x-+ | | ; v2x-+ | | ...], length = N+-- storage(y): [v1y----+ | ; v2y----+ | ...], length = N+-- storage(z): [v1z-------+ ; v2z-------+ ...], length = N+-- @+--+-- You almost definitely want to use 'CVec3' instead as it has better+-- performance.+newtype TVec3 = TVec3 (Double, Double, Double)+ deriving (Eq, Show)+++derivingUnbox "TVec3"+ [t|TVec3 -> (Double, Double, Double)|]+ [|\(TVec3 v) -> v|]+ [|TVec3|]+++instance Vec3 TVec3 where+ newtype Matrix TVec3 = TMatrix (TVec3, TVec3, TVec3)+ deriving (Eq, Show)+++ fromXYZ = TVec3+ {-# INLINE fromXYZ #-}++ toXYZ (TVec3 v) = v+ {-# INLINE toXYZ #-}++ fromRows (r1, r2, r3) = TMatrix (r1, r2, r3)+ {-# INLINE fromRows #-}++ toRows (TMatrix (r1, r2, r3)) = (r1, r2, r3)+ {-# INLINE toRows #-}+++derivingUnbox "TMatrix"+ [t|Matrix TVec3 -> (TVec3, TVec3, TVec3)|]+ [|\(TMatrix v) -> v|]+ [|TMatrix|]
− src/Data/Vec3/Unboxed.hs
@@ -1,64 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeFamilies #-}--module Data.Vec3.Unboxed- ( UVec3(..)- )--where--import Prelude hiding (reverse)--import Data.Vector.Unboxed.Deriving--import Data.Vec3.Class----- | 'Vec3' implementation with 'Data.Vector.Unboxed.Unbox' instance--- based on tuples, suitable for use with "Data.Vector.Unboxed".------ This represents 3-vector as a triple of doubles, using the default--- Unbox instance for tuples as provided by "Data.Vector.Unboxed",--- which wraps a vector of tuples as a tuple of vectors.------ @--- interface: [d1 (x, y, z); d2 (x, y, z) ...], length = N--- | | | | | |--- storage(x): [d1x-+ | | ; d2x-+ | | ...], length = N--- storage(y): [d1y----+ | ; d2y----+ | ...], length = N--- storage(z): [d1z-------+ ; d2z-------+ ...], length = N--- @-newtype UVec3 = UVec3 (Double, Double, Double)- deriving (Eq, Show)---derivingUnbox "UVec3"- [t|UVec3 -> (Double, Double, Double)|]- [|\(UVec3 v) -> v|]- [|UVec3|]---instance Vec3 UVec3 where- newtype Matrix UVec3 = UMatrix (UVec3, UVec3, UVec3)- deriving (Eq, Show)--- fromXYZ = UVec3- {-# INLINE fromXYZ #-}-- toXYZ (UVec3 v) = v- {-# INLINE toXYZ #-}-- fromRows (r1, r2, r3) = UMatrix (r1, r2, r3)- {-# INLINE fromRows #-}-- toRows (UMatrix (r1, r2, r3)) = (r1, r2, r3)- {-# INLINE toRows #-}---derivingUnbox "UMatrix"- [t|Matrix UVec3 -> (UVec3, UVec3, UVec3)|]- [|\(UMatrix v) -> v|]- [|UMatrix|]
− src/Data/Vec3/Unboxed/Contiguous.hs
@@ -1,133 +0,0 @@-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeFamilies #-}--{-|--'Vec3' implementation with 'Data.Vector.Unboxed.Unbox' instance based-on single array storage scheme, suitable for use with-"Data.Vector.Unboxed".---}--module Data.Vec3.Unboxed.Contiguous- ( UVec3(..)- )---where--import Prelude hiding (reverse)--import Control.Monad--import Data.Vector.Unboxed as VU-import Data.Vector.Generic as VG-import Data.Vector.Generic.Mutable as VGM--import Data.Vec3.Class----- | 'Vec3' implementation with 'Data.Vector.Unboxed.Unbox' instance--- based on a single contiguous array storage scheme, suitable for use--- with "Data.Vector.Unboxed".------ 'Unbox' instance provides the required index transformations.------ @--- interface: [d1 x y z ; d2 x y z ...], length = N = M / 3--- | | | | | |--- storage: [ d1x d2y d2z ; d2x d2y d2z ...], length = M--- @-data UVec3 = UVec3 !Double !Double !Double- deriving (Eq, Show)---instance Vec3 UVec3 where- newtype Matrix UVec3 = UMatrix (UVec3, UVec3, UVec3)-- fromXYZ (x, y, z) = UVec3 x y z- {-# INLINE fromXYZ #-}-- toXYZ (UVec3 x y z) = (x, y, z)- {-# INLINE toXYZ #-}-- fromRows (r1, r2, r3) = UMatrix (r1, r2, r3)- {-# INLINE fromRows #-}-- toRows (UMatrix (r1, r2, r3)) = (r1, r2, r3)- {-# INLINE toRows #-}---newtype instance VU.MVector s UVec3 = MV_UVec3 (VU.MVector s Double)-newtype instance VU.Vector UVec3 = V_UVec3 (VU.Vector Double)---instance VGM.MVector VU.MVector UVec3 where- basicInitialize (MV_UVec3 v) =- VGM.basicInitialize v- {-# INLINE basicInitialize #-}-- basicLength (MV_UVec3 v) =- VGM.basicLength v `quot` 3- {-# INLINE basicLength #-}-- basicUnsafeSlice s l (MV_UVec3 v) =- MV_UVec3 $ VGM.basicUnsafeSlice (s * 3) (l * 3) v- {-# INLINE basicUnsafeSlice #-}-- basicOverlaps (MV_UVec3 v1) (MV_UVec3 v2) =- VGM.basicOverlaps v1 v2- {-# INLINE basicOverlaps #-}-- basicUnsafeNew n =- MV_UVec3 `liftM` VGM.basicUnsafeNew (n * 3)- {-# INLINE basicUnsafeNew #-}-- basicUnsafeRead (MV_UVec3 v) i = do- x <- VGM.basicUnsafeRead v j- y <- VGM.basicUnsafeRead v (j + 1)- z <- VGM.basicUnsafeRead v (j + 2)- return $ UVec3 x y z- where- j = i * 3- {-# INLINE basicUnsafeRead #-}-- basicUnsafeWrite (MV_UVec3 v) i (UVec3 x y z) =- VGM.basicUnsafeWrite v j x >>- VGM.basicUnsafeWrite v (j + 1) y >>- VGM.basicUnsafeWrite v (j + 2) z- where- j = i * 3- {-# INLINE basicUnsafeWrite #-}---instance VG.Vector VU.Vector UVec3 where- basicUnsafeFreeze (MV_UVec3 v) =- V_UVec3 `liftM` VG.basicUnsafeFreeze v- {-# INLINE basicUnsafeFreeze #-}-- basicUnsafeThaw (V_UVec3 v) =- MV_UVec3 `liftM` VG.basicUnsafeThaw v- {-# INLINE basicUnsafeThaw #-}-- basicLength (V_UVec3 v) = VG.basicLength v `quot` 3- {-# INLINE basicLength #-}-- basicUnsafeSlice s l (V_UVec3 v) =- V_UVec3 $ VG.basicUnsafeSlice (s * 3) (l * 3) v- {-# INLINE basicUnsafeSlice #-}-- basicUnsafeIndexM (V_UVec3 v) i = do- x <- VG.basicUnsafeIndexM v j- y <- VG.basicUnsafeIndexM v (j + 1)- z <- VG.basicUnsafeIndexM v (j + 2)- return $ UVec3 x y z- where- j = i * 3- {-# INLINE basicUnsafeIndexM #-}-- basicUnsafeCopy (MV_UVec3 mv) (V_UVec3 v)- = VG.basicUnsafeCopy mv v- {-# INLINE basicUnsafeCopy #-}--instance Unbox UVec3
tests/Tests.hs view
@@ -7,13 +7,13 @@ infix 4 <~=>-(<~=>) :: SVec3 -> SVec3 -> Bool+(<~=>) :: CVec3 -> CVec3 -> Bool (<~=>) a b = ax ~= bx && ay ~= by && az ~= bz where- (ax, ay, az) = toXYZ (a :: SVec3)- (bx, by, bz) = toXYZ (b :: SVec3)+ (ax, ay, az) = toXYZ (a :: CVec3)+ (bx, by, bz) = toXYZ (b :: CVec3) infix 4 ~=@@ -30,37 +30,37 @@ tests = [ testProperty "Commutativity of addition: a + b = b + a"- (\(a :: SVec3) b -> a <+> b <~=> b <+> a)+ (\(a :: CVec3) b -> a <+> b <~=> b <+> a) , testProperty "Associativity of addition: (a + b) + c = a + (b + c)"- (\(a :: SVec3) b c -> (a <+> b) <+> c <~=> a <+> (b <+> c))+ (\(a :: CVec3) b c -> (a <+> b) <+> c <~=> a <+> (b <+> c)) , testProperty "Identity element of addition (zero): v + 0 = v"- (\(v :: SVec3) -> (v <+> origin <~=> v))+ (\(v :: CVec3) -> (v <+> origin <~=> v)) , testProperty "Inverse elements of addition: v + (-v) = 0"- (\(v :: SVec3) -> (v <+> invert v <~=> origin))+ (\(v :: CVec3) -> (v <+> invert v <~=> origin)) , testProperty "Compatibility of scalar and field multiplication"- (\(v :: SVec3) p q -> (v .^ p .^ q <~=> v .^ (p * q)))+ (\(v :: CVec3) p q -> (v .^ p .^ q <~=> v .^ (p * q))) , testProperty "Identity of scalar multiplication"- (\(v :: SVec3) -> (v .^ 1 <~=> v))+ (\(v :: CVec3) -> (v .^ 1 <~=> v)) , testProperty "Distributivity wrt vector addition"- (\(a :: SVec3) b p -> ((a <+> b) .^ p) <~=> (a .^ p) <+> (b .^ p))+ (\(a :: CVec3) b p -> ((a <+> b) .^ p) <~=> (a .^ p) <+> (b .^ p)) , testProperty "Distributivity wrt scalar addition"- (\(a :: SVec3) p q -> (a .^ (p + q) <~=> (a .^ p) <+> (a .^ q)))+ (\(a :: CVec3) p q -> (a .^ (p + q) <~=> (a .^ p) <+> (a .^ q))) , testProperty "Subtraction definition"- (\(a :: SVec3) b -> (a <+> invert b <~=> a <-> b))+ (\(a :: CVec3) b -> (a <+> invert b <~=> a <-> b)) , testProperty "Normalization"- (\(v :: SVec3) -> (v <~=> origin || norm (normalize v) ~= 1))+ (\(v :: CVec3) -> (v <~=> origin || norm (normalize v) ~= 1)) , testProperty "Triangle inequality"- (\(a :: SVec3) b c -> (distance a b + distance b c >= distance a c))+ (\(a :: CVec3) b c -> (distance a b + distance b c >= distance a c)) ]