Skip to content

Conversation

@CozySocksAlways
Copy link
Contributor

This PR fixes Issue #679 . Currently van_rossum_distance could return nan due to extremely small negative values because of floating point errors before applying np.sqrt.

Fix
Added check before np.sqrt to find small negative values, then replaced them using np.maximum(vr_dist,0). Also outputs runtime warning for transparancy.
This ensures that spike trains that should result in a distance of 0 no longer produce nan.

Test
Added unit test that reproduces the spike train scenario from the issue, it asserts that the computed distance is 0 and not nan

@coveralls
Copy link
Collaborator

coveralls commented Nov 27, 2025

Coverage Status

coverage: 88.289% (+0.006%) from 88.283%
when pulling cd3f15f on INM-6:fix/van-rossum-nan
into 867a0fc on NeuralEnsemble:master.

@CozySocksAlways CozySocksAlways marked this pull request as ready for review November 27, 2025 07:59
@mdenker mdenker added this to the v1.2.0 milestone Dec 1, 2025
@CozySocksAlways CozySocksAlways added the bugfix Fix for an indentified bug. label Dec 1, 2025
@kohlerca kohlerca self-requested a review December 2, 2025 10:33


# Check small negative values edge case
with warnings.catch_warnings(record='True') as w:
Copy link
Contributor

Choose a reason for hiding this comment

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

The expected type for argument record is bool, not str

self.assertEqual(len(stds.van_rossum_distance([], self.tau3)), 0)


# Check small negative values edge case
Copy link
Contributor

Choose a reason for hiding this comment

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

Although there is a single unit test for the function, it is clearer to add a specific regression unit test for the issue. We have examples in other modules, e.g., test_instantaneous_rate_regression_288 in elephant.statistics. It is good to point to the issue number and have a short comment.

self.st23 = StationaryPoissonProcess(rate=30 * Hz, t_start=0 * ms,
t_stop=1000 * ms
).generate_spiketrain()
self.st24 = SpikeTrain([0.1782, 0.2286, 0.2804, 0.4972, 0.5504], units='s',t_stop=4.0)
Copy link
Contributor

Choose a reason for hiding this comment

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

As suggested by the dedicated regression test, the spike train can be initialized locally in the function, which facilitates code reading.

# Clip small negative values
if np.any(vr_dist < 0):
warnings.warn(
"van_rossum_distance: very small negative values encountered "
Copy link
Contributor

Choose a reason for hiding this comment

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

Here, it would also be helpful to hint at possible causes. As we tested, this does not happen if the units are in ms, and the user could change the representation to prevent the warning if noticed. Maybe something like "... very small negative values encountered, setting them to zero. This is likely due to floating point error, which can happen if the spike times are small floating point values. In this case, a possible solution to prevent the warning is to change the time unit of the input spike trains for better precision (e.g., from seconds to milliseconds).".

@kohlerca
Copy link
Contributor

The implementation looks good. I made small suggestions to improve the warnings and structure of the unit test.

Copy link
Contributor

@kohlerca kohlerca left a comment

Choose a reason for hiding this comment

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

I reviewed the recent changes, and they look good to me. The PR can be merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Fix for an indentified bug.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Underflow: Negative value in van_rossum_distance function

4 participants