J: Неявное наречие метода Ньютона.

Я нашел в 'addons/math/misc/brent.ijs' реализацию метода Брента в виде наречия. Я хотел бы построить метод Ньютона и как наречие, но это намного сложнее, чем построение неявных глаголов.

Вот явная версия итерации Ньютона:

   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^:_'

Что такое молчаливый эквивалент?


person Dan Oak    schedule 01.11.2014    source источник
comment
Я думаю, что d. мешает вам написать неявное наречие в этом случае.   -  person Eelvex    schedule 01.11.2014
comment
Короткий ответ: n_i =: d.0 1 (%/@:) (-`) (]`) (`:6) и newton =: n_i (^:_). Я вернусь и объясню, почему позже (я м по телефону прямо сейчас).   -  person Dan Bron    schedule 03.11.2014
comment
@DanBron, большое спасибо! Я все понял с помощью вашей ссылки на сообщение, кроме того, почему (-`) (]`) (`:6) не (]`) (-`) (`:6) для создания ] - f форка.   -  person Dan Oak    schedule 03.11.2014
comment
Даниил: потому что последовательности наречий строятся слева направо (т.е. ЛИФО); думайте о f (d.0 1) (%/@:) как о черном ящике, который создает (эффективно) (f % f d.1); хорошо, тогда у вас есть black_box (`-) (`]), который при обратном чтении (LIFO) читается как ],-,black_box, который затем выполняется в поезде ] - black_box. Нет, настоящий хитрый трюк здесь заключался в использовании d.0 1 :). Это проясняет ситуацию или вы все же хотите, чтобы я опубликовал официальный ответ?   -  person Dan Bron    schedule 03.11.2014
comment
Дэн, я полностью понял f (d.0 1) (%/@:) трюк :) - это действительно круто: мы вычисляем нулевую и первую производные от f, а затем вставляем между ними %. Я также понял порядок, в котором вы написали эти три наречия. Большое тебе спасибо!   -  person Dan Oak    schedule 03.11.2014
comment
@Dan: Формально я бы хотел получить ответ не в комментариях. Если вы опубликуете свой краткий ответ newton_i =: d.0 1 (%/@:) (-`) (]`) (`:6), я приму его. Затем я добавлю все объяснение, как я понял.   -  person Dan Oak    schedule 03.11.2014
comment
Круто, тогда я так и сделаю. После того, как вы внесете свои правки, я добавлю или уточню что-нибудь по мере необходимости.   -  person Dan Bron    schedule 03.11.2014


Ответы (2)


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
comment
Очень хороший метод и решение. - person Eelvex; 04.11.2014
comment
@DanBron, я добавил к твоему ответу свое объяснение, как я понял. Вы получили это? - person Dan Oak; 05.11.2014
comment
@Danylo, я этого не делал, может быть, он был отклонен другими пользователями до того, как я получил уведомление? Вы хотите добавить ответ, который я могу скопировать и вставить? - person Dan Bron; 05.11.2014
comment
@DanBron, нет, я слишком ленив. Ваше объяснение здесь великолепно. - person Dan Oak; 07.11.2014
comment
@DanBron, недавно я обнаружил, где мое отклоненное редактирование: stackoverflow.com/review/suggested-edits/6149041. Интересно, как некомпетентные в вопросе люди делают рейтинг. - person Dan Oak; 11.11.2014
comment
Также обратите внимание, что это может быть легко распространено на функции большего количества переменных с помощью: n_i =: D.0 1 (%./@:) (]`-`) (`:6) - person jpjacobs; 19.11.2014

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

является полумолчаливым в том смысле, что неявный глагол получается, когда он связан с глаголом (наречие исчезает при связывании).

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

является полностью явным в том, что связывание с глаголом не разрешает наречие.

 + 1 : 'u/'

+/

 + 1 : 'u/ y'

+ (1 : 'u/ y')

Нет большого значения в том, чтобы сделать полумолчаливые наречия полностью неявными, так как это может не дать выигрыша в производительности, и это имеет то же преимущество, что разрешается в локали наречий, а не в вызывающих (случай для полностью явных наречий).

person pascalJ    schedule 20.09.2015