exercise 3.58~62

やっとch3.5.2が終わった・・・
いつになったら4章にたどり着くのやら。


っとその前に、無限リストだとdisplay-streamではちょっと不便なので

(define (display-stream-n-lines stream n)
  (if (= n 0)
      'done
      (begin (display-line (stream-car stream))
             (display-stream-n-lines (stream-cdr stream) (- n 1)))))

(define (display-line x)
  (display x)
  (newline))

としておく。
ちなみにdisplay-lineはちょろっと変更してある。

ex3.58
gosh> (display-stream-n-lines (expand 1 7 10) 10)   
1                                                   
4                                                   
2                                                   
8                                                   
5                                                   
7                                                   
1                                                   
4                                                   
2                                                   
8                                                   
done 
gosh> (display-stream-n-lines (expand 3 8 10) 10)   
3                                                   
7                                                   
5                                                   
0                                                   
0                                                   
0                                                   
0                                                   
0                                                   
0                                                   
0                                                   
done  

となる。
以下と比べると

gosh> (/ 1.0 7.0)                                   
0.14285714285714285                                 
gosh> (/ 3.0 8.0)                                   
0.375

radix進法で商を求めていると分かる。

ex3.59
(define (integrate-series stream)
  (stream-map / stream (integers-starting-from 1)))

(define exp-series
  (cons-stream 1 (integrate-series exp-series)))

(define cosine-series
  (cons-stream 1 (stream-map
                  (lambda (x) (* x -1))
                  (integrate-series sine-series))))

(define sine-series
 (cons-stream 0 (integrate-series cosine-series)))

小数で表示させたきゃinetgral-sereisでintgersの代わりに(integer-starting-from 1.0)とかやればおk。

gosh> (display-stream-n-lines exp-series 10)        
1                                                   
1                                                   
1/2                                                 
1/6                                                 
1/24                                                
1/120                                               
1/720                                               
1/5040                                              
1/40320                                             
1/362880                                            
done
gosh> (display-stream-n-lines cosine-series 10)     
1                                                   
0                                                   
-1/2                                                
0                                                   
1/24                                                
0                                                   
-1/720                                              
0                                                   
1/40320                                             
0                                                   
done
gosh> (display-stream-n-lines sine-series 10)       
0                                                   
1                                                   
0                                                   
-1/6                                                
0                                                   
1/120                                               
0                                                   
-1/5040                                             
0                                                   
1/362880                                            
done 
ex3.60
(define (mul-series s1 s2)
  (cons-stream (* (stream-car s1) (stream-car s2))
               (add-stream
                (stream-map
                 (lambda (x) (* x (stream-car s1)))
                 (stream-cdr s2))
                (mul-series (stream-cdr s1) s2))))

で、

gosh> (display-stream-n-lines 
(add-stream 
(mul-series cosine-series cosine-series) 
(mul-series sine-series sine-series)) 
10)                              
1                                                   
0                                                   
0                                                   
0                                                   
0                                                   
0                                                   
0                                                   
0                                                   
0                                                   
0                                                   
done

と、確かに問題文のとおりですな。

ex3.61
(define (invert-unit-series S)
  (define X (cons-stream 1
                         (stream-map
                          (lambda (x) (* x -1))
                          (mul-series X (stream-cdr S)))))
  X)
ex3.62
(define (div-series s1 s2)
  (define (invert S)
    (stream-map (lambda (x) (/ x (stream-car S))) (invert-unit-series S)))
  (if (= (stream-car s2) 0)
      (error "ZERO!!!!!!!!!!!!" (stream-car s2)) ;;何このエラー判定・・・
      (mul-series s1 (invert s2))))

(define tangent-series
  (div-series sine-series cosine-series))

出力は

gosh> (display-stream-n-lines tangent-series 10)    
0                                                   
1                                                   
0                                                   
1/3                                                 
0                                                   
2/15                                                
0                                                   
17/315                                              
0                                                   
62/2835                                             
done

であってたよね・・・。
あと、どうでもいいけど

(define zeros (cons-stream 0 zeros))
(define constant-is-one (cons-stream 1 zeros))

 (define tangent-series
   (cons-stream 0
                (integrate-series
                 (div-series constant-is-one
                             (mul-series cosine-series cosine-series)))))

とかでもうまくいくのな