编程的科学/时光流逝
在 CME 的第 8 章中,SPT 讨论了牛顿如何使用变量上的一个点来表示微分,而莱布尼茨则使用了本书中的符号:. 莱布尼茨符号的优点是,它明确说明了在进行微分时应考虑哪个自变量(如果有多个自变量)。[1]
例如,如果
那么
另一方面,关于 t 而不是 x 进行微分得到
因为 被视为相对于自变量 t 的常数。也就是说,无论你改变 t 的值多少, 的值都不会改变(因为你没有改变 x,只是 t)。
到目前为止,我们一直在假设,自变量和我们求导的变量是同一个。
让我们研究一下如果我们不做出这样的假设,我们的代码可能是什么样子。
根据我们对术语构造器的可视化,我们一直假设自变量是 x,因为我们最终得到了像这样的可视化
3x^2
如果我们不硬编码自变量,我们将需要将其传递进来。以下是 term 的一个版本框架,其中自变量的名称将被传递进来
function term(a,iv,n) { function value(x) { ... } function toString() { ... } function diff(wrtv) { ... } this; }
新版 term 和旧版 term 之间的第一个主要区别在于,新版 term 有三个形式参数,而不是两个。第二个形式参数 iv(代表independent variable,即自变量),表示自变量。我们假设它将绑定到诸如 x、t 等符号。我们可以在基本 toString 方法(没有简化的那个)中看到这一点,它从
function toString() { "" + a + "x^" + n; }
变为
function toString() { "" + a + iv + "^" + n; }
注意,原始版本中的 x 是字符串的一部分,因此是固定的。在第二个版本中,iv 是一个变量,它被(或更确切地说将被)绑定到一个符号。看一下可视化将有助于我们理清思路
var t = term(5,:w,3); sway> t . toString(); STRING: 5w^3
第二个主要变化是,微分方法 diff 现在接受一个参数 wrtv,它代表with-respect-to variable(即关于哪个变量微分)。如果自变量和关于哪个变量微分的变量相同,则微分将像以前一样进行。如果不相同,则会生成一个常数零
function diff(wrtv) { if (wrtv == iv) { if(n == 0,term(0,iv,0),term(a * n,iv,n - 1)); } else { constant(0); } }
现在让我们测试一下
var a = t . diff(:w); //iv and wrtv match var b = t . diff(:x); //iv and wrtv do not match sway> t . toString(); STRING: 5w^3 sway> a . toString(); STRING: 15w^2 sway> b . toString(); STRING: 0
此输出假设 term 的 toString 方法执行了上一章中讨论的简化。
我们不需要更改术语的 value 方法。这是因为使用了自变量的值,而不是它的名称。换句话说,value 方法执行数值计算,而 diff 方法执行符号计算。因此,value 需要一个数字,而 diff 需要一个名称。
由于 toString 和 diff 都使用术语变量的名称而不是值,因此它们都需要修改,因为名称不再是硬编码的。
1. 如果我们将形式参数 iv 重命名为 x 并且将所有 iv 的出现替换为 x 会发生什么?解释一下。
2. 重新定义简化的 term 构造器,使其不再假设自变量是 x。
3. 重新定义简化的 sum 构造器,使其不再假设自变量是 x。
4. 完成朴素的微分系统(minus、times 和 div)。
5. 使用 sway 做 p. 92 上的 2。
6. 使用 sway 做 p. 92 上的 4 和 5。
7. 我们正在玩一个把沙包扔进垃圾桶的游戏,我们想正确地模拟物理现象。水平位移为 ,垂直位移为 。x 和 z 关于 t 的变化是什么?令 ,,,并且 。绘制 x 和 z 以及 x 和 z 方向上的速度与时间的关系图,时间范围为 0 到 10。
- ↑ 正如 SPT 指出的那样,点符号是在假设关于时间 t 进行微分的情况下使用的。因此,本章的名称。