提交 7b380a80 编写于 作者: W wizardforcel

4.2

上级 b4a53b50
# Approximating square root
# 近似平方根
There are a lot of useful functions that have no closed form solution, meaning we can't just do a computation and return the value. Instead, we need to use an iterative method to approximate the function value. We can use this to approximate sine (with Taylor series expansion), approximate square root (as we'll do in this lecture), or optimize a cost or error function (gradient descent in next lecture).
有许多有用的函数没有闭式解,这意味着我们不能只进行计算并返回值。 相反,我们需要使用迭代方法来近似函数值。 我们可以用它来近似正弦(用泰勒级数展开),近似平方根(我们将在本课程中做),或优化成本或误差函数(下一讲的梯度下降)。
As with the previous uniform random variable lecture, we must translate a recurrence relation to Python. Instead of returning a single value in the recurrence series, we will look for **convergence of the series**. In other words, if we run the series out far enough, $x_{i+1}$ will be close to $x_i$ leaving $x_i$ as a very accurate approximation of square root. This will teach us the basics of iterative computing and prepare us for the more complicated function optimization material.
与之前的统一随机变量讲座一样,我们必须将递归关系转换为 Python。 我们将寻找收敛**序列**,而不是返回递推序列中的单个值。 换句话说,如果我们将序列计算得足够远,`x_{i + 1}`将接近`xi`,使`xi`成为平方根的非常准确的近似值。 这将教会我们迭代计算的基础知识,并为更复杂的函数优化材料做好准备。
## 巴比伦方法
## Babylonian method
为了近似平方根,我们的想法是选择一个初始估计值`x0`,然后使用[巴比伦方法](https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)来更好地的估计和迭代值`xi`。递归关系:
To approximate square root, the idea is to pick an initial estimate, $x_0$, and then iterate with better and better estimates, $x_i$, using the ([Babylonian method](https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)) recurrence relation:
$x_{i+1} = \frac{1}{2}(x_i + \frac{n}{x_i})$
```
x{i+1} = 1/2 (xi + n/xi)
```
There’s a great deal on the web you can read to learn more about why this process works but it relies on the average (midpoint) of $x_i$ and $n/x_i$ getting us closer to the square root of n. The cool thing is that the iteration converges quickly.
网上有很多东西你可以阅读,来更多了解为什么这个过程有效,但它依赖于`xi``n / xi`的平均值(中点),让我们更接近`n`的平方根。很酷的是迭代很快收敛。
Our goal is to write a function that takes a single number and returns it square root. What do we know about this function before even beginning to code? Well, we have a clear description of the problem per our function workplan, and we also have the function signature we want:
我们的目标是编写一个函数,它接受一个数字并将其返回平方根。 在开始编码之前我们对这个函数了解多少? 好吧,根据我们的函数工作计划,我们有一个明确的问题描述,我们也有我们想要的函数签名:
```python
def sqrt(n):
```
Because we are implementing a recurrence relation, we know that we will have a loop that computes $x_{i+1}$ from $x_{i}$.
### Convergence
因为我们正在实现递归关系,所以我们知道我们将有一个循环,从`xi`计算`x{i + 1}`
The terminating condition of the loop is when we have reached convergence or close to it. Convergence just means that $x_{i+1}$ is pretty close to $x_i$. Because we can never compare to real numbers for equality, we have to check for the difference being smaller than some precision like 0.00000001.
### 收敛
### Iterative method outline
循环的终止条件是当我们达到收敛或接近收敛。 收敛只意味着`x{i + 1}`非常接近`xi`。 因为我们永远无法比较实数,所以我们必须检查差异是否小于某些精度,如 0.00000001。
Just as we have an outline for an analytics program, iterative methods all share the same basic outline. (I'm assuming here that $x_{i+1}$ depends only on a single previous value and that $i$ implicitly increments as the loop goes around.)
### 迭代方法的大纲
*set $x_0$ to initial value*<br>
*repeat:*<br>
&nbsp;&nbsp;&nbsp;&nbsp;$x_{i+1} =$ function-giving-next-value$(x_i)$<br>
*until $abs(x_{i+1} - x_i) \lt precision$<br>
return $x_{i+1}$*<br>
正如我们有一个分析程序的大纲,迭代方法都共享相同的基本大纲。 (我在这里假设`x{i + 1}`仅取决于一个先前的值,并且`i`在循环转换时隐式递增。)
Because Python does not have a repeat-until loop, we fake it with an infinite loop containing a conditional that breaks us out upon convergence:
+`x0`设为初始值
+ 重复:
+ `function-giving-next-value(xi)`
+ 直到`abs(x{i+1} - xi) < precision`
+ 返回`x{i+1}`
*set $x_0$ to initial value*<br>
*while True:*<br>
&nbsp;&nbsp;&nbsp;&nbsp;$x_{i+1} =$ function-giving-next-value$(x_i)$<br>
&nbsp;&nbsp;&nbsp;&nbsp;*if $abs(x_{i+1} - x_i) \lt precision$<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $x_{i+1}$*<br>
因为 Python 没有`do-while`循环,所以我们用一个包含条件的无限循环来伪造它,这会在收敛时中断:
That is a fairly straightforward implementation of the recurrence relation, but you will notice that we don't actually need to keep all previous $x_i$ around except for the new value and the previous value. Here is a Python implementation that tracks only two values and follows the infinite loop pattern:
+`x0`设为初始值
+ `while True:`
+ `function-giving-next-value(xi)`
+ 如果`abs(x{i+1} - xi) < precision`
+ 返回`x{i+1}`
这是一个相当简单的递归关系实现,但你会注意到,我们实际上不需要保留所有先前的`xi`,除了新值和前一个值。 这是一个 Python 实现,它只跟踪两个值并遵循无限循环模式:
```python
def sqrt(n):
......@@ -79,15 +79,7 @@ sqrt(100)
# 10.0
```
To test our square root approximation, we can compare it to `math.sqrt()` and use numpy's `isclose` to do the comparison.
为了测试我们的平方根近似,我们可以将它与`math.sqrt()`进行比较,并使用 numpy 的`isclose`来进行比较。
```python
import numpy as np
......@@ -103,11 +95,11 @@ def test_sqrt():
test_sqrt()
```
As you can see we can define a function within a function. It's not special in any way except that code outside of `test_sqrt()` cannot see function `check()`. On the other hand, `check()` **can** see the symbols outside of `test_sqrt()`, such as our `sqrt()`.
如您所见,我们可以在函数中定义函数。 除了`test_sqrt()`之外的代码看不到函数`check()`之外,它没有任何特殊之处。 另一方面,`check()`**可以**看到`test_sqrt()`之外的符号,比如我们的`sqrt()`
### Exercise
### 练习
Type in (don't cut/paste) the `sqrt(n)` function and test with, for example, `sqrt(125348.0)`. Make sure you get the right answer (354.045195) and then add print statements so that you can see the sequence of $x_{i}$ values. I get:
输入(不要剪切/粘贴)`sqrt(n)`函数并测试,例如,`sqrt(125348.0)`。 确保得到正确的答案(354.045195),然后添加`print`语句,以便您可以看到`xi`值的序列。 我得到了:
```
1.0
......@@ -126,8 +118,7 @@ Type in (don't cut/paste) the `sqrt(n)` function and test with, for example, `sq
354.045194855
```
Notice how quickly it converges!
注意它收敛得多快!
```python
def sqrt_with_trace(n):
......@@ -163,4 +154,4 @@ sqrt_with_trace(125348.000000)
'''
```
Now that we know how to implement a recurrence relation that converges, let's take a look at function optimization. At first glance, it seems completely different, but uses the same abstraction of an iterative method.
现在我们知道了如何实现收敛的递归关系,让我们来看看函数优化。 乍一看,它看起来完全不同,但使用了迭代方法的相同抽象。
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册