HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Implementing Division of Streams (where it's a stream of polynomial coefficients)

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
streamdivisionpolynomialwherecoefficientsstreamsimplementing

Problem

Per this homework, I'm trying to implement a Fractional (Stream Integer) where the stream represents coefficients of polynomials:


where Q is defined as Q = (A'/b0) + x((1/b0)(A' − QB0)).


where A/B = Q,


That is, the first element of the result is A'/b0; the remainder is
formed by computing A' − QB' and dividing each of its elements by b0


Note that A' == tail of A and same for B'

Here's my attempt:

divStreams :: Stream Integer -> Stream Integer -> Stream Integer
divStreams a@(Cons x xs) b@(Cons y ys) = 
    Cons (x `div` y) (streamMap ((1 `div` y) *) xs - (multStreams q ys) ) 
      where q = divStreams a b


with the following functions' definitions:

multStreams :: Stream Integer -> Stream Integer -> Stream Integer
multStreams (Cons x xs) b@(Cons y ys) = 
    Cons (x * y) (streamMap (*x) ys + multStreams xs b)

data Stream a = Cons a (Stream a)

streamMap :: (a -> b) -> Stream a -> Stream b
streamMap f (Cons x xs) = Cons (f x) rest
   where rest = streamMap f xs


Note that I defined Num (Stream Integer) where (+) == combineStreams (+)

combineStreams :: (a -> b -> c) -> Stream a -> Stream b -> Stream c
combineStreams f (Cons x xs) (Cons y ys) = Cons (f x y) rest
   where rest = combineStreams f xs ys


Thanks to this answer that resolved an issue I had implementing multiplication of Streams.

Solution

There are a couple of cases where using where isn't gaining us anything. For instance, combineStreams can just be written as

combineStreams :: (a -> b -> c) -> Stream a -> Stream b -> Stream c
combineStreams f (Cons x xs) (Cons y ys) = Cons (f x y) (combineStreams f xs ys)


Same goes for streamMap.

If you're not using combineStreams anywhere else, we can just write

instance Num (Stream Integer) where
    (Cons x xs) + (Cons y ys) = Cons (x + y) (xs + ys)


I just want to repeat the definition given in the homework, for clarity:


If \$A = a_0 + x A'\$ and \$B = b_0 + x B'\$, then \$A / B = Q\$,
where \$Q\$ is defined as


\begin{align} Q = (a_0 / b_0) + x((1 / b_0)(A' - QB')). \end{align}

Your definition of divStreams is very close to this, but we can use the following trick where q refers to itself, just as in the formula above:

divStreams :: Stream Integer -> Stream Integer -> Stream Integer
divStreams (Cons x xs) (Cons y ys) = 
    let q = Cons (x `div` y) (streamMap ((1 `div` y) *) (xs - q * ys)) in q


assuming you have defined * to be multStreams.

Code Snippets

combineStreams :: (a -> b -> c) -> Stream a -> Stream b -> Stream c
combineStreams f (Cons x xs) (Cons y ys) = Cons (f x y) (combineStreams f xs ys)
instance Num (Stream Integer) where
    (Cons x xs) + (Cons y ys) = Cons (x + y) (xs + ys)
divStreams :: Stream Integer -> Stream Integer -> Stream Integer
divStreams (Cons x xs) (Cons y ys) = 
    let q = Cons (x `div` y) (streamMap ((1 `div` y) *) (xs - q * ys)) in q

Context

StackExchange Code Review Q#68043, answer score: 2

Revisions (0)

No revisions yet.