7

我在'addons/math/misc/brent.ijs'Brent 方法的实现中发现了一个副词。我也想建立一个牛顿法作为副词,但这比建立默示动词要困难得多。

这是牛顿迭代的显式版本:

   newton_i =: 1 : '] - u % u d.1'

有了这样的用法:

   2&o. newton_i^:_ (1) NB. (-: 1p1) must be found
1.5708
   2 o. 1.5708 NB. after substitution we get almost 0
_3.67321e_6

当然,为了方便起见:

    newton =: 1 : 'u newton_i^:_'

什么是默认等价物?

4

2 回答 2

6

TL;博士

根据评论,简短回答;默示的等价于原来的、显式的newton_inewton分别为:

n_i =: d.0 1 (%/@:) (]`-`) (`:6) 
newton =: n_i (^:_)

一般而言,有关如何获得此类翻译的一些技术可以在J 论坛上找到。

建造

这里的关键见解是(a)一个函数与其自己的“第零次导数”相同,并且(b)我们可以同时计算 J 中函数的“第零次”和一阶导数,这要归功于语言的数组 -定向性质。其余的只是集邮。

在一个理想的世界中,给定一个函数f,我们想产生一个动词 train 像(] - f % f d. 1)。问题是 J 中的默示状语编程限制我们产生一个动词,该动词只提到f一次输入函数 ( )。

所以,相反,我们使用了一个偷偷摸摸的技巧:我们同时计算两个导数f:“零”导数(这是一个恒等函数)和一阶导数。

   load 'trig'
   sin              NB. Sine function (special case of the "circle functions", o.)
1&o.

   sin d. 1 f.      NB. First derivative of sine, sin'.
2&o.

   sin d. 0 f.      NB. "Zeroeth" derivative of sine, i.e. sine.
1&o."0

   sin d. 0 1 f.    NB.  Both, resulting in two outputs.
(1&o. , 2&o.)"0

   znfd =: d. 0 1   NB. Packaged up as a re-usable name.
   sin znfd f.
(1&o. , 2&o.)"0

然后我们只需在它们之间插入一个除法:

   dh =: znfd (%/@) NB. Quotient of first-derivative over 0th-derivattive

   sin dh
%/@(sin d.0 1)

   sin dh f.
%/@((1&o. , 2&o.)"0)

   sin dh 1p1  NB. 0
_1.22465e_16

   sin 1p1     NB. sin(pi) = 0
1.22465e_16
   sin d. 1 ] 1p1  NB. sin'(pi) = -1
_1
   sin dh 1p1  NB. sin(pi)/sin'(pi) = 0/-1 = 0
_1.22465e_16

出现在 J(%/@)的右侧,znfd因为 J 中的默认副词编程是 LIFO(即从左到右,而“正常”J 是从右到左)。

集邮

正如我所说,剩下的代码只是集邮,使用标准工具构造一个动词序列,从原始输入中减去这个商:

   ssub  =: (]`-`) (`:6)     NB. x - f(x)

   +: ssub                   NB. x - double(x)
] - +:
   -: ssub                   NB. x - halve(x)
] - -:

   -: ssub 16                NB. 16 - halve(16)
8
   +: ssub 16                NB. 16 - double(16)
_16
   *: ssub 16                NB. 16 - square(16)
_240
   %: ssub 16                NB. 16 - sqrt(16)
12

因此:

    n_i =: znfd ssub         NB. x - f'(x)/f(x)

最后,使用 的“应用到定点”特性^:_我们有:

    newton =: n_i (^:_)

瞧。

于 2014-11-03T19:11:55.170 回答
1
 newton_i =: 1 : '] - u % u d.1'

是半默示的,因为默示动词与动词结合时产生(副词在结合时消失)。

 newton_i2 =: 1 : '(] - u % u d.1) y'

是完全明确的,因为与动词的结合不会解析副词。

 + 1 : 'u/'

+/

 + 1 : 'u/ y'

+ (1 : 'u/y')

使半默示副词完全默示并不重要,因为可能没有性能提升,并且它具有在副词区域而不是调用者中解决的相同好处(完全显式副词的情况)。

于 2015-09-20T08:13:40.763 回答