"""File: 01simpleIntegral.py
 Author: Michel Bierlaire, EPFL
 Date: Wed Dec 11 16:20:24 2019

Calculation of a simple integral using Monte-Carlo integration.

"""

import pandas as pd
import biogeme.database as db
import biogeme.biogeme as bio
import biogeme.draws as draws
from biogeme.expressions import exp, bioDraws, MonteCarlo

# We create a fake database with one entry, as it is required
# to store the draws
pandas = pd.DataFrame()
pandas['FakeColumn'] = [1.0]
database = db.Database('fakeDatabase',pandas)

integrand = exp(bioDraws('U','UNIFORM'))
simulatedI = MonteCarlo(integrand)

trueI = exp(1.0) - 1.0 

R = 2000

sampleVariance = \
  MonteCarlo(integrand*integrand) - simulatedI * simulatedI
stderr = (sampleVariance / R)**0.5
error = simulatedI - trueI

simulate = {'Analytical Integral': trueI,
            'Simulated Integral': simulatedI,
            'Sample variance   ': sampleVariance,
            'Std Error         ': stderr,
            'Error             ': error}

biogeme = bio.BIOGEME(database,simulate,numberOfDraws=R)
biogeme.modelName = f'01simpleIntegral_{R}'
results = biogeme.simulate()
print(f'Number of draws: {R}')
for c in results.columns:
    print(f'{c}: {results.loc[0,c]}')

# With 10 times more draws
biogeme2 = bio.BIOGEME(database,simulate,numberOfDraws=10*R)
biogeme2.modelName = '01simpleIntegral_{10*R}'
results2 = biogeme2.simulate()
print(f'Number of draws: {10*R}')
for c in results.columns:
    print(f'{c}: {results2.loc[0,c]}')



