Skip to content

Conversation

jsmzhng
Copy link
Collaborator

@jsmzhng jsmzhng commented Jan 3, 2025

This PR introduces Chimera, a general-purpose achievement scalarizing function for multi-target optimization that allows users to establish a hierarchy of targets with relative or absolute thresholds for concurrent optimization.

This implementation includes a new objective class, ChimeraObjective, which follows a similar approach to the DesirabilityObjective. It scalarizes multiple targets into a single score, termed Chimera Merits, which is to be minimized.

For further details, please refer to the following publication:
F. Häse, L.M. Roch, and A. Aspuru-Guzik. Chimera: enabling hierarchy-based multi-objective optimization for self-driving laboratories. Chemical Science 2018, 9(39), 7642-7655.


WIP:

  • Further testing and validation of the ChimeraObjective implementation.
  • Consideration of whether the optimization should be adjusted to a maximization approach, similar to the DesirabilityObjective.
  • Additional documentation and examples to illustrate the usage of ChimeraObjective.

@CLAassistant
Copy link

CLAassistant commented Jan 3, 2025

CLA assistant check
All committers have signed the CLA.

@Scienfitz Scienfitz changed the title Chimera Extension Chimera Objective Jan 3, 2025
@Scienfitz
Copy link
Collaborator

@AVHopp @AdrianSosic PR in draft mode, NOT for review


# Force that every drawn target has a linear transformation and mode MIN or MAX.
assume(all(t.mode is not TargetMode.MATCH for t in targets))
n_targets = len(targets)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not really sued often hence this shortcut is not needed

Comment on lines +255 to +260
# Normalize external merits to match internal implementation
ext_range = np.amax(ext_merits) - np.amin(ext_merits)
if ext_range > 0:
ext_merits = (ext_merits - np.amin(ext_merits)) / ext_range
else:
ext_merits = np.zeros_like(ext_merits) # Handle uniform values
Copy link
Collaborator Author

@jsmzhng jsmzhng Jun 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Scienfitz The reference code performs final normalization in scalarize via:

if np.amax(merits) > 0.:
    merits = (merits - np.amin(merits)) / (np.amax(merits) - np.amin(merits))

See reference: reference line 259 onwards

This approach has two issues:

  • It is not numerically stable: Division by (max - min) can cause division-by-zero when values are nearly identical
  • When max(merits) ≤ 0, no normalization occurs, leaving merits in arbitrary negative ranges, causing confusions as they are acquisition weights for BoTorch (in minimization mode), our implementation always normalizes to [0,1] when range > 0 and handling edge case of a uniform merits

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Scienfitz this however does not mitigate the warning message when running the test:

tests/test_objective.py::test_chimera_merits
  /Users/x272626/Desktop/chimera/src/chimera/chimera.py:263: RuntimeWarning: invalid value encountered in divide
    merits = (merits - np.amin(merits)) / (np.amax(merits) - np.amin(merits))

which means we have uniform merits (all values identical) -> this is however not sth that we can explicitly predict based on the input values, nor build the exclusion logics explicitly in the test as many different combinations and variations in target_vals and threshold_vals and threshold_type can lead to this issue.

How can we overcome this?


target_vals = data.draw(
data_frames(columns=columns, index=range_indexes(min_size=2)).filter(
lambda df: len(df.drop_duplicates()) > 1
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? Because it could have multiple measurements that are the same

@Scienfitz Scienfitz added the new feature New functionality label Aug 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new feature New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants