
On Sun, Feb 26, 2006 at 01:00:54PM +0000, Chris Kuklewicz wrote:
To: Matthias Fischmann
Cc: haskell-cafe@haskell.org From: Chris Kuklewicz Date: Sun, 26 Feb 2006 13:00:54 +0000 Subject: Re: [Haskell-cafe] rounding errors with real numbers. Your solution works, but is slightly wasteful with (repair) traversing the whole list again. Here is a slightly more efficient expression:
-- Precondition: The first parameter (xs) is sorted (ascending) : -- assert (all (zipWith (<=) (xs, tail xs))) -- low' < high' -- low < high normInterval :: [Double] -> Double -> Double -> [Double] normInterval xs low high = let low' = head xs; high' = last xs; scale = (high-low)/(high'-low') middle = init (tail xs) in (low : [scale*(x-low')+low) | x <-middle])++[high]
hi chris, i like this code better, too. slightly better still, because of fewer typos: normInterval :: [Double] -> Double -> Double -> [Double] normInterval ps lower upper = assert check ([lower] ++ [ stretch * (p - oldLower) + lower | p <- middle ] ++ [upper]) where check = lower < upper && oldLower < oldUpper && (and (zipWith (<=) ps (tail ps))) oldLower = head ps oldUpper = last ps stretch = (upper - lower) / (oldUpper - oldLower) middle = init (tail ps) but then i'll just take this as the best solution. thanks, matthias