이 문제는 아주 재미있는 문제입니다.

power series를 스트림으로 구현하는데,

특히 b번이 아주 흥미로운 결과를 보여주었습니다.

 

 

a. 수열을 적분하는 프로시저를 만드는 문제입니다.

간단히 integer 스트림과 계수 스트림을 나누는 것으로 해결하였습니다.

 

 

b. cosine과 sine 함수를 정의하는 문제입니다.

예제로 나온 exponential 함수의 정의는 자기 자신을 적분하는 것으로 나와있습니다.

왜냐하면 exponential 함수는 미분을 하나 적분을 하나 자기 자신이기 때문입니다.

(물론 부정적분을 하면 상수가 나오겠죠.)

 

이에 맞춰 cosine과 sine 함수 정의에 각각을 적분하는 것으로 끼워넣었습니다.

처음에는 잘 되겠는가 싶었으나 의외로 깔끔하게 답이 나왔습니다.

 

서로가 서로를 정의하는데 쓰이고 있음에도 이렇게 잘 나오다니... 놀랐습니다.^^

스트림을 사용하면 이런 것도 가능하군요.^^

 

 

참조

해럴드 애빌슨, 김재우 역, <컴퓨터 프로그램의 구조와 해석>, 인사이트, 2007, pp. 432

 

 

; stream
(define true (= 0 0))
(define false (= 1 0))

(define (cons-stream a b)
  (cons a (delay b)))
(define the-empty-stream '())
(define stream-null? null?)
(define (stream-car stream) (car stream))
(define (stream-cdr stream) (force (cdr stream)))

; section 3.5
(define (stream-ref s n)
  (if (= n 0)
      (stream-car s)
      (stream-ref (stream-cdr s) (- n 1))))

(define (stream-for-each proc s)
  (if (stream-null? s)
      'done
      (begin (proc (stream-car s))
             (stream-for-each proc (stream-cdr s)))))

(define (display-stream s)
  (stream-for-each display-line s))

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

(define (stream-enumerate-interval low high)
  (if (> low high)
      the-empty-stream
      (cons-stream
       low
       (stream-enumerate-interval (+ low 1) high))))

(define (stream-filter pred stream)
  (cond ((stream-null? stream) the-empty-stream)
        ((pred (stream-car stream))
         (cons-stream (stream-car stream)
                      (stream-filter pred
                                     (stream-cdr stream))))
        (else (stream-filter pred (stream-cdr stream)))))

(define (memo-proc proc)
  (let ((already-run? false) (result false))
    (lambda ()
      (if (not already-run?)
          (begin (set! result (proc))
                 (set! already-run? true)
                 result)
          result))))

(define (scale-stream stream factor)
  (stream-map (lambda (x) (* x factor)) stream))

; exercise 3.50
(define (stream-map proc . argstreams)
  (if (stream-null? (car argstreams))
      the-empty-stream
      (cons-stream
       (apply proc (map stream-car argstreams))
       (apply stream-map
              (cons proc (map stream-cdr argstreams))))))

;;;SECTION 3.5.2
(define (add-streams s1 s2)
  (stream-map + s1 s2))

(define ones (cons-stream 1 ones))
(define integers (cons-stream 1 (add-streams ones integers)))

; exercise 3.54
(define (mul-streams s1 s2)
  (stream-map * s1 s2))

; exercise 3.56
(define (merge s1 s2)
  (cond ((stream-null? s1) s2)
        ((stream-null? s2) s1)
        (else
         (let ((s1car (stream-car s1))
               (s2car (stream-car s2)))
           (cond ((< s1car s2car)
                  (cons-stream s1car (merge (stream-cdr s1) s2)))
                 ((> s1car s2car)
                  (cons-stream s2car (merge s1 (stream-cdr s2))))
                 (else
                  (cons-stream s1car
                               (merge (stream-cdr s1)
                                      (stream-cdr s2)))))))))

; answer
(define (print-stream-n S n)
  (define (iter i)
    (if (= i n)
        'done
        (begin (display (stream-ref S i))
               (display "  ")
               (if (= (remainder (+ i 1) 10) 0)
                   (newline))
               (iter (+ i 1)))))
  (iter 0))

; a
(define (div-streams s1 s2)
  (stream-map / s1 s2))

(define (integrate-series coff_stm)
  (let ((integrate_s (cons-stream 1 ; 상수 c
                                  (div-streams coff_stm integers))))
    (stream-cdr integrate_s)))

; execute
(define a (scale-stream integers 10))
(define b (integrate-series a))
(print-stream-n a 10)
(print-stream-n b 10)
(newline)

; b
(define exp-series
  (cons-stream 1 (integrate-series exp-series)))
(define cosine-series
  (cons-stream 1
               (integrate-series (scale-stream sine-series -1))))
(define sine-series
  (cons-stream 0
               (integrate-series cosine-series)))

; execute
(print-stream-n exp-series 10)
(print-stream-n cosine-series 10)
(print-stream-n sine-series 10)

크리에이티브 커먼즈 라이센스
Creative Commons License

글에 잘못된 점, 다른 점, 부족한 점이 있다면 지적해주세요.
댓글, 트랙백, 메일 모두 고맙습니다.

트랙백 주소 :: http://nosyu.pe.kr/trackback/1618

댓글을 달아 주세요

[로그인][오픈아이디란?]