方案Lisp继续广场根的分数

时间:2018-02-07 06:30:38

标签: scheme lisp racket helper r5rs

我需要创建一个连续分数函数来查找数字的平方根并在平方根函数中使用它。我正在使用的系列和代码的重新排列版本如上所示。

{{1}}

这是我的连续分数函数,它似乎正在检查初始分数,但我无法继续经过第二个分数并在(newsquareroot xy)函数x变量中实现它以确定x' s平方根和y是递归分数递归调用的次数。我不确定是否应该更改contfract函数以调用自身一定次数或在newsquareroot函数中执行此操作。 continued fraction series

1 个答案:

答案 0 :(得分:1)

可能最好的方法是通过矩阵乘法,因为正数的平方根被简单地表示。如果a是N的整数平方根并且b = N-a ^ 2那么连续分数是a + b /(2a + b /(2a + b ...))。这可以用无限矩阵乘积((a b)(10))乘以无穷乘积((2a b)(10))来表示你想要的精度。当你拥有任意数量的术语时,只需将理性作为第一列。

这是一个应该易于扩展的例子。

#lang racket/base
(require math/number-theory)

(define (times left right)
  (define (transpose m)
    (apply map list m))
  (define r (transpose right))
  (for/list ((row left))
    (for/list ((col r))
      (apply + (map * row col)))))

(define iterations (make-parameter 50))

(define (square-root N)
  (define a (integer-root N 2))
  (define b (- N (* a a)))
  (if (zero? b)
      a
      (let* ((first-matrix (list (list a b) (list 1 0)))
             (2a (* 2 a))
             (rest-matrix (list (list 2a b) (list 1 0))))
        (let ((result-matrix
               (for/fold ((accum first-matrix))
                         ((i (in-range (iterations))))
                 (times accum rest-matrix))))
          (apply / (map car result-matrix))))))
 ;;;;;;
Welcome to DrRacket, version 6.12 [3m].
Language: racket/base [custom]; memory limit: 16384 MB.
> (square-root 2)
1 4866752642924153522/11749380235262596085
> (- (sqrt 2) (square-root 2))
0.0
> (square-root 23)
;;;4 and a huge fraction that breaks formatting here
> (- (sqrt 23) (square-root 23))
0.0
> 

顺便提一句continued fraction package可用,但它比这更复杂,并建立在序列之上。

修改 由于这是标记r5rs我应该这样写。我对球拍/ r5rs的合规性并不是100%肯定,但这样就可以了。

#lang r5rs

(define (transpose m)
  (apply map list m))

(define (row*col r c)
  (apply + (map * r c)))

(define (make-row* r)
  (lambda(c) (row*col r c)))

(define (times left right)
  (let ((r (transpose right)))
    (let loop ((rows left))
      (if (null? rows)
          '()
          (cons (map (make-row* (car rows))
                     r)
                (loop (cdr rows)))))))

(define (matrix-expt m e)
  (cond ((= 1 e) m)
        ((even? e) (matrix-expt (times m m)
                                (/ e 2)))
        (else (times m (matrix-expt (times m m)
                                    (/ (- e 1) 2))))))

(define (integer-root N exp)
  (letrec ((recur (lambda(i)
                    (let ((next (+ 1 i)))
                      (if (< N (expt next exp))
                          i
                          (recur next))))))
    (recur 1)))

(define (square-root N iters)
  (let* ((a (integer-root N 2))
         (b (- N (* a a))))
    (if (zero? b)
        a
        (let* ((first-matrix (list (list a b)
                                   (list 1 0)))
               (2a (* 2 a))
               (rest-matrix (list (list 2a b)
                                  (list 1 0)))
               (result-matrix
                (times first-matrix
                       (matrix-expt rest-matrix
                                    iters))))
          (apply / (map car result-matrix))))))