module Simulation.Aivika.Table
(tableLookup,
tableLookupStepwise) where
import Data.Array
tableLookup :: Double -> Array Int (Double, Double) -> Double
tableLookup :: Double -> Array Int (Double, Double) -> Double
tableLookup Double
x Array Int (Double, Double)
tbl = Int -> Int -> Double -> Double
find Int
first Int
last Double
x
where
(Int
first, Int
last) = forall i e. Array i e -> (i, i)
bounds Array Int (Double, Double)
tbl
find :: Int -> Int -> Double -> Double
find Int
left Int
right Double
x =
if Int
left forall a. Ord a => a -> a -> Bool
> Int
right then
forall a. HasCallStack => [Char] -> a
error [Char]
"Incorrect index: tableLookup"
else
let index :: Int
index = (Int
left forall a. Num a => a -> a -> a
+ Int
1 forall a. Num a => a -> a -> a
+ Int
right) forall a. Integral a => a -> a -> a
`div` Int
2
x1 :: Double
x1 = forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ Array Int (Double, Double)
tbl forall i e. Ix i => Array i e -> i -> e
! Int
index
in if Double
x1 forall a. Ord a => a -> a -> Bool
<= Double
x then
let y :: Double
y | Int
index forall a. Ord a => a -> a -> Bool
< Int
right = Int -> Int -> Double -> Double
find Int
index Int
right Double
x
| Int
right forall a. Eq a => a -> a -> Bool
== Int
last = forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ Array Int (Double, Double)
tbl forall i e. Ix i => Array i e -> i -> e
! Int
right
| Bool
otherwise =
let x2 :: Double
x2 = forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ Array Int (Double, Double)
tbl forall i e. Ix i => Array i e -> i -> e
! (Int
index forall a. Num a => a -> a -> a
+ Int
1)
y1 :: Double
y1 = forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ Array Int (Double, Double)
tbl forall i e. Ix i => Array i e -> i -> e
! Int
index
y2 :: Double
y2 = forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ Array Int (Double, Double)
tbl forall i e. Ix i => Array i e -> i -> e
! (Int
index forall a. Num a => a -> a -> a
+ Int
1)
in Double
y1 forall a. Num a => a -> a -> a
+ (Double
y2 forall a. Num a => a -> a -> a
- Double
y1) forall a. Num a => a -> a -> a
* (Double
x forall a. Num a => a -> a -> a
- Double
x1) forall a. Fractional a => a -> a -> a
/ (Double
x2 forall a. Num a => a -> a -> a
- Double
x1)
in Double
y
else
let y :: Double
y | Int
left forall a. Ord a => a -> a -> Bool
< Int
index = Int -> Int -> Double -> Double
find Int
left (Int
index forall a. Num a => a -> a -> a
- Int
1) Double
x
| Int
left forall a. Eq a => a -> a -> Bool
== Int
first = forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ Array Int (Double, Double)
tbl forall i e. Ix i => Array i e -> i -> e
! Int
left
| Bool
otherwise = forall a. HasCallStack => [Char] -> a
error [Char]
"Incorrect index: tableLookup"
in Double
y
tableLookupStepwise :: Double -> Array Int (Double, Double) -> Double
tableLookupStepwise :: Double -> Array Int (Double, Double) -> Double
tableLookupStepwise Double
x Array Int (Double, Double)
tbl = Int -> Int -> Double -> Double
find Int
first Int
last Double
x
where
(Int
first, Int
last) = forall i e. Array i e -> (i, i)
bounds Array Int (Double, Double)
tbl
find :: Int -> Int -> Double -> Double
find Int
left Int
right Double
x =
if Int
left forall a. Ord a => a -> a -> Bool
> Int
right then
forall a. HasCallStack => [Char] -> a
error [Char]
"Incorrect index: tableLookupStepwise"
else
let index :: Int
index = (Int
left forall a. Num a => a -> a -> a
+ Int
1 forall a. Num a => a -> a -> a
+ Int
right) forall a. Integral a => a -> a -> a
`div` Int
2
x1 :: Double
x1 = forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ Array Int (Double, Double)
tbl forall i e. Ix i => Array i e -> i -> e
! Int
index
in if Double
x1 forall a. Ord a => a -> a -> Bool
<= Double
x then
let y :: Double
y | Int
index forall a. Ord a => a -> a -> Bool
< Int
right = Int -> Int -> Double -> Double
find Int
index Int
right Double
x
| Int
right forall a. Eq a => a -> a -> Bool
== Int
last = forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ Array Int (Double, Double)
tbl forall i e. Ix i => Array i e -> i -> e
! Int
right
| Bool
otherwise = forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ Array Int (Double, Double)
tbl forall i e. Ix i => Array i e -> i -> e
! Int
right
in Double
y
else
let y :: Double
y | Int
left forall a. Ord a => a -> a -> Bool
< Int
index = Int -> Int -> Double -> Double
find Int
left (Int
index forall a. Num a => a -> a -> a
- Int
1) Double
x
| Int
left forall a. Eq a => a -> a -> Bool
== Int
first = forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ Array Int (Double, Double)
tbl forall i e. Ix i => Array i e -> i -> e
! Int
left
| Bool
otherwise = forall a. HasCallStack => [Char] -> a
error [Char]
"Incorrect index: tableLookupStepwise"
in Double
y