sicp-ex-3.60



<< Previous exercise (3.59) | Index | Next exercise (3.61) >>


meteorgan

  
  
 (define (mul-series s1 s2) 
   (cons-stream (* (stream-car s1) (stream-car s2)) 
                (add-streams 
                 (scale-stream (stream-cdr s2) (stream-car s1)) 
                 (mul-series (stream-cdr s1) s2)))) 
  
  
 (define (mul-series s1 s2) 
   (cons-stream (* (stream-car s1) 
                   (stream-car s2)) 
                (add-streams (mul-streams (stream-cdr s1) 
                                          (stream-cdr s2)) 
                             (mul-series s1 s2)))) 
  
 (define (mul-series2 s1 s2) 
   (partial-sums (mul-streams s1 s2))) 
  
  
  
 (define (mul-series s1 s2) 
   (cons-stream 
    (* (stream-car s1) (stream-car s2)) 
    (add-streams (add-streams 
                  (scale-stream (stream-cdr s1) (stream-car s2)) 
                  (scale-stream (stream-cdr s2) (stream-car s1))) 
                 (cons-stream 0 
                              (mul-series (stream-cdr s1) 
                                          (stream-cdr s2)))))) 
  
atupal is correct

meteorgan is also correct. Also see seok's comment.

zzd3zzd's implementation is weird and is wrong. This can be easily found by checking the former few coeffs of the result. Assume we want to multiply (a+bx+...)*(c+dx+...). Then zzd3zzd's result is (ac)+(bd+ac)x+... . Here coeff of x should be ad+bc.

------

See http://community.schemewiki.org/?sicp-ex-3.55 meteorgan's comment. Here recursive calls of (mul-series (stream-cdr s1) s2) won't reuse the former calculated results. So the problem in sicp-ex-3.55 doesn't exist here.

This can be checked by thinking of (* (stream-car s1) (stream-car s2)) as connecting (stream-car s1) and (stream-car s2). Then (scale-stream (stream-cdr s2) (stream-car s1)) connects (stream-car s1) to the rest of s2. Then (mul-series (stream-cdr s1) s2) just does the former sequence operation for the 2nd, 3rd ... element of s1. So no "recalculation".

After iterating through s1, we do add-streams and then cons-stream for the last element of s1 and then the second to last, ... until the 1st.

---

If you have difficulty about the above 2nd paragraph sequence, you can think of mul-series doing similar things as the book integers-starting-from but with the different step.






seok

meteorgan and atupal are correct and zzd3zzd is wrong according to my checker.

  
 (define (display-stream-until n s)     ; n-th value included 
   (if (< n 0) 
       the-empty-stream 
       (begin (newline) (display (stream-car s)) 
              (display-stream-until (- n 1) (stream-cdr s))))) 
  
 ; It can be easily seen that (mul-series (stream-cdr s1) s2) equals 
 ; (add-streams (scale-stream (stream-cdr s2) (stream-car s1)) 
 ;              (cons-stream 0 (mul-series (stream-cdr s1) (stream-cdr s2)))) 
 ; , which means that meteorgan's solution and atupal's solution are equivalent. 
  
 (define (mul-series s1 s2) 
   (cons-stream (* (stream-car s1) (stream-car s2)) 
                (add-streams (scale-stream (stream-cdr s1) (stream-car s2)) 
                             (mul-series (stream-cdr s2) s1)))) 
  
 (define circle-series 
   (add-streams (mul-series cosine-series cosine-series) 
                (mul-series sine-series sine-series))) 
  
 ; if you see one 1 followed by 0's, your mul-series is correct. 
 (display-stream-until 30 circle-series) 
  
  

Patrick-OHara

I agree with seok. However, in testing with non-infinite series I found that the book's version of stream-map does not cope with series of different lengths, and so gives an incorrect result for mul-series applied to non-infinite series. See http://community.schemewiki.org/?sicp-ex-3.50 for my fix for this.


joshroybal

  
  
 (define (mul-series s1 s2) 
   (cons-stream (* (stream-car s1) (stream-car s2)) 
                (add-streams 
                 (scale-stream (stream-cdr s2) (stream-car s1)) 
                 (mul-series (stream-cdr s1) s2))))