Your First Optimization with globalMOO
This guide will take you from zero to your first working optimization in about 15 minutes. We'll create a simple but complete example that demonstrates the key features of globalMOO.
Try it interactively: Follow along with this guide in our Interactive Google Colab Notebook
What You'll Build
We'll optimize a simple function with two inputs to achieve desired outputs. This example will teach you:
How to set up authentication
How to create a model and project
How to run an optimization
How to interpret and use the results
Prerequisites
Python 3.10 or higher
A globalMOO API key (get one at https://api.globalmoo.ai/)
Basic Python knowledge
Step 1: Installation and Setup
Install the SDK (use the appropriate package manager for your language):
pip install globalmoo-sdk
Create a new file and add the necessary imports and setup:
import logging
from typing import List
from dotenv import load_dotenv
from globalmoo.client import Client
from globalmoo.request.create_model import CreateModel
from globalmoo.request.create_project import CreateProject
from globalmoo.request.load_output_cases import LoadOutputCases
from globalmoo.request.load_objectives import LoadObjectives
from globalmoo.request.suggest_inverse import SuggestInverse
from globalmoo.request.load_inversed_output import LoadInversedOutput
from globalmoo.enums.input_type import InputType
from globalmoo.enums.objective_type import ObjectiveType
# Configure logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('httpx').setLevel(logging.WARNING)
logger = logging.getLogger(__name__)
# Load environment variables
load_dotenv()
# Initialize client using environment variables
client = Client()
Or if you prefer to specify credentials directly:
from globalmoo.credentials import Credentials
credentials = Credentials(
api_key="your-api-key",
base_uri="https://api.globalmoo.ai/api"
)
client = Client(credentials=credentials)
Step 2: Define Your Function
Let's optimize a simple linear function with 3 inputs and 5 outputs:
def my_function(inputs: List[float]) -> List[float]:
"""Simple linear function that we want to optimize."""
v01 = inputs[0]
v02 = inputs[1]
v03 = inputs[2]
o01 = v01 + v02 + v03 # Sum of all inputs
o02 = (v01 - 2.0) + (v02 - 2.0) + v03 # Shifted sum
o03 = (v01 - 2.0) + v02 + (v03 - 2.0) # Different shifted sum
o04 = v01 + (v02 - 2.0) + (v03 - 2.0) # Another variation
o05 = 3.0 * v01 + 2.0 * v03 + 1.0 * v03 # Weighted sum
return [o01, o02, o03, o04, o05]
Step 3: Create a Model and Project
# Model configuration
MODEL_NAME = "My First Optimization"
INPUT_COUNT = 3
OUTPUT_COUNT = 5
MIN_VALUES = [0.0, 0.0, 0.0]
MAX_VALUES = [10.0, 10.0, 10.0]
INPUT_TYPES = [InputType.FLOAT] * INPUT_COUNT
# Create a model
model = client.execute_request(CreateModel(
name=MODEL_NAME
))
logger.info(f"Created model with ID: {model.id}")
# Create a project with input specifications
project = client.execute_request(CreateProject(
model_id=model.id,
input_count=INPUT_COUNT,
minimums=MIN_VALUES,
maximums=MAX_VALUES,
input_types=INPUT_TYPES,
categories=[] # Empty list since we have no categorical variables
))
logger.info(f"Created project with ID: {project.id}")
Step 4: Run Initial Learning Cases
# Get input cases from the project
input_cases = project.input_cases
logger.info(f"Received {len(input_cases)} input cases")
# Compute outputs for each input case
output_cases = [my_function(single_case) for single_case in input_cases]
logger.info(f"Computed {len(output_cases)} output cases")
# Create trial with the computed outputs
trial = client.execute_request(LoadOutputCases(
model_id=model.id,
project_id=project.id,
output_count=OUTPUT_COUNT,
output_cases=output_cases
))
logger.info(f"Successfully created trial with ID: {trial.id}")
Step 5: Set Optimization Goals
# Define our target values and how we want to achieve them
TRUTHCASE = [5.4321, 5.4321, 5.4321] # The inputs we're trying to find
objectives = my_function(TRUTHCASE) # The outputs we want to match
# Define how precise we want each objective to be
OBJECTIVE_TYPES = [ObjectiveType.PERCENT] * OUTPUT_COUNT # Use percentage-based matching
PERCENT_BELOW = [-1.0] * OUTPUT_COUNT # Allow 1% below target
PERCENT_ABOVE = [ 1.0] * OUTPUT_COUNT # Allow 1% above target
# By convention, the last entry in input_cases is the center of the search space,
# which serves as a good starting point for the optimization
initial_input = input_cases[-1]
initial_output = output_cases[-1]
# Initialize the optimization
objective = client.execute_request(LoadObjectives(
model_id=model.id,
project_id=project.id,
trial_id=trial.id,
objectives=objectives, # What outputs we want
objective_types=OBJECTIVE_TYPES, # How to match each output
initial_input=initial_input, # Where to start from
initial_output=initial_output, # Its corresponding output
minimum_bounds=PERCENT_BELOW, # How far below target is acceptable
maximum_bounds=PERCENT_ABOVE, # How far above target is acceptable
desired_l1_norm=0.0 # Required, defaults to 0.0
))
logger.info("Initialized inverse optimization")
Other available objective types include:
ObjectiveType.EXACT
: Match exactly within L1 normObjectiveType.VALUE
: Match within absolute error boundsObjectiveType.LESS_THAN
: Keep output below targetObjectiveType.LESS_THAN_EQUAL
: Keep output at or below targetObjectiveType.GREATER_THAN
: Keep output above targetObjectiveType.GREATER_THAN_EQUAL
: Keep output at or above targetObjectiveType.MINIMIZE
: Minimize output down to targetObjectiveType.MAXIMIZE
: Maximize output up to target
Step 6: Run the Optimization Loop
# Run optimization loop
max_iterations = 10
for iteration in range(max_iterations):
# Get next suggested experiment
inverse = client.execute_request(SuggestInverse(
model_id=model.id,
project_id=project.id,
trial_id=trial.id,
objective_id=objective.id
))
logger.info(f"Iteration {iteration + 1}: Received suggestion")
# Run the experiment
next_output = my_function(inverse.input)
# Load the experimental results
inverse = client.execute_request(LoadInversedOutput(
model_id=model.id,
project_id=project.id,
trial_id=trial.id,
objective_id=objective.id,
output=next_output
))
# Log detailed results
logger.info("Current solution details:")
logger.info(f" Input: {[f'{x:.4f}' for x in inverse.input]}")
logger.info(f" Output: {[f'{x:.4f}' for x in next_output]}")
logger.info(f" Target: {[f'{x:.4f}' for x in objectives]}")
if inverse.results:
for result in inverse.results:
logger.info(f"\nObjective {result.number}:")
logger.info(f" Type: {result.type}")
logger.info(f" Error: {result.error:.6f}")
logger.info(f" Satisfied: {'✓' if result.satisfied else '✗'}")
logger.info(f" Detail: {result.detail}")
# Check if we've found a satisfactory solution
if inverse.should_stop():
if inverse.satisfied_at:
logger.info("Found satisfactory solution!")
else:
logger.info(f"Search stopped: {inverse.get_stop_reason().description()}")
break
logger.info(f"Completed iteration {iteration + 1}")
# Report final results
logger.info("\nFinal Results:")
if inverse.satisfied_at:
logger.info("Solution satisfied all objectives!")
logger.info("Satisfaction details:")
for i, (satisfied, detail) in enumerate(zip(inverse.get_satisfaction_status(), inverse.get_result_details())):
logger.info(f" Objective {i}: {'✓' if satisfied else '✗'} - {detail}")
else:
logger.info("Solution did not satisfy all objectives")
logger.info("Status per objective:")
for i, (satisfied, detail) in enumerate(zip(inverse.get_satisfaction_status(), inverse.get_result_details())):
logger.info(f" Objective {i}: {'✓' if satisfied else '✗'} - {detail}")
logger.info(f"\nFinal solution:")
logger.info(f" Input values: {[f'{x:.4f}' for x in inverse.input]}")
logger.info(f" Output values: {[f'{x:.4f}' for x in next_output]}")
logger.info(f" Target values: {[f'{x:.4f}' for x in objectives]}")
logger.info(f" Error values: {[f'{e:.6f}' for e in inverse.get_objective_errors()]}")
# Don't forget to close the client
client.http_client.close()
logger.info("Closed client connection")
Complete Code
The complete code is available in the examples directory as linear_example.py
.
What's Next?
Now that you have your first optimization working, you can:
Try different objective types (EXACT, VALUE, LESS_THAN, etc.)
Learn about different input types (integers, categories) in the tutorials
Explore more complex optimization scenarios
Check out the example gallery for real-world applications
Common Issues
Authentication errors
Check your API key in .env file or credentials
Ensure you're using the correct base URI
Optimization not converging
Try increasing max_iterations
Check if your target values are achievable
Consider relaxing your objective criteria
Need help?
Contact support@globalmoo.com
Check our documentation at https://docs.globalmoo.ai
Last updated