Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Sequence.generate_random_poisson and update Sequence.generate_random_exponential #108

Merged
merged 3 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
_Nothing yet_
### Fixed
- Fixed interpretation of `Sequence.generate_random_exponential`'s `lam` parameter, to match common interpretation of lambda parameters of exponential and Poisson distributions (#108)

### Removed
- Removed `Sequence.generate_random_poisson`, potentially generating invalid sequences; refer to `Sequence.generate_random_exponetial` instead (#108)

## [0.2.0] - 2023-12-22
### Added
Expand Down
66 changes: 12 additions & 54 deletions thebeat/core/sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,55 +561,6 @@ def generate_random_uniform(
iois = rng.uniform(low=a, high=b, size=n_iois)
return cls(iois, end_with_interval=end_with_interval, **kwargs)

@classmethod
def generate_random_poisson(
cls,
n_events: int,
lam: float,
rng: np.random.Generator | None = None,
end_with_interval: bool = False,
**kwargs,
) -> Sequence:
"""
Class method that generates a :py:class:`Sequence` object with random inter-onset intervals
(IOIs) based on a Poisson distribution.

Parameters
----------
n_events
The desired number of events in the sequence.
lam
The desired value for lambda.
rng
A :class:`numpy.random.Generator` object. If not supplied
:func:`numpy.random.default_rng` is used.
end_with_interval
Indicates whether the sequence should end with an event (``False``) or an interval
(``True``).
**kwargs
Additional keyword arguments are passed to the :py:class:`Sequence` constructor.


Examples
--------
>>> generator = np.random.default_rng(123)
>>> seq = Sequence.generate_random_poisson(n_events=5,lam=500,rng=generator)
>>> print(seq.iois)
[512. 480. 476. 539.]

"""
if rng is None:
rng = np.random.default_rng()

# Number of IOIs depends on end_with_interval argument
n_iois = n_events if end_with_interval else n_events - 1

return cls(
rng.poisson(lam=lam, size=n_iois),
end_with_interval=end_with_interval,
**kwargs,
)

@classmethod
def generate_random_exponential(
cls,
Expand All @@ -619,15 +570,22 @@ def generate_random_exponential(
end_with_interval: bool = False,
**kwargs,
) -> Sequence:
"""Class method that generates a :py:class:`Sequence` object with random inter-onset
intervals (IOIs) based on an exponential distribution.
"""Generate a :py:class:`Sequence` object with random inter-onset intervals (IOIs) sampled
from an exponential distribution.

Random IOIs drawn from an exponential distribution will result in a sequence sampled from a
Poisson point process. Consequently, the number of events within a certain time window
will follow a corresponding Poisson distribution. In particular, if IOIs are exponentially
distributed according to parameter :math:`\\lambda`, the number of events within any interval
of duration 1 will follow a Poisson distribution with the same :math:`\\lambda` value.

Parameters
----------
n_events
The desired number of events in the sequence.
lam
The desired value for lambda.
The desired value for lambda, the rate parameter (the mean number of events per time unit,
equal to the inverse of the mean interval duration).
rng
A :class:`numpy.random.Generator` object. If not supplied NumPy's
:func:`numpy.random.default_rng` is used.
Expand All @@ -641,7 +599,7 @@ def generate_random_exponential(
Examples
--------
>>> generator = np.random.default_rng(seed=123)
>>> seq = Sequence.generate_random_exponential(n_events=5,lam=500,rng=generator)
>>> seq = Sequence.generate_random_exponential(n_events=5, lam=0.002, rng=generator)
>>> print(seq.iois)
[298.48624756 58.51553052 125.89734975 153.98272273]

Expand All @@ -652,7 +610,7 @@ def generate_random_exponential(
n_iois = n_events if end_with_interval else n_events - 1

return cls(
rng.exponential(scale=lam, size=n_iois),
rng.exponential(scale=1 / lam, size=n_iois),
end_with_interval=end_with_interval,
**kwargs,
)
Expand Down
Loading