F=(a,b=a)=>a?(b+~a)*F(--a,b-2)+F(a,b)*++b:+!b
Try it online!
Valid for all En values (as required), but not for F(n,i) generally (outputs −F(n,i) for odd ns.) The code is modified to reduce one byte by changing the output to F′(n,i)=(−1)nF(n,i) where F is defined as below. Specifically, the recurrence formula for F′ is F′(n,i)=(i−n−1)F′(n−1,i−2)+(i+1)F′(n−1,i)
F=(a,b=a)=>a?-F(--a,b)*++b+F(a,b-=3)*(a-b):+!b
Try it online!
Surprised to find no JavaScript answer yet, so I'll have a try.
The code consists of only basic mathematics, but the mathematics behind the code requires calculus. The recursion formula is derived from the expansion of the derivatives of sech(x) of different orders.
Explanation
Here I'll use some convenient notation. Let Tn:=tanhn(t) and Sn:=sechn(t). Then we have
dnSdtn=∑i=0nF(n,i)Tn−iSi+1
Since dTdt=S2 and dSdt=−TS, we can deduce that
ddt(TaSb)=aTa−1(S2)(Sb)+bSb−1(−TS)(Ta)=aTa−1Sb+2−bTa+1Sb
Let b=i+1 and a=n−i, we can rewrite the relation above as
ddt(Tn−iSi+1)=(n−i)Tn−i−1Si+3−(i+1)Tn−i+1Si+1=(n−i)T(n+1)−(i+2)S(i+2)+1−(i+1)T(n+1)−iSi+1
That is, F(n,i) contributes to both F(n+1,i+2) and F(n+1,i). As a result, we can write F(n,i) in terms of F(n−1,i−2) and F(n−1,i):
F(n,i)=(n−i+1)F(n−1,i−2)−(i+1)F(n−1,i)
with initial condition F(0,0)=1 and F(0,i)=0 where i≠0.
The related part of the code a?-F(--a,b)*++b+F(a,b-=3)*(a-b):+!b
is exactly calculating using the above recurrence formula. Here's the breakdown:
-F(--a,b) // -F(n-1, i) [ a = n-1, b = i ]
*++b // *(i+1) [ a = n-1, b = i+1 ]
+F(a,b-=3) // +F(n-1, i-2) [ a = n-1, b = i-2 ]
*(a-b) // *((n-1)-(i-2)) [ a = n-1, b = i-2 ]
// which is equivalent to *(n-i+1)
Since T(0)=0 and S(0)=1, En equals the coefficient of Sn+1 in the expansion of dnSdtn, which is F(n,n).
For branches that F(0,0) can never be reached, the recurrences always end at 0, so F(n,i)=0 where i<0 or i is odd. The latter one, particularly, implies that En=0 for all odd ns. For even is strictly larger than n, the recurrence may eventually allow 0≤i≤n to happen at some point, but before that step it must reach a point where i=n+1, and the recurrence formula shows that the value must be 0 at that point (since the first term is multiplied by n−i+1=n−(n+1)+1=0, and the second term is farther from the "triangle" of 0≤i≤n). As a result, F(n,i)=0 where i>n. This completes the proof of the validity of the algorithm.
Extensions
The code can be modified to calculate three more related sequences:
Tangent Numbers (46 bytes)
F=(a,b=a)=>a?F(--a,b)*++b+F(a,b-=3)*(a-b):+!~b
Secant Numbers (45 bytes)
F=(a,b=a)=>a?F(--a,b)*++b+F(a,b-=3)*(a-b):+!b
Euler Zigzag Numbers (48 bytes)
F=(a,b=a)=>a?F(--a,b)*++b+F(a,b-=3)*(a-b):!b+!~b
-i/2
, which yield-i
when added. Multiply that by thei
outside of the summation, and you get1
.