-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7b4d1b5
commit 0e3aa97
Showing
12 changed files
with
325 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
This is my gallery | ||
================== | ||
Examples | ||
======== | ||
|
||
Below is a gallery of examples | ||
Below is a gallery of examples that use various part of the :mod:`f3dasm` package |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Data generation | ||
--------------- | ||
|
||
Examples that use the :mod:`f3dasm.datageneration` module to generate output for the data generation process. |
62 changes: 62 additions & 0 deletions
62
examples/datageneration/plot_builtin_benchmarkfunctions.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
""" | ||
Use the built-in benchmark functions | ||
==================================== | ||
In this example, we will use the built-in benchmark functions provided by :mod:`f3dasm.datageneration.functions` to generate output for a data-driven experiment. | ||
""" | ||
|
||
import matplotlib.pyplot as plt | ||
|
||
from f3dasm import ExperimentData | ||
from f3dasm.design import make_nd_continuous_domain | ||
|
||
############################################################################### | ||
# :mod:`f3dasm` ships with a set of benchmark functions that can be used to test the performance of | ||
# optimization algorithms or to mock some expensive simulation in order to test the data-driven process. | ||
# These benchmark functions are taken and modified from the `Python Benchmark Test Optimization Function Single Objective <https://github.com/AxelThevenot/Python_Benchmark_Test_Optimization_Function_Single_Objective>`_ github repository. | ||
# | ||
# Let's start by creating a continuous domain | ||
# with 2 input variables, each ranging from -1.0 to 1.0 | ||
|
||
domain = make_nd_continuous_domain([[-1., 1.], [-1., 1.]]) | ||
|
||
############################################################################### | ||
# We generate the input data by sampling the domain equally spaced with the grid sampler and create the :class:`~f3dasm.ExperimentData` object: | ||
|
||
experiment_data = ExperimentData.from_sampling( | ||
'grid', domain=domain, stepsize_continuous_parameters=0.1) | ||
|
||
print(experiment_data) | ||
|
||
############################################################################### | ||
# Evaluating a 2D version of the Ackley function is as simple as | ||
# calling the :meth:`~f3dasm.ExperimentData.evaluate` method with the function name as the ``data_generator`` argument. | ||
# | ||
# In addition, you can provide a dictionary (``kwargs``) with the followinging keywords to the :class:`~f3dasm.design.ExperimentData.evaluate` method: | ||
# | ||
# * ``scale_bounds``: A 2D list of floats that define the scaling lower and upper boundaries for each dimension. The normal benchmark function box-constraints will be scaled to these boundaries. | ||
# * ``noise``: A float that defines the standard deviation of the Gaussian noise that is added to the objective value. | ||
# * ``offset``: A boolean value. If ``True``, the benchmark function will be offset by a constant vector that will be randomly generated [1]_. | ||
# * ``seed``: Seed for the random number generator for the ``noise`` and ``offset`` calculations. | ||
# | ||
# .. [1] As benchmark functions usually have their minimum at the origin, the offset is used to test the robustness of the optimization algorithm. | ||
|
||
experiment_data.evaluate(data_generator='Ackley', kwargs={ | ||
'scale_bounds': domain.get_bounds(), 'offset': False}) | ||
|
||
############################################################################### | ||
# The function values are stored in the ``y`` variable of the output data: | ||
|
||
print(experiment_data) | ||
|
||
############################################################################### | ||
|
||
arr_in, arr_out = experiment_data.to_numpy() | ||
fig, ax = plt.subplots(subplot_kw={'projection': '3d'}) | ||
ax.scatter(arr_in[:, 0], arr_in[:, 1], arr_out.ravel()) | ||
_ = ax.set_xlabel('$x_0$') | ||
_ = ax.set_ylabel('$x_1$') | ||
_ = ax.set_zlabel('$f(x)$') | ||
|
||
############################################################################### | ||
# A complete list of all the implemented benchmark functions can be found :ref:`here <implemented-benchmark-functions>` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
""" | ||
Implement your own datagenerator: car stopping distance problem | ||
=============================================================== | ||
In this example, we will implement a custom data generator that generates output for a data-driven experiment. | ||
We will use the 'car stopping distance' problem as an example. | ||
""" | ||
|
||
import matplotlib.pyplot as plt | ||
import numpy as np | ||
from scipy.stats import norm | ||
|
||
from f3dasm import ExperimentData | ||
from f3dasm.datageneration import DataGenerator | ||
from f3dasm.design import Domain | ||
|
||
############################################################################### | ||
# | ||
# Car stopping distance :math:`y` as a function of its velocity :math:`x` before it starts braking: | ||
# | ||
# .. math:: | ||
# | ||
# y = z x + \frac{1}{2 \mu g} x^2 = z x + 0.1 x^2 | ||
# | ||
# | ||
# - :math:`z` is the driver's reaction time (in seconds) | ||
# - :math:`\mu` is the road/tires coefficient of friction (we assume :math:`\mu=0.5`) | ||
# - :math:`g` is the acceleration of gravity (assume :math:`g=10 m/s^2`). | ||
# | ||
# .. math:: | ||
# | ||
# y = d_r + d_{b} | ||
# | ||
# where :math:`d_r` is the reaction distance, and :math:`d_b` is the braking distance. | ||
# | ||
# Reaction distance :math:`d_r` | ||
# | ||
# .. math:: | ||
# | ||
# d_r = z x | ||
# | ||
# with :math:`z` being the driver's reaction time, and :math:`x` being the velocity of the car at the start of braking. | ||
# | ||
# Kinetic energy of moving car: | ||
# | ||
# .. math:: | ||
# | ||
# E = \frac{1}{2}m x^2 | ||
# | ||
# where :math:`m` is the car mass. | ||
# | ||
# Work done by braking: | ||
# | ||
# .. math:: | ||
# | ||
# W = \mu m g d_b | ||
# | ||
# | ||
# where :math:`\mu` is the coefficient of friction between the road and the tire, :math:`g` is the acceleration of gravity, and :math:`d_b` is the car braking distance. | ||
# | ||
# The braking distance follows from :math:`E=W`: | ||
# | ||
# .. math:: | ||
# | ||
# d_b = \frac{1}{2\mu g}x^2 | ||
# | ||
# Therefore, if we add the reacting distance :math:`d_r` to the braking distance :math:`d_b` we get the stopping distance :math:`y`: | ||
# | ||
# .. math:: | ||
# | ||
# y = d_r + d_b = z x + \frac{1}{2\mu g} x^2 | ||
# | ||
# | ||
# Every driver has its own reaction time :math:`z` | ||
# Assume the distribution associated to :math:`z` is Gaussian with mean :math:`\mu_z=1.5` seconds and variance :math:`\sigma_z^2=0.5^2`` seconds\ :sup:`2`: | ||
# | ||
# .. math:: | ||
# | ||
# z \sim \mathcal{N}(\mu_z=1.5,\sigma_z^2=0.5^2) | ||
# | ||
# | ||
# We create a function that generates the stopping distance :math:`y` given the velocity :math:`x` and the reaction time :math:`z`: | ||
|
||
|
||
def y(x): | ||
z = norm.rvs(1.5, 0.5, size=1) | ||
y = z*x + 0.1*x**2 | ||
return y | ||
|
||
|
||
############################################################################### | ||
# Implementing this relationship in :mod:`f3dasm` can be done in two ways: | ||
# | ||
# | ||
# 1. Directly using a function | ||
# 2. Providing an object from a custom class that inherits from the :class:`~f3dasm.datageneration.DataGenerator` class. | ||
# | ||
# Using a function directly | ||
# ------------------------- | ||
# | ||
# We can use the function :func:`y(x)` directly as the data generator. We will demonstrate this in the following example code: | ||
# | ||
# | ||
# In order to create an :class:`~f3dasm.ExperimentData` object, we have to first create a domain | ||
domain = Domain() | ||
domain.add_float('x', low=0., high=100.) | ||
|
||
############################################################################### | ||
# For demonstration purposes, we will generate a dataset of stopping distances for velocities between 3 and 83 m/s. | ||
|
||
N = 33 # number of points to generate | ||
Data_x = np.linspace(3, 83, 100) | ||
|
||
############################################################################### | ||
# We can construct an :class:`~f3dasm.ExperimentData` object with the :class:`~f3dasm.design.Domain` and the numpy array: | ||
|
||
experiment_data = ExperimentData(input_data=Data_x, domain=domain) | ||
print(experiment_data) | ||
|
||
############################################################################### | ||
# As you can see, the ExperimentData object has been created successfully and the jobs have the label 'open'. | ||
# This means that the output has not been generated yet. We can now compute the stopping distance by calling the :meth:`~f3dasm.ExperimentData.evaluate` method: | ||
# We have to provide the function as the ``data_generator`` argument and provide name of the return value as the ``output_names`` argument: | ||
|
||
experiment_data.evaluate(data_generator=y, output_names=['y']) | ||
|
||
arr_in, arr_out = experiment_data.to_numpy() | ||
|
||
fig, ax = plt.subplots() | ||
ax.scatter(arr_in, arr_out.flatten(), s=2) | ||
_ = ax.set_xlabel('Car velocity ($m/s$)') | ||
_ = ax.set_ylabel('Stopping distance ($m$)') | ||
|
||
############################################################################### | ||
# The experiments have been evaluated and the jobs value has been set to 'finished' | ||
|
||
print(experiment_data) | ||
|
||
############################################################################### | ||
# | ||
# Using the DataGenerator class | ||
# ----------------------------- | ||
# | ||
# We can also implement the data generator as a class that inherits from the :class:`~f3dasm.datageneration.DataGenerator` class. | ||
# This allows for more flexibility and control over the data generation process. | ||
|
||
experiment_data_class = ExperimentData(input_data=Data_x, domain=domain) | ||
|
||
############################################################################### | ||
# The custom data generator class should have an :meth:`~f3dasm.datageneration.DataGenerator.execute` method. | ||
# In this method, we can access the experiment using the :attr:`~f3dasm.datageneration.DataGenerator.experiment_sample` attribute. | ||
# We can store the output of the data generation process using the :meth:`~f3dasm.datageneration.DataGenerator.experiment_sample.store` method. | ||
|
||
|
||
class CarStoppingDistance(DataGenerator): | ||
def __init__(self, mu_z: float, sigma_z: float): | ||
self.mu_z = mu_z | ||
self.sigma_z = sigma_z | ||
|
||
def execute(self): | ||
x = self.experiment_sample.get('x') | ||
z = norm.rvs(self.mu_z, self.sigma_z, size=1) | ||
y = z*x + 0.1*x**2 | ||
self.experiment_sample.store(object=y, name='y', to_disk=False) | ||
|
||
############################################################################### | ||
# We create an object of the :class:`~CarStoppingDistance` class and pass it to the :meth:`~f3dasm.ExperimentData.evaluate` method: | ||
|
||
|
||
car_stopping_distance = CarStoppingDistance(mu_z=1.5, sigma_z=0.5) | ||
experiment_data_class.evaluate(data_generator=car_stopping_distance) | ||
|
||
print(experiment_data_class) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
Domain | ||
------ | ||
Design of Experiments | ||
--------------------- | ||
|
||
Below is a gallery of examples | ||
Examples that use the :mod:`f3dasm.design` module to create a design of experiments |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
ExperimentData | ||
-------------- | ||
|
||
Below is a gallery of examples | ||
Examples that use the :class:`~f3dasm.ExperimentData` object to control | ||
the data-driven process. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
Integration with hydra | ||
---------------------- | ||
|
||
Below is a gallery of examples | ||
Examples that integrate the :mod:`f3dasm` package with the configuration manager `hydra <https://hydra.cc/>`_ |
Oops, something went wrong.