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> 

 

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

5 × = thirty five