-- | -- Module : Simulation.Aivika.Table -- Copyright : Copyright (c) 2009-2017, David Sorokin -- License : BSD3 -- Maintainer : David Sorokin -- Stability : experimental -- Tested with: GHC 8.0.1 -- -- It defines the table functions. -- module Simulation.Aivika.Table (tableLookup, tableLookupStepwise) where import Data.Array -- | Lookup @x@ in a table of pairs @(x, y)@ using linear interpolation. tableLookup :: Double -> Array Int (Double, Double) -> Double tableLookup x tbl = find first last x where (first, last) = bounds tbl find left right x = if left > right then error "Incorrect index: tableLookup" else let index = (left + 1 + right) `div` 2 x1 = fst \$ tbl ! index in if x1 <= x then let y | index < right = find index right x | right == last = snd \$ tbl ! right | otherwise = let x2 = fst \$ tbl ! (index + 1) y1 = snd \$ tbl ! index y2 = snd \$ tbl ! (index + 1) in y1 + (y2 - y1) * (x - x1) / (x2 - x1) in y else let y | left < index = find left (index - 1) x | left == first = snd \$ tbl ! left | otherwise = error "Incorrect index: tableLookup" in y -- | Lookup @x@ in a table of pairs @(x, y)@ using stepwise function. tableLookupStepwise :: Double -> Array Int (Double, Double) -> Double tableLookupStepwise x tbl = find first last x where (first, last) = bounds tbl find left right x = if left > right then error "Incorrect index: tableLookupStepwise" else let index = (left + 1 + right) `div` 2 x1 = fst \$ tbl ! index in if x1 <= x then let y | index < right = find index right x | right == last = snd \$ tbl ! right | otherwise = snd \$ tbl ! right in y else let y | left < index = find left (index - 1) x | left == first = snd \$ tbl ! left | otherwise = error "Incorrect index: tableLookupStepwise" in y