{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE TypeFamilies #-} -- | -- Module : Numeric.Tools.Mesh -- Copyright : (c) 2011 Aleksey Khudyakov -- License : BSD3 -- -- Maintainer : Aleksey Khudyakov -- Stability : experimental -- Portability : portable -- -- 1-dimensional meshes. Used by 'Numeric.Tools.Interpolation'. -- module Numeric.Tools.Mesh ( -- * Meshes Mesh(..) -- ** Uniform mesh , UniformMesh , uniformMesh , uniformMeshStep ) where import Data.Data (Data,Typeable) import Numeric.Classes.Indexing ---------------------------------------------------------------- -- Type class ---------------------------------------------------------------- -- | Class for 1-dimensional meshes. Mesh is ordered set of -- points. Each instance must guarantee that every next point is -- greater that previous and there is at least 2 points in mesh. class Indexable a => Mesh a where -- | Low bound of mesh meshLowerBound :: a -> Double -- | Upper bound of mesh meshUpperBound :: a -> Double -- | Find such index for value that -- -- > mesh ! i <= x && mesh ! i+1 > x -- -- Will return invalid index if value is out of range. meshFindIndex :: a -> Double -> Int ---------------------------------------------------------------- -- Uniform mesh ---------------------------------------------------------------- -- | Uniform mesh data UniformMesh = UniformMesh { uniformMeshFrom :: Double , uniformMeshStep :: Double -- ^ Distance between points , uniformMeshSize :: Int } deriving (Eq,Show,Data,Typeable) -- | Create uniform mesh uniformMesh :: (Double,Double) -- ^ Lower and upper bound -> Int -- ^ Number of points -> UniformMesh uniformMesh (a,b) n | b <= a = error "Numeric.Tool.Interpolation.Mesh.uniformMesh: bad range" | n < 2 = error "Numeric.Tool.Interpolation.Mesh.uniformMesh: too few points" | otherwise = UniformMesh a ((b - a) / fromIntegral (n - 1)) n instance Indexable UniformMesh where type IndexVal UniformMesh = Double size = uniformMeshSize unsafeIndex (UniformMesh a da _) i = a + fromIntegral i * da instance Mesh UniformMesh where meshLowerBound = uniformMeshFrom meshUpperBound (UniformMesh a da n) = a + da * fromIntegral (n - 1) meshFindIndex (UniformMesh a da _) x = truncate $ (x - a) / da