# Example for full simulation loop using the multi target mode for custom analytic functions This example shows how to use a multi target objective for a custom analytic function. It uses a desirability value to handle several targets. This example assumes basic familiarity with BayBE, custom test functions and multiple targets. For further details, we thus refer to - [`campaign`](./../Basics/campaign.md) for a more general and basic example, - [`custom_analytical`](./custom_analytical.md) for custom test functions, and - [`desirability`](./../Multi_Target/desirability.md) for multiple targets. ## Necessary imports for this example ```python import os ``` ```python import numpy as np ``` ```python from baybe import Campaign from baybe.objectives import DesirabilityObjective from baybe.parameters import NumericalDiscreteParameter from baybe.searchspace import SearchSpace from baybe.simulation import simulate_scenarios from baybe.targets import NumericalTarget ``` ## Parameters for a full simulation loop For the full simulation, we need to define some additional parameters. These are the number of Monte Carlo runs and the number of experiments to be conducted per run. ```python SMOKE_TEST = "SMOKE_TEST" in os.environ ``` ```python N_MC_ITERATIONS = 2 if SMOKE_TEST else 5 N_DOE_ITERATIONS = 2 if SMOKE_TEST else 4 BATCH_SIZE = 1 if SMOKE_TEST else 2 DIMENSION = 4 BOUNDS = [(-2, 2), (-2, 2), (-2, 2), (-2, 2)] POINTS_PER_DIM = 3 if SMOKE_TEST else 10 ``` ## Defining the test function See [`custom_analytical`](./custom_analytical.md) for details. ```python def sum_of_squares(*x: float) -> tuple[float, float]: """Calculate the sum of squares.""" res = 0 for y in x: res += y**2 return res, 2 * res**2 - 1 ``` ## Creating the searchspace In this example, we construct a purely discrete space with 10 points per dimension. ```python parameters = [ NumericalDiscreteParameter( name=f"x_{k+1}", values=list(np.linspace(*BOUNDS[k], POINTS_PER_DIM)), tolerance=0.01, ) for k in range(DIMENSION) ] ``` ```python searchspace = SearchSpace.from_product(parameters=parameters) ``` ## Creating multiple target object The multi target mode is handled when creating the objective object. Thus we first need to define the different targets. We use two targets here. The first target is maximized and the second target is minimized during the optimization process. ```python Target_1 = NumericalTarget( name="Target_1", mode="MAX", bounds=(0, 100), transformation="LINEAR" ) Target_2 = NumericalTarget( name="Target_2", mode="MIN", bounds=(0, 100), transformation="LINEAR" ) ``` ## Creating the objective object We collect the two targets in a list and use this list to construct the objective. ```python targets = [Target_1, Target_2] ``` ```python objective = DesirabilityObjective( targets=targets, weights=[20, 30], scalarizer="MEAN", ) ``` ## Constructing a campaign and performing the simulation loop ```python campaign = Campaign(searchspace=searchspace, objective=objective) ``` We can now use the `simulate_scenarios` function to simulate a full experiment. ```python scenarios = {"BayBE": campaign} ``` ```python results = simulate_scenarios( scenarios, sum_of_squares, batch_size=BATCH_SIZE, n_doe_iterations=N_DOE_ITERATIONS, n_mc_iterations=N_MC_ITERATIONS, ) ``` ```python print(results) ``` Scenario Monte_Carlo_Run Iteration Num_Experiments Target_1_Measurements \ 0 BayBE 0 0 1 [12.0] 1 BayBE 0 1 2 [16.0] 2 BayBE 1 0 1 [8.0] 3 BayBE 1 1 2 [16.0] Target_2_Measurements Target_1_IterBest Target_1_CumBest \ 0 [287.0] 12.0 12.0 1 [511.0] 16.0 16.0 2 [127.0] 8.0 8.0 3 [511.0] 16.0 16.0 Target_2_IterBest Target_2_CumBest 0 287.0 287.0 1 511.0 287.0 2 127.0 127.0 3 511.0 127.0