Reputation: 623
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
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
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