.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/programmers/plot_tools.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_programmers_plot_tools.py: biogeme.tools ============= Examples of use of several functions. This is designed for programmers who need examples of use of the functions of the module. The examples are designed to illustrate the syntax. They do not correspond to any meaningful model. :author: Michel Bierlaire :date: Sat Dec 2 13:09:42 2023 .. GENERATED FROM PYTHON SOURCE LINES 15-34 .. code-block:: Python import biogeme.biogeme_logging as blog import numpy as np import pandas as pd from IPython.core.display_functions import display from biogeme.exceptions import BiogemeError from biogeme.function_output import FunctionOutput from biogeme.tools import ( CheckDerivativesResults, calculate_prime_numbers, check_derivatives, count_number_of_groups, findiff_g, findiff_h, get_prime_numbers, likelihood_ratio, ) from biogeme.version import get_text .. GENERATED FROM PYTHON SOURCE LINES 35-36 Version of Biogeme. .. GENERATED FROM PYTHON SOURCE LINES 36-38 .. code-block:: Python print(get_text()) .. rst-class:: sphx-glr-script-out .. code-block:: none biogeme 3.3.1 [2025-09-03] Home page: http://biogeme.epfl.ch Submit questions to https://groups.google.com/d/forum/biogeme Michel Bierlaire, Transport and Mobility Laboratory, Ecole Polytechnique Fédérale de Lausanne (EPFL) .. GENERATED FROM PYTHON SOURCE LINES 39-42 .. code-block:: Python logger = blog.get_screen_logger(level=blog.INFO) .. GENERATED FROM PYTHON SOURCE LINES 43-52 Define a function and its derivatives: .. math:: f = \log(x_0) + \exp(x_1), .. math:: g = \left( \begin{array}{c}\frac{1}{x_0} \\ \exp(x_1)\end{array}\right), .. math:: h=\left(\begin{array}{cc} -\frac{1}{x_0^2} & 0 \\ 0 & \exp(x_1)\end{array}\right). .. GENERATED FROM PYTHON SOURCE LINES 52-76 .. code-block:: Python def my_function( x: np.ndarray, gradient: bool, hessian: bool, bhhh: bool ) -> FunctionOutput: """Implementation of the test function. :param x: point at which the function and its derivatives must be evaluated. """ f = np.log(x[0]) + np.exp(x[1]) g = np.empty(2) g[0] = 1.0 / x[0] g[1] = np.exp(x[1]) h = np.empty((2, 2)) h[0, 0] = -1.0 / x[0] ** 2 h[0, 1] = 0.0 h[1, 0] = 0.0 h[1, 1] = np.exp(x[1]) return FunctionOutput( function=float(f), gradient=g if gradient else None, hessian=h if hessian else None, bhhh=None, ) .. GENERATED FROM PYTHON SOURCE LINES 77-81 Evaluate the function at the point .. math:: x = \left( \begin{array}{c}1.1 \\ 1.1 \end{array}\right). .. GENERATED FROM PYTHON SOURCE LINES 81-84 .. code-block:: Python x = np.array([1.1, 1.1]) the_output = my_function(x, gradient=True, hessian=True, bhhh=False) .. GENERATED FROM PYTHON SOURCE LINES 85-87 .. code-block:: Python display(the_output.function) .. rst-class:: sphx-glr-script-out .. code-block:: none 3.099476203750758 .. GENERATED FROM PYTHON SOURCE LINES 88-89 We use the `DataFrame` for a nicer display. .. GENERATED FROM PYTHON SOURCE LINES 89-91 .. code-block:: Python pd.DataFrame(the_output.gradient) .. raw:: html
0
0 0.909091
1 3.004166


.. GENERATED FROM PYTHON SOURCE LINES 92-94 .. code-block:: Python pd.DataFrame(the_output.hessian) .. raw:: html
0 1
0 -0.826446 0.000000
1 0.000000 3.004166


.. GENERATED FROM PYTHON SOURCE LINES 95-96 Calculates an approximation of the gradient by finite differences. .. GENERATED FROM PYTHON SOURCE LINES 96-98 .. code-block:: Python g_fd = findiff_g(my_function, x) .. GENERATED FROM PYTHON SOURCE LINES 99-101 .. code-block:: Python pd.DataFrame(g_fd) .. raw:: html
0
0 0.909091
1 3.004166


