choderalab / perses

Experiments with expanded ensembles to explore chemical space
http://perses.readthedocs.io
MIT License
179 stars 50 forks source link

Fix incorrect implementation of logsumexp #1238

Closed badisa closed 8 months ago

badisa commented 8 months ago

Doesn't look like MultiTargetDesign is used, so feel free to close this PR. Just happened to see the bug when reading the code.

Description

Noticed that a custom implementation of logsumexp was incorrect, as it didn't add back in a_n.max().

Motivation and context

Incorrect implementation, will produce non-normalized log probabilities for the class MultiTargetDesign

No associated case

How has this been tested?

Tested by the following python script

import numpy as np
from numpy.typing import NDArray
from scipy.special import logsumexp

def old_log_sum_exp(vals: NDArray):
    return np.log(np.sum(np.exp(vals - vals.max())))

rng = np.random.default_rng(2023)

log_prob = rng.normal(size=1000, loc=1000)

assert not np.all(np.isclose(np.sum(np.exp(log_prob)), 1.0))

# Verify that the logsumexp from scipy produces a normalized log probability
norm_log = log_prob - logsumexp(log_prob)
print("Sum of probabilities (scipy.special.logsumexp)", np.sum(np.exp(norm_log)))
# Sum of probabilities (scipy.special.logsumexp) 0.9999999999999626
assert np.all(np.isclose(np.sum(np.exp(norm_log)), 1.0))

bad_norm_log = log_prob - old_log_sum_exp(log_prob)
print("Sum of probabilities (old logsumexp)", np.sum(np.exp(bad_norm_log)))
# Sum of probabilities (old logsumexp) inf
assert np.all(np.isclose(np.sum(np.exp(bad_norm_log)), 1.0)), np.sum(
    np.exp(bad_norm_log) 
)  # Fails

Change log

Fix log probability normalization in `MultiTargetDesign`
mikemhenry commented 8 months ago

@badisa Thank you for your contribution! Even if we don't end up really using this function, it would be good for it to be correct!

badisa commented 8 months ago

@badisa Thank you for your contribution! Even if we don't end up really using this function, it would be good for it to be correct!

Looks like the tests failed due to being unable to get the OE license, let me know if I need to do anything to resolve that.

Perhaps because it is a fork?

mikemhenry commented 8 months ago

Yah this is an issue with it being a fork, I will need to make this PR under a branch attached to the main repo, I can do that right now

mikemhenry commented 8 months ago

This "tricks" github into running the tests here as well as https://github.com/choderalab/perses/pull/1239 since it is the same commit

mikemhenry commented 8 months ago

@ijpulidos This PR has more context, do you mind reviewing this one?

mikemhenry commented 8 months ago

The code is the same btw @ijpulidos