通过原始表达,我的意思是+ - * / sqrt
,除非我缺少其他表达。我想知道如何编写一个仅使用这些函数找到第 6 个根的 Scheme 表达式。
我知道我可以找到平方根的立方根,但立方根似乎不是一个原始表达式。
通过原始表达,我的意思是+ - * / sqrt
,除非我缺少其他表达。我想知道如何编写一个仅使用这些函数找到第 6 个根的 Scheme 表达式。
我知道我可以找到平方根的立方根,但立方根似乎不是一个原始表达式。
考虑expt,将分数幂作为其第二个参数传递。
但是,假设我们不知道expt
. 我们还能计算吗?
一种方法是应用类似Newton's method 的方法。例如,假设我们要计算 n^(1/4)。当然,我们已经知道我们可以只用sqrt
两次就可以做到这一点,但让我们看看牛顿的方法如何适用于这个问题。
给定n
,我们想发现x
函数的根源:
f(x) = x^4 - n
具体来说,如果我们想寻找16^(1/4)
,那么我们会寻找函数的根:
f(x) = x^4 - 16
我们已经知道如果我们x=2
在那里插入,我们会发现这2
是这个函数的根。但是说我们不知道。我们如何发现x
使这个函数为零的值?
牛顿的方法说,如果我们对 有一个猜测x
,调用它x_0
,我们可以通过执行以下过程来改进这个猜测:
x_1 = x_0 - f(x_0) / f'(x_0)
其中f'(x)
是 的导数的符号f(x)
。对于上述情况, 的导数f(x)
是4x^3
。
我们可以通过重复计算得到更好的猜测x_2
, x_3
, ...
x_2 = x_1 - f(x_1) / f'(x_1)
x_3 = x_2 - f(x_2) / f'(x_2)
...
直到我们累了。
现在让我们用代码编写所有内容:
(define (f x)
(- (* x x x x) 16))
(define (f-prime x)
(* 4 x x x))
(define (improve guess)
(- guess (/ (f guess)
(f-prime guess))))
(define approx-quad-root-of-16
(improve (improve (improve (improve (improve 1.0))))))
上面的代码只是表达了f(x)
, f'(x)
, 以及将初始猜测提高五次的想法。让我们看看它的价值approx-quad-root-of-16
是什么:
> approx-quad-root-of-16
2.0457437305170534
嘿,酷。它实际上正在做某事,并且接近于2
. 从如此糟糕的第一次猜测开始也不错1.0
。
当然,16
在那里硬编码有点傻。让我们概括一下,把它变成一个接受任意值的函数n
,这样我们就可以计算任何东西的四根:
(define (approx-quad-root-of-n n)
(define (f x)
(- (* x x x x) n))
(define (f-prime x)
(* 4 x x x))
(define (improve guess)
(- guess (/ (f guess)
(f-prime guess))))
(improve (improve (improve (improve (improve 1.0))))))
这有什么效果吗?让我们来看看:
> (approx-quad-root-of-n 10)
1.7800226459895
> (expt (approx-quad-root-of-n 10) 4)
10.039269440807693
酷:它正在做一些有用的事情。但请注意,它还不是那么精确。为了获得更好的精度,我们应该继续调用improve
,而不是四五次。思考循环或递归:重复改进,直到解决方案“足够接近”。
这是如何解决这些问题的草图。有关更多详细信息,请查看计算机程序的结构和解释中有关计算平方根的部分。
您可能想尝试一种数字方式,这对于较大的数字可能效率低下,但它确实有效。
此外,如果你也算作pow
一个原始人(因为你也 count sqrt
),你可以这样做:
pow(yournum, 1/6);