user1202733
user1202733

Reputation: 623

maclaurin series in J

I'm trying to implement the series expansion for sine(x) in J (I'm not worried about accuracy, but more the problem of expressing the series nicely).

So far I have the following explicit version which computes sine(pi) using 50 terms:

3.14 (4 :'+/((_1^y) * (x^(1+2*y)) % !1+2*y)') i.50

But it seems somewhat clunky, is there a "better" version (maybe tacit?) ?

Upvotes: 1

Views: 107

Answers (2)

Eelvex
Eelvex

Reputation: 9153

You want a list of odd numbers for powers and factorials: l =: >:+:i. y (>:@+:@i.) or >:@+: if your y is i..

Then, you want the powers (x^l) divided by the factorials (!l). One way is to see this as a fork (x f y) h (x g y) -> (x ^ l) % (x (]!) l)(^ % (]!)).

The last step is to multiply this series by the series 1, _1, 1, ...: _1 ^ y_1&^

So, the final form is (_1 ^ y) * (x (^ * (]!)) (>:@+:@i.) y) which is the train (h y) j (x f (g y))(h y) j (x (f g) y)(x (]h) y) j (x (f g) y)(]h) j (f g):

ms =: (] _1&^)  *   ((^ % (]!)) (>:@+:))
+/ 3.14 ms i.50 
0.00159265

or

f =: +/@(ms i.)
3.14 f 50
0.00159265

On the other hand, you can use T. for the taylor approximation.

Upvotes: 3

bob
bob

Reputation: 4302

   3.14 (4 :'+/((_1^y) * (x^(1+2*y)) % !1+2*y)') i.50
0.00159265

Tacit version could look like this:

   3.14 +/@:((_1 ^ ]) * ([ ^ 1 + +:@]) % !@(1 + +:@])) i.50
0.00159265

or this:

   3.14 +/@:((_1 ^ ]) * ([ ^ >:@+:@]) % !@>:@+:@]) i.50
0.00159265

or even this:

   3.14 +/@:((_1 ^ ]) * (( ^  % !@])(>:@+:@]))) i.50
0.00159265

The first and second are pretty much tacit translations, the last uses hooks and forks, which can be a bit much unless you are used to them.

Upvotes: 0

Related Questions