平方根的 Scheme Lisp 连分数

标签 scheme lisp racket helper r5rs

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

(define (contfrac x)
   (cond
     ((= x 0) 1)
     (contfrac (/ (- x 1) (+ 2 (- x 1))))))

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

最佳答案

可能最好的方法是通过矩阵乘法,因为正数的平方根很容易表示。如果 a 是 N 的整数平方根并且 b = N-a^2 则连分数是 a+b/(2a+b/(2a+b ...))。这可以用无限矩阵乘积 ((a b)(1 0)) 乘以无限乘积 ((2a b)(1 0)) 来表示,精度随心所欲。当您有任意多的项时,只需将有理数作为第一列即可。

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

#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,所以我应该这样写。我不是 100% 确定 racket/r5rs 合规性,但这运行。

#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))))))

关于平方根的 Scheme Lisp 连分数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48657356/

相关文章:

lisp - Common Lisp 有很大的遗产吗? (学习 Common Lisp 还是更现代的变体(例如 Scheme)更好?)

recursion - 方案中的汉诺塔(递归)

scheme - MIT/GNU 方案哈希表/修改!论点

haskell - s-expr 打印功能中的错误

macros - 如何使用 Racket 宏定义函数?

scheme - 申请申请Scheme

recursion - 调试简单的 LISP 函数。

methods - CLOS中 'Standard method combination'和 'Simple method combination'的区别

scheme - 删除列表的最后一个元素(方案)

linux - Racket - 导入 OpenCL