e Day!
Un peu plus tôt dans le mois, j’ai découvert le e-day!
e étant le nombre d’Euler: 2.718
Cette année, le 7 février 2018 – soit 2/7/18 au format américain – la date reprenait les 4 premières décimales de e!
En clin d’œil, je me suis demandé comment réaliser une approximation probabiliste de e en SQL. Cf article similaire du pi-day!
Le thread https://stats.stackexchange.com/questions/193990/approximate-e-using-monte-carlo-simulation détaille plusieurs méthodes.
Je suis parvenu à la formulation suivante à partir de l’algorithme principal indiqué dans le thread:
SQL> set timing on
SQL> WITH
2 src
3 AS
4 ( SELECT LEVEL id, TRUNC (LEVEL / 10) grp, DBMS_RANDOM.VALUE val
5 FROM DUAL
6 CONNECT BY LEVEL < 1e5),
7 interim
8 AS
9 ( SELECT grp, COUNT (*) + 1 cnt
10 FROM (SELECT grp,
11 SUM (val) OVER (PARTITION BY grp ORDER BY id) rollsum
12 FROM src)
13 WHERE rollsum < 1
14 GROUP BY grp)
15 SELECT AVG (cnt)
16 FROM interim;
AVG(CNT)
----------
2.7149
Elapsed: 00:00:01.11
SQL>
Une formule alternative – mais dont je ne comprends pas les fondements (aïe!) – est proposé par Xi’An. J’ai traduit son code R en SQL et effectivement ça marche…
SQL> SELECT 1 / AVG (sup1) 2 FROM (SELECT CASE 3 WHEN ( v 4 - NVL ( 5 LAG (v) OVER (PARTITION BY NULL ORDER BY r), 6 0)) 7 * COUNT (*) OVER (PARTITION BY NULL) > 8 1 9 THEN 10 1 11 ELSE 12 0 13 END 14 sup1 15 FROM (SELECT ROWNUM r, v 16 FROM ( SELECT DBMS_RANDOM.VALUE v 17 FROM DUAL 18 CONNECT BY LEVEL < 1e5 19 ORDER BY 1))); 1/AVG(SUP1) ----------- 2.71411899 Elapsed: 00:00:00.75 SQL>