Dear All, I am trying to translate some codes of mine into haskell. It looks like Haskell can shorten quite a bit the implementation of mathematical formulas. Let us say you have two list of real numbers; let us call them y and t. The list t is increasing (a sort of time). Now consider the couples (t_a, y_a) and (t_b,y_b) where t_a<t_b i.e. two (non-simultaneous) values of t and the corresponding y_a and y_b. There are no assumptions on y. What I would like to write is a function which checks the existence (t_c,y_c), where y_a<y_c<y_b (i.e. y_c is some intermediate time) such that y_c<y_b+(y_a-y_b)*(t_b-t_c)/(t_b-t_a). I have already implemented this in other languages, but I ended up with quite lengthy functions (what if a list is empty, what if it has fewer than 2-3 elements and so on...). Also, it would be nice to iterate this function on all possible combinations (t_a, y_a) and (t_b,y_b), t_a<t_b I can form from my data. I am not asking someone to 'do my homework', rather I would like to see how much more compact things can get in haskell. Many thanks Lorenzo
On Friday 10 September 2010 18:35:45, Lorenzo Isella wrote:
Dear All, I am trying to translate some codes of mine into haskell. It looks like Haskell can shorten quite a bit the implementation of mathematical formulas. Let us say you have two list of real numbers; let us call them y and t. The list t is increasing (a sort of time). Now consider the couples (t_a, y_a) and (t_b,y_b) where t_a<t_b i.e. two (non-simultaneous) values of t and the corresponding y_a and y_b. There are no assumptions on y. What I would like to write is a function which checks the existence (t_c,y_c), where y_a<y_c<y_b (i.e. y_c is some intermediate time) such that
I suppose that should've been t_a < t_c < t_b since you speak of times.
y_c<y_b+(y_a-y_b)*(t_b-t_c)/(t_b-t_a).
I have already implemented this in other languages, but I ended up with quite lengthy functions (what if a list is empty, what if it has fewer than 2-3 elements and so on...). Also, it would be nice to iterate this function on all possible combinations (t_a, y_a) and (t_b,y_b), t_a<t_b I can form from my data. I am not asking someone to 'do my homework', rather I would like to see how much more compact things can get in haskell. Many thanks
Lorenzo
-- Event has time and value, probably some other name would be more appropriate type Event = (Double, Double) combinations :: (Event -> Event -> Event -> Bool) -> [Event] -> [((Event, Event), [Event])] combinations _ [] = [] combinations cond (e:es) = sat e [] es ++ combinations cond es where sat _ _ [] = [] sat start between (now : later) = ((start, now), filter (cond start now) between) : sat start (now : between) later gives you a list of all pairs of events together with all intermediate events satisfying the condition. To check whether for a pair of events there are any intermediate events satisfying the condition, use (not . null . snd). To find out how many, (length . snd). If you have many events, however, using a list would probably be too inefficient, then instead of a [(Double, Double)], you'd better use a Data.Map.Map Double Double (or use a newtype for the time if you calculate the times in different ways, in floating point math, sin (2*x) == 2 * sin x * cos x isn't always true).
participants (2)
-
Daniel Fischer -
Lorenzo Isella