.. GENERATED FROM PYTHON SOURCE LINES 102-103 Check the precision of the approximation .. GENERATED FROM PYTHON SOURCE LINES 103-105 .. code-block:: Python pd.DataFrame(the_output.gradient - g_fd) .. raw:: html
0
0 0.000000e+00
1 6.486904e-10


.. GENERATED FROM PYTHON SOURCE LINES 106-107 Calculates an approximation of the Hessian by finite differences. .. GENERATED FROM PYTHON SOURCE LINES 107-109 .. code-block:: Python h_fd = findiff_h(my_function, x) .. GENERATED FROM PYTHON SOURCE LINES 110-112 .. code-block:: Python pd.DataFrame(h_fd) .. raw:: html
0 1
0 -0.826446 0.000000
1 0.000000 3.004166


.. GENERATED FROM PYTHON SOURCE LINES 113-114 Check the precision of the approximation .. GENERATED FROM PYTHON SOURCE LINES 114-116 .. code-block:: Python pd.DataFrame(the_output.hessian - h_fd) .. raw:: html
0 1
0 -1.600951e-08 0.000000e+00
1 0.000000e+00 6.486904e-10


.. GENERATED FROM PYTHON SOURCE LINES 117-119 There is a function that checks the analytical derivatives by comparing them to their finite difference approximation. .. GENERATED FROM PYTHON SOURCE LINES 119-123 .. code-block:: Python results: CheckDerivativesResults = check_derivatives( my_function, x, names=None, logg=True ) .. rst-class:: sphx-glr-script-out .. code-block:: none Comparing first derivatives x Gradient FinDiff Difference x[0] 0.909091 0.909091 0 x[1] 3.00417 3.00417 6.4869e-10 Comparing second derivatives Row Col Hessian FinDiff Difference x[0] x[0] -0.826446 -0.826446 -1.60095e-08 x[1] x[0] 0 0 0 x[0] x[1] 0 0 0 x[1] x[1] 3.00417 3.00417 6.4869e-10 .. GENERATED FROM PYTHON SOURCE LINES 124-125 Difference between analytical and finite difference gradient .. GENERATED FROM PYTHON SOURCE LINES 125-127 .. code-block:: Python display(results.errors_gradient) .. rst-class:: sphx-glr-script-out .. code-block:: none [0.00000000e+00 6.48690435e-10] .. GENERATED FROM PYTHON SOURCE LINES 128-129 Difference between analytical and finite difference hessian .. GENERATED FROM PYTHON SOURCE LINES 129-131 .. code-block:: Python display(results.errors_hessian) .. rst-class:: sphx-glr-script-out .. code-block:: none [[-1.60095120e-08 0.00000000e+00] [ 0.00000000e+00 6.48690435e-10]] .. GENERATED FROM PYTHON SOURCE LINES 132-133 To help reading the reporting, it is possible to give names to variables. .. GENERATED FROM PYTHON SOURCE LINES 135-139 .. code-block:: Python named_results: CheckDerivativesResults = check_derivatives( my_function, x, names=['First', 'Second'], logg=True ) .. rst-class:: sphx-glr-script-out .. code-block:: none Comparing first derivatives x Gradient FinDiff Difference First 0.909091 0.909091 0 Second 3.00417 3.00417 6.4869e-10 Comparing second derivatives Row Col Hessian FinDiff Difference First First -0.826446 -0.826446 -1.60095e-08 Second First 0 0 0 First Second 0 0 0 Second Second 3.00417 3.00417 6.4869e-10 .. GENERATED FROM PYTHON SOURCE LINES 140-142 .. code-block:: Python pd.DataFrame(named_results.errors_gradient) .. raw:: html
0
0 0.000000e+00
1 6.486904e-10


.. GENERATED FROM PYTHON SOURCE LINES 143-145 .. code-block:: Python display(named_results.errors_hessian) .. rst-class:: sphx-glr-script-out .. code-block:: none [[-1.60095120e-08 0.00000000e+00] [ 0.00000000e+00 6.48690435e-10]] .. GENERATED FROM PYTHON SOURCE LINES 146-147 Prime numbers: calculate prime numbers lesser or equal to an upper bound. .. GENERATED FROM PYTHON SOURCE LINES 147-150 .. code-block:: Python my_primes = calculate_prime_numbers(10) display(my_primes) .. rst-class:: sphx-glr-script-out .. code-block:: none [2, 3, 5, 7] .. GENERATED FROM PYTHON SOURCE LINES 151-154 .. code-block:: Python my_primes = calculate_prime_numbers(100) display(my_primes) .. rst-class:: sphx-glr-script-out .. code-block:: none [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] .. GENERATED FROM PYTHON SOURCE LINES 155-156 Calculate a given number of prime numbers. .. GENERATED FROM PYTHON SOURCE LINES 156-159 .. code-block:: Python my_primes = get_prime_numbers(7) display(my_primes) .. rst-class:: sphx-glr-script-out .. code-block:: none [2, 3, 5, 7, 11, 13, 17] .. GENERATED FROM PYTHON SOURCE LINES 160-161 Counting groups of data. .. GENERATED FROM PYTHON SOURCE LINES 161-163 .. code-block:: Python alist = [1, 2, 2, 3, 3, 3, 4, 1, 1] .. GENERATED FROM PYTHON SOURCE LINES 164-171 .. code-block:: Python df = pd.DataFrame( { 'ID': [1, 1, 2, 3, 3, 1, 2, 3], 'value': [1000, 2000, 3000, 4000, 5000, 5000, 10000, 20000], } ) .. GENERATED FROM PYTHON SOURCE LINES 172-174 .. code-block:: Python count_number_of_groups(df, 'ID') .. rst-class:: sphx-glr-script-out .. code-block:: none 6 .. GENERATED FROM PYTHON SOURCE LINES 175-177 .. code-block:: Python count_number_of_groups(df, 'value') .. rst-class:: sphx-glr-script-out .. code-block:: none 7 .. GENERATED FROM PYTHON SOURCE LINES 178-179 Likelihood ratio test. .. GENERATED FROM PYTHON SOURCE LINES 179-182 .. code-block:: Python model1 = (-1340.8, 5) model2 = (-1338.49, 7) .. GENERATED FROM PYTHON SOURCE LINES 183-185 A likelihood ratio test is performed. The function returns the outcome of the test, the statistic, and the threshold. .. GENERATED FROM PYTHON SOURCE LINES 185-187 .. code-block:: Python likelihood_ratio.likelihood_ratio_test(model1, model2) .. rst-class:: sphx-glr-script-out .. code-block:: none LRTuple(message='H0 cannot be rejected at level 5.0%', statistic=4.619999999999891, threshold=np.float64(5.99146454710798)) .. GENERATED FROM PYTHON SOURCE LINES 188-189 The default level of significance is 0.95. It can be changed. .. GENERATED FROM PYTHON SOURCE LINES 189-191 .. code-block:: Python likelihood_ratio.likelihood_ratio_test(model1, model2, significance_level=0.9) .. rst-class:: sphx-glr-script-out .. code-block:: none LRTuple(message='H0 can be rejected at level 90.0%', statistic=4.619999999999891, threshold=np.float64(0.21072103131565265)) .. GENERATED FROM PYTHON SOURCE LINES 192-193 The order in which the models are presented is irrelevant. .. GENERATED FROM PYTHON SOURCE LINES 193-195 .. code-block:: Python likelihood_ratio.likelihood_ratio_test(model2, model1) .. rst-class:: sphx-glr-script-out .. code-block:: none LRTuple(message='H0 cannot be rejected at level 5.0%', statistic=4.619999999999891, threshold=np.float64(5.99146454710798)) .. GENERATED FROM PYTHON SOURCE LINES 196-198 But the unrestricted model must have a higher loglikelihood than the restricted one. .. GENERATED FROM PYTHON SOURCE LINES 198-201 .. code-block:: Python model1 = (-1340.8, 7) model2 = (-1338.49, 5) .. GENERATED FROM PYTHON SOURCE LINES 202-206 .. code-block:: Python try: likelihood_ratio.likelihood_ratio_test(model1, model2) except BiogemeError as e: print(e) .. rst-class:: sphx-glr-script-out .. code-block:: none The unrestricted model (-1340.8, 7) has a lower log likelihood than the restricted one (-1338.49, 5) .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.032 seconds) .. _sphx_glr_download_auto_examples_programmers_plot_tools.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_tools.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_tools.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_tools.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_