J: Newton's tactical adverb

I found in 'addons/math/misc/brent.ijs' implementation of the Brent as method and adverbs. I would like to construct the Newton method as an adverb, but it is much more complicated than creating unspoken verbs.
Here is the explicit version of the Newton iteration:

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

With this use:

  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 

And, of course, for convenience:

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

What is the tacit equivalent?

+6
source share
2 answers

TL DR

Per comments , short answer; the exact equivalent of the original, explicit newton_i and newton , respectively:

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

Some methods for obtaining such translations can generally be found on the J Forums .

Construction

The key considerations here are that (a) the function is identical to its “zero derivative” and that (b) we can calculate the “zero” and the first derivative of the function from J at the same time, thanks to the language-oriented character. The rest is just collecting stamps.

In an ideal world defined by the function f , we would like to create a verb similar to (] - f % f d. 1) . The problem is that silent adverbial programming in J restricts us to creating a verb that mentions the input function ( f ) once and only once.

So, instead, we use a tricky trick: we simultaneously compute two derivatives of f : the “zero” derivative (which is the identity function) and the first derivative.

  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, ie 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 

Then we just insert the separation between them:

  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 

(%/@) is to the right of znfd , because silent adverbial programming in J is LIFO (i.e., from left to right, where the "normal" J is from right to left).

Stamp collection

As I said, the remaining code is a simple collection of stamps using standard tools for constructing a verb train that subtracts this ratio from the original input:

  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 

In this way:

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

And finally, using apply to the fixed point function ^:_ , we have:

  newton =: n_i (^:_) 

Voila.

+6
source
  newton_i =: 1 : '] - u % u d.1' 

is semi-tactile, because a silent verb is obtained when it is associated with a verb (the overlay disappears when attached).

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

completely explicit in that the attachment with the verb does not allow the adverb.

  + 1 : 'u/' 

+ /

  + 1 : 'u/ y' 

+ (1: 'u / y')

There is no great significance for semi-like dialects to be completely silent, since there can be no increase in productivity, and it has the same benefit as in the locale of dialects, and not in callers (in the case of completely frank dialects).

+1
source

Source: https://habr.com/ru/post/977587/


All Articles