The integral procedure at the end of the preceding section shows how we
can use streams to model signal-processing systems that contain feedback loops.
The feedback loop for the adder shown in Figure 3.32 is modeled by the
fact that integral’s internal stream int is defined in terms of
itself:
上一节末尾的 integral 过程展示了如何用流来对含有反馈回路的信号处理系统建模。图 3.32 中加法器的反馈回路,通过 integral 的内部流 int 以自身来定义这一事实得到刻画:
The interpreter’s ability to deal with such an implicit definition depends on
the delay that is incorporated into cons-stream. Without this
delay, the interpreter could not construct int before evaluating
both arguments to cons-stream, which would require that int
already be defined. In general, delay is crucial for using streams to
model signal-processing systems that contain loops. Without delay, our
models would have to be formulated so that the inputs to any signal-processing
component would be fully evaluated before the output could be produced. This
would outlaw loops.
解释器能够处理这种隐式定义,依赖于 cons-stream 中内置的延迟。若没有这一延迟,解释器在构造 int 之前就必须对 cons-stream 的两个参数全部求值,而这又要求 int 已经定义好。一般来说,delay 对于用流来对含有回路的信号处理系统建模至关重要。没有延迟,我们的模型就必须保证:在产生任何信号处理部件的输出之前,该部件的所有输入都已完全求值。这将使回路无从存在。
Unfortunately, stream models of systems with loops may require uses of
delay beyond the “hidden” delay supplied by cons-stream.
For instance, Figure 3.34 shows a signal-processing system for solving
the differential equation d
y
遗憾的是,带有回路的系统的流模型,有时需要在 cons-stream 所提供的"隐式"延迟之外额外使用 delay。例如,图 3.34 展示了一个用于求解微分方程 d
y 的信号处理系统
/
d
t
=
f
(
y
) where f is a given
function. The figure shows a mapping component, which applies f to its
input signal, linked in a feedback loop to an integrator in a manner very
similar to that of the analog computer circuits that are actually used to solve
such equations.
d
t
=
f
(
y
),其中 f 是给定的函数。图中显示了一个映射部件,它对输入信号施用 f,并以与实际用于求解此类方程的模拟计算机电路非常相似的方式,通过反馈回路与一个积分器相连。
Figure 3.34: An “analog computer circuit” that solves the equation d
y
图 3.34:求解方程 d
y 的"模拟计算机电路"
/
d
t
=
f
(
y
).
d
t
=
f
(
y
)。
Assuming we are given an initial value y
0 for y, we could try to model
this system using the procedure
假设已知 y 的初始值 y
0,我们可以尝试用下面的过程来对该系统建模
This procedure does not work, because in the first line of solve the
call to integral requires that the input dy be defined, which
does not happen until the second line of solve.
这个过程行不通,因为在 solve 第一行对 integral 的调用要求输入 dy 已经定义,而 dy 要到 solve 的第二行才会定义。
On the other hand, the intent of our definition does make sense, because we
can, in principle, begin to generate the y stream without knowing
dy. Indeed, integral and many other stream operations have
properties similar to those of cons-stream, in that we can generate part
of the answer given only partial information about the arguments. For
integral, the first element of the output stream is the specified
initial-value. Thus, we can generate the first element of the output
stream without evaluating the integrand dy. Once we know the first
element of y, the stream-map in the second line of solve
can begin working to generate the first element of dy, which will
produce the next element of y, and so on.
另一方面,我们定义的意图本身是合理的,因为原则上我们可以在尚不知道 dy 的情况下开始生成流 y。实际上,integral 和许多其他流操作都具有与 cons-stream 相似的性质:即便只知道参数的部分信息,也能生成一部分答案。对于 integral,输出流的第一个元素就是指定的初始值;因此,无需对被积量 dy 求值,就可以生成输出流的第一个元素。一旦知道了 y 的第一个元素,solve 第二行中的 stream-map 就可以开始工作,生成 dy 的第一个元素,进而产生 y 的下一个元素,如此循环往复。
To take advantage of this idea, we will redefine integral to expect the
integrand stream to be a
delayed argument. Integral will
force the integrand to be evaluated only when it is required to generate
more than the first element of the output stream:
为了利用这一思路,我们将重新定义 integral,使其期望被积量流作为一个延迟参数 (delayed argument)。integral 只有在需要生成输出流第一个元素之后的内容时,才会强迫对被积量求值:
Now we can implement our solve procedure by delaying the evaluation of
dy in the definition of y:
现在,我们可以通过在 y 的定义中延迟对 dy 的求值,来实现我们的 solve 过程:
In general, every caller of integral must now delay the integrand
argument. We can demonstrate that the solve procedure works by
approximating e
≈
2.718 by computing the value at y
=
1 of the
solution to the differential equation d
y
一般来说,integral 的每个调用方现在都必须对被积量参数进行延迟。我们可以通过近似计算 e
≈
2.718 来验证 solve 过程正确可用——具体方法是计算微分方程 d
y 在 y
=
1 处的解值
/
d
t
=
y with initial
condition y
(
0
)
=
1:
d
t
=
y,初始条件为 y
(
0
)
=
1:
(define int
(cons-stream
initial-value
(add-streams
(scale-stream integrand dt) int))) (define (solve f y0 dt)
(define y (integral dy y0 dt))
(define dy (stream-map f y))
y) (define (integral
delayed-integrand initial-value dt)
(define int
(cons-stream
initial-value
(let ((integrand
(force delayed-integrand)))
(add-streams
(scale-stream integrand dt)
int))))
int) (define (solve f y0 dt)
(define y (integral (delay dy) y0 dt))
(define dy (stream-map f y))
y) (stream-ref
(solve (lambda (y) y) 1 0.001) 1000)
2.716924