Skip to content
Open
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
2 changes: 1 addition & 1 deletion jupiter_examples/nm_sigma_estimation_comparison.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
" \"\"\"\n",
" generator = NMGenerator()\n",
" mixture = NormalMeanMixtures(\"canonical\", sigma=real_sigma, distribution=distribution)\n",
" return generator.canonical_generate(mixture, sample_len)\n",
" return generator.generate(mixture, sample_len)\n",
"\n",
"def estimate_sigma_eigenvalue_based(sample, real_sigma, search_area, a, b):\n",
" sample_len = len(sample)\n",
Expand Down
25 changes: 3 additions & 22 deletions src/generators/nm_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class NMGenerator(AbstractGenerator):

@staticmethod
def classical_generate(mixture: AbstractMixtures, size: int) -> tpg.NDArray:
def generate(mixture: AbstractMixtures, size: int) -> tpg.NDArray:
"""Generate a sample of given size. Classical form of NMM
Copy link
Collaborator

Choose a reason for hiding this comment

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

Change docstrings


Args:
Expand All @@ -27,25 +27,6 @@ def classical_generate(mixture: AbstractMixtures, size: int) -> tpg.NDArray:
raise ValueError("Mixture must be NormalMeanMixtures")
mixing_values = mixture.params.distribution.rvs(size=size)
normal_values = scipy.stats.norm.rvs(size=size)
if mixture.mixture_form=="canonical":
return mixing_values + mixture.params.sigma * normal_values
return mixture.params.alpha + mixture.params.beta * mixing_values + mixture.params.gamma * normal_values

@staticmethod
def canonical_generate(mixture: AbstractMixtures, size: int) -> tpg.NDArray:
"""Generate a sample of given size. Canonical form of NMM

Args:
mixture: Normal Mean Mixture
size: length of sample

Returns: sample of given size

Raises:
ValueError: If mixture is not a Normal Mean Mixture

"""

if not isinstance(mixture, NormalMeanMixtures):
raise ValueError("Mixture must be NormalMeanMixtures")
mixing_values = mixture.params.distribution.rvs(size=size)
normal_values = scipy.stats.norm.rvs(size=size)
return mixing_values + mixture.params.sigma * normal_values
25 changes: 3 additions & 22 deletions src/generators/nmv_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class NMVGenerator(AbstractGenerator):

@staticmethod
def classical_generate(mixture: AbstractMixtures, size: int) -> tpg.NDArray:
def generate(mixture: AbstractMixtures, size: int) -> tpg.NDArray:
"""Generate a sample of given size. Classical form of NMVM
Copy link
Collaborator

Choose a reason for hiding this comment

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

Change docstrings


Args:
Expand All @@ -27,29 +27,10 @@ def classical_generate(mixture: AbstractMixtures, size: int) -> tpg.NDArray:
raise ValueError("Mixture must be NormalMeanMixtures")
mixing_values = mixture.params.distribution.rvs(size=size)
normal_values = scipy.stats.norm.rvs(size=size)
if mixture.mixture_form=="canonical":
return mixture.params.alpha + mixture.params.mu * mixing_values + (mixing_values ** 0.5) * normal_values
return (
mixture.params.alpha
+ mixture.params.beta * mixing_values
+ mixture.params.gamma * (mixing_values**0.5) * normal_values
)

@staticmethod
def canonical_generate(mixture: AbstractMixtures, size: int) -> tpg.NDArray:
"""Generate a sample of given size. Canonical form of NMVM

Args:
mixture: Normal Mean Variance Mixtures
size: length of sample

Returns: sample of given size

Raises:
ValueError: If mixture type is not Normal Mean Variance Mixtures

"""

if not isinstance(mixture, NormalMeanVarianceMixtures):
raise ValueError("Mixture must be NormalMeanMixtures")
mixing_values = mixture.params.distribution.rvs(size=size)
normal_values = scipy.stats.norm.rvs(size=size)
return mixture.params.alpha + mixture.params.mu * mixing_values + (mixing_values**0.5) * normal_values
25 changes: 3 additions & 22 deletions src/generators/nv_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class NVGenerator(AbstractGenerator):

@staticmethod
def classical_generate(mixture: AbstractMixtures, size: int) -> tpg.NDArray:
def generate(mixture: AbstractMixtures, size: int) -> tpg.NDArray:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Change docstrings

"""Generate a sample of given size. Classical form of NVM

Args:
Expand All @@ -27,25 +27,6 @@ def classical_generate(mixture: AbstractMixtures, size: int) -> tpg.NDArray:
raise ValueError("Mixture must be NormalMeanMixtures")
mixing_values = mixture.params.distribution.rvs(size=size)
normal_values = scipy.stats.norm.rvs(size=size)
if mixture.mixture_form == "canonical":
return mixture.params.alpha + (mixing_values ** 0.5) * normal_values
return mixture.params.alpha + mixture.params.gamma * (mixing_values**0.5) * normal_values

@staticmethod
def canonical_generate(mixture: AbstractMixtures, size: int) -> tpg.NDArray:
"""Generate a sample of given size. Canonical form of NVM

Args:
mixture: Normal Variance Mixtures
size: length of sample

Returns: sample of given size

Raises:
ValueError: If mixture type is not Normal Variance Mixtures

"""

if not isinstance(mixture, NormalVarianceMixtures):
raise ValueError("Mixture must be NormalMeanMixtures")
mixing_values = mixture.params.distribution.rvs(size=size)
normal_values = scipy.stats.norm.rvs(size=size)
return mixture.params.alpha + (mixing_values**0.5) * normal_values
1 change: 1 addition & 0 deletions src/mixtures/abstract_mixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def __init__(self, mixture_form: str, **kwargs: Any) -> None:
mixture_form: Form of Mixture classical or Canonical
**kwargs: Parameters of Mixture
"""
self.mixture_form=mixture_form
if mixture_form == "classical":
self.params = self._params_validation(self._classical_collector, kwargs)
elif mixture_form == "canonical":
Expand Down
20 changes: 10 additions & 10 deletions tests/generators/nm_generator/test_mixing_normal.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,38 @@ class TestMixingNormal:
)
def test_classic_generate_variance_0(self, mixing_variance: float, expected_variance: float) -> None:
mixture = NormalMeanMixtures("classical", alpha=0, beta=mixing_variance**0.5, gamma=1, distribution=norm)
sample = self.generator.classical_generate(mixture, self.test_mixture_size)
sample = self.generator.generate(mixture, self.test_mixture_size)
actual_variance = ndimage.variance(sample)
assert actual_variance == pytest.approx(expected_variance, 0.1)

@pytest.mark.parametrize("beta", np.random.uniform(0, 100, size=50))
def test_classic_generate_variance_1(self, beta: float) -> None:
expected_variance = beta**2 + 1
mixture = NormalMeanMixtures("classical", alpha=0, beta=beta, gamma=1, distribution=norm)
sample = self.generator.classical_generate(mixture, self.test_mixture_size)
sample = self.generator.generate(mixture, self.test_mixture_size)
actual_variance = ndimage.variance(sample)
assert actual_variance == pytest.approx(expected_variance, 0.1)

@pytest.mark.parametrize("beta, gamma", np.random.uniform(0, 100, size=(50, 2)))
def test_classic_generate_variance_2(self, beta: float, gamma: float) -> None:
expected_variance = beta**2 + gamma**2
mixture = NormalMeanMixtures("classical", alpha=0, beta=beta, gamma=gamma, distribution=norm)
sample = self.generator.classical_generate(mixture, self.test_mixture_size)
sample = self.generator.generate(mixture, self.test_mixture_size)
actual_variance = ndimage.variance(sample)
assert actual_variance == pytest.approx(expected_variance, 0.1)

@pytest.mark.parametrize("beta, gamma", np.random.uniform(0, 10, size=(50, 2)))
def test_classic_generate_mean(self, beta: float, gamma: float) -> None:
expected_mean = 0
mixture = NormalMeanMixtures("classical", alpha=0, beta=beta, gamma=gamma, distribution=norm)
sample = self.generator.classical_generate(mixture, self.test_mixture_size)
sample = self.generator.generate(mixture, self.test_mixture_size)
actual_mean = np.mean(np.array(sample))
assert abs(actual_mean - expected_mean) < 1

@pytest.mark.parametrize("expected_size", np.random.randint(0, 100, size=50))
def test_classic_generate_size(self, expected_size: int) -> None:
mixture = NormalMeanMixtures("classical", alpha=0, beta=1, gamma=1, distribution=norm)
sample = self.generator.classical_generate(mixture, expected_size)
sample = self.generator.generate(mixture, expected_size)
actual_size = np.size(sample)
assert actual_size == expected_size

Expand All @@ -56,37 +56,37 @@ def test_classic_generate_size(self, expected_size: int) -> None:
)
def test_canonical_generate_variance_0(self, mixing_variance: float, expected_variance: float) -> None:
mixture = NormalMeanMixtures("canonical", sigma=1, distribution=norm(0, mixing_variance**0.5))
sample = self.generator.canonical_generate(mixture, self.test_mixture_size)
sample = self.generator.generate(mixture, self.test_mixture_size)
actual_variance = ndimage.variance(sample)
assert actual_variance == pytest.approx(expected_variance, 0.1)

@pytest.mark.parametrize("sigma", np.random.uniform(0, 100, size=50))
def test_canonical_generate_variance_1(self, sigma: float) -> None:
expected_variance = sigma**2 + 1
mixture = NormalMeanMixtures("canonical", sigma=sigma, distribution=norm)
sample = self.generator.canonical_generate(mixture, self.test_mixture_size)
sample = self.generator.generate(mixture, self.test_mixture_size)
actual_variance = ndimage.variance(sample)
assert actual_variance == pytest.approx(expected_variance, 0.1)

@pytest.mark.parametrize("mixing_variance, sigma", np.random.uniform(0, 100, size=(50, 2)))
def test_canonical_generate_variance_2(self, mixing_variance: float, sigma: float) -> None:
expected_variance = mixing_variance + sigma**2
mixture = NormalMeanMixtures("canonical", sigma=sigma, distribution=norm(0, mixing_variance**0.5))
sample = self.generator.canonical_generate(mixture, self.test_mixture_size)
sample = self.generator.generate(mixture, self.test_mixture_size)
actual_variance = ndimage.variance(sample)
assert actual_variance == pytest.approx(expected_variance, 0.1)

@pytest.mark.parametrize("sigma", np.random.uniform(0, 10, size=50))
def test_canonical_generate_mean(self, sigma: float) -> None:
expected_mean = 0
mixture = NormalMeanMixtures("canonical", sigma=sigma, distribution=norm)
sample = self.generator.canonical_generate(mixture, self.test_mixture_size)
sample = self.generator.generate(mixture, self.test_mixture_size)
actual_mean = np.mean(np.array(sample))
assert abs(actual_mean - expected_mean) < 1

@pytest.mark.parametrize("expected_size", [*np.random.randint(0, 100, size=50), 0, 1, 1000000])
def test_canonical_generate_size(self, expected_size: int) -> None:
mixture = NormalMeanMixtures("canonical", sigma=1, distribution=norm)
sample = self.generator.canonical_generate(mixture, expected_size)
sample = self.generator.generate(mixture, expected_size)
actual_size = np.size(sample)
assert actual_size == expected_size
Loading