TL;DR
За комментарии, краткий ответ; неявный эквивалент оригинала, явные newton_i
и newton
соответственно:
n_i =: d.0 1 (%/@:) (]`-`) (`:6)
newton =: n_i (^:_)
Некоторые методы получения таких переводов в целом можно найти на форумы J.
Строительство
Ключевым моментом здесь является то, что (а) функция идентична своей собственной «нулевой производной» и что (б) мы можем вычислить «нулевую» и первую производную функции в J одновременно, благодаря массиву языка. ориентированный характер. Остальное — просто коллекционирование марок.
В идеальном мире, учитывая функцию f
, мы хотели бы создать последовательность глаголов, подобную (] - 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
(%/@)
идет справа от 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)
И, наконец, с помощью "apply с фиксированной точкой" ^:_
, мы имеем:
newton =: n_i (^:_)
Вуаля.
person
Dan Bron
schedule
03.11.2014
d.
мешает вам написать неявное наречие в этом случае. - person Eelvex   schedule 01.11.2014n_i =: d.0 1 (%/@:) (-`) (]`) (`:6)
иnewton =: n_i (^:_)
. Я вернусь и объясню, почему позже (я м по телефону прямо сейчас). - person Dan Bron   schedule 03.11.2014(-`) (]`) (`:6)
не(]`) (-`) (`:6)
для создания] - f
форка. - person Dan Oak   schedule 03.11.2014f (d.0 1) (%/@:)
как о черном ящике, который создает (эффективно)(f % f d.1)
; хорошо, тогда у вас естьblack_box (`-) (`])
, который при обратном чтении (LIFO) читается как]
,-
,black_box
, который затем выполняется в поезде] - black_box
. Нет, настоящий хитрый трюк здесь заключался в использованииd.0 1
:). Это проясняет ситуацию или вы все же хотите, чтобы я опубликовал официальный ответ? - person Dan Bron   schedule 03.11.2014f (d.0 1) (%/@:)
трюк :) - это действительно круто: мы вычисляем нулевую и первую производные отf
, а затем вставляем между ними%
. Я также понял порядок, в котором вы написали эти три наречия. Большое тебе спасибо! - person Dan Oak   schedule 03.11.2014newton_i =: d.0 1 (%/@:) (-`) (]`) (`:6)
, я приму его. Затем я добавлю все объяснение, как я понял. - person Dan Oak   schedule 03.11.2014