def test_scalar_quantity_distribution(): # Regression test for gh-12336 angles = Distribution([90., 30., 0.] * u.deg) sin_angles = np.sin(angles) # This failed in 4.3. assert isinstance(sin_angles, Distribution) assert isinstance(sin_angles, u.Quantity) assert_array_equal(sin_angles, Distribution(np.sin([90., 30., 0.]*u.deg)))
def test_histogram(): arr = np.random.randn(2, 3, 1000) distr = Distribution(arr) hist, bins = distr.pdf_histogram(bins=10) assert hist.shape == (2, 3, 10) assert bins.shape == (2, 3, 11)
def setup_class(self): with NumpyRNGContext(12345): self.data = np.random.normal(np.array([1, 2, 3, 4])[:, np.newaxis], np.array([3, 2, 4, 5])[:, np.newaxis], (4, 10000)) self.distr = Distribution(self.data * u.kpc)
def test_reprs(): darr = np.arange(30).reshape(3, 10) distr = Distribution(darr * u.kpc) assert 'n_samples=10' in repr(distr) assert 'n_samples=10' in str(distr) assert r'n_{\rm samp}=10' in distr._repr_latex_()
def test_array_repr_latex(): # as of this writing ndarray does not have a _repr_latex_, and this test # ensure distributions account for that. However, if in the future ndarray # gets a _repr_latex_, we can skip this. arr = np.random.randn(4, 1000) if hasattr(arr, '_repr_latex_'): pytest.skip('in this version of numpy, ndarray has a _repr_latex_') distr = Distribution(arr) assert distr._repr_latex_() is None
def test_distr_cannot_view_new_dtype(): # A Distribution has a very specific structured dtype with just one # element that holds the array of samples. As it is not clear what # to do with a view as a new dtype, we just error on it. # TODO: with a lot of thought, this restriction can likely be relaxed. distr = Distribution([2., 3., 4.]) with pytest.raises(ValueError, match='with a new dtype'): distr.view(np.dtype('f8')) # Check subclass just in case. ad = Angle(distr, 'deg') with pytest.raises(ValueError, match='with a new dtype'): ad.view(np.dtype('f8')) with pytest.raises(ValueError, match='with a new dtype'): ad.view(np.dtype('f8'), Distribution)
def test_init_scalar(): parr = np.random.poisson( np.array([1, 5, 30, 400])[:, np.newaxis], (4, 1000)) with pytest.raises(TypeError) as exc: Distribution(parr.ravel()[0]) assert exc.value.args[ 0] == "Attempted to initialize a Distribution with a scalar"
def test_quantity_init(self): # Test that we can initialize directly from a Quantity pq = self.parr << u.ct pqd = Distribution(pq) assert isinstance(pqd, u.Quantity) assert isinstance(pqd, Distribution) assert isinstance(pqd.value, Distribution) assert_array_equal(pqd.value.distribution, self.parr)
def test_quantity_init_with_distribution(self): # Test that we can initialize a Quantity from a Distribution. pd = Distribution(self.parr) qpd = pd << u.ct assert isinstance(qpd, u.Quantity) assert isinstance(qpd, Distribution) assert qpd.unit == u.ct assert_array_equal(qpd.value.distribution, pd.distribution.astype(float))
def test_index_assignment_quantity(): arr = np.random.randn(2, 1000) distr = Distribution(arr*u.kpc) d1q, d2q = distr assert isinstance(d1q, Distribution) assert isinstance(d2q, Distribution) ndistr = ds.normal(center=[1, 2]*u.kpc, std=[3, 4]*u.kpc, n_samples=1000) n1, n2 = ndistr assert isinstance(n1, ds.Distribution) assert isinstance(n2, ds.Distribution)
def test_index_assignment_array(): arr = np.random.randn(2, 1000) distr = Distribution(arr) d1a, d2a = distr assert isinstance(d1a, Distribution) assert isinstance(d2a, Distribution) ndistr = ds.normal(center=[1, 2], std=[3, 4], n_samples=1000) n1, n2 = ndistr assert isinstance(n1, ds.Distribution) assert isinstance(n2, ds.Distribution)
def test_add_distribution(self): another_data = (np.random.randn(4, 10000) * np.array([1000, .01, 80, 10])[:, np.newaxis] + np.array([2000, 0, 0, 500])[:, np.newaxis]) # another_data is in pc, but main distr is in kpc another_distr = Distribution(another_data * u.pc) combined_distr = self.distr + another_distr expected = np.median(self.data + another_data/1000, axis=-1) * self.distr.unit assert_quantity_allclose(combined_distr.pdf_median, expected) expected = np.var(self.data + another_data/1000, axis=-1) * self.distr.unit**2 assert_quantity_allclose(combined_distr.pdf_var, expected)
def test_distr_angle_view_as_quantity(): # Check that Quantity subclasses decay to Quantity appropriately. distr = Distribution([2., 3., 4.]) ad = Angle(distr, 'deg') qd = ad.view(u.Quantity) assert not isinstance(qd, Angle) assert isinstance(qd, u.Quantity) assert isinstance(qd, Distribution) # View directly as DistributionQuantity class. qd2 = ad.view(qd.__class__) assert not isinstance(qd2, Angle) assert isinstance(qd2, u.Quantity) assert isinstance(qd2, Distribution) assert_array_equal(qd2.distribution, qd.distribution) qd3 = ad.view(qd.dtype, qd.__class__) assert not isinstance(qd3, Angle) assert isinstance(qd3, u.Quantity) assert isinstance(qd3, Distribution) assert_array_equal(qd3.distribution, qd.distribution)
def test_distr_angle(): # Check that Quantity subclasses decay to Quantity appropriately. distr = Distribution([2., 3., 4.]) ad = Angle(distr, 'deg') ad_plus_ad = ad + ad assert isinstance(ad_plus_ad, Angle) assert isinstance(ad_plus_ad, Distribution) ad_times_ad = ad * ad assert not isinstance(ad_times_ad, Angle) assert isinstance(ad_times_ad, u.Quantity) assert isinstance(ad_times_ad, Distribution) ad += ad assert isinstance(ad, Angle) assert isinstance(ad, Distribution) assert_array_equal(ad.distribution, ad_plus_ad.distribution) with pytest.raises(u.UnitTypeError): ad *= ad
def test_numpy_init(self): # Test that we can initialize directly from a Numpy array Distribution(self.parr)
class TestDistributionStatistics(): def setup_class(self): with NumpyRNGContext(12345): self.data = np.random.normal(np.array([1, 2, 3, 4])[:, np.newaxis], np.array([3, 2, 4, 5])[:, np.newaxis], (4, 10000)) self.distr = Distribution(self.data * u.kpc) def test_shape(self): # Distribution shape assert self.distr.shape == (4, ) assert self.distr.distribution.shape == (4, 10000) def test_size(self): # Total number of values assert self.distr.size == 4 assert self.distr.distribution.size == 40000 def test_n_samples(self): # Number of samples assert self.distr.n_samples == 10000 def test_n_distr(self): assert self.distr.shape == (4,) def test_pdf_mean(self): # Mean of each PDF expected = np.mean(self.data, axis=-1) * self.distr.unit assert_quantity_allclose(self.distr.pdf_mean, expected) assert_quantity_allclose(self.distr.pdf_mean, [1, 2, 3, 4] * self.distr.unit, rtol=0.05) # make sure the right type comes out - should be a Quantity because it's # now a summary statistic assert not isinstance(self.distr.pdf_mean, Distribution) assert isinstance(self.distr.pdf_mean, u.Quantity) def test_pdf_std(self): # Standard deviation of each PDF expected = np.std(self.data, axis=-1) * self.distr.unit assert_quantity_allclose(self.distr.pdf_std, expected) assert_quantity_allclose(self.distr.pdf_std, [3, 2, 4, 5] * self.distr.unit, rtol=0.05) # make sure the right type comes out - should be a Quantity because it's # now a summary statistic assert not isinstance(self.distr.pdf_std, Distribution) assert isinstance(self.distr.pdf_std, u.Quantity) def test_pdf_var(self): # Variance of each PDF expected = np.var(self.data, axis=-1) * self.distr.unit**2 assert_quantity_allclose(self.distr.pdf_var, expected) assert_quantity_allclose(self.distr.pdf_var, [9, 4, 16, 25] * self.distr.unit**2, rtol=0.1) # make sure the right type comes out - should be a Quantity because it's # now a summary statistic assert not isinstance(self.distr.pdf_var, Distribution) assert isinstance(self.distr.pdf_var, u.Quantity) def test_pdf_median(self): # Median of each PDF expected = np.median(self.data, axis=-1) * self.distr.unit assert_quantity_allclose(self.distr.pdf_median, expected) assert_quantity_allclose(self.distr.pdf_median, [1, 2, 3, 4] * self.distr.unit, rtol=0.1) # make sure the right type comes out - should be a Quantity because it's # now a summary statistic assert not isinstance(self.distr.pdf_median, Distribution) assert isinstance(self.distr.pdf_median, u.Quantity) @pytest.mark.skipif(not HAS_SCIPY, reason='no scipy') def test_pdf_mad_smad(self): # Median absolute deviation of each PDF median = np.median(self.data, axis=-1, keepdims=True) expected = np.median(np.abs(self.data - median), axis=-1) * self.distr.unit assert_quantity_allclose(self.distr.pdf_mad, expected) assert_quantity_allclose(self.distr.pdf_smad, self.distr.pdf_mad * SMAD_FACTOR, rtol=1e-5) assert_quantity_allclose(self.distr.pdf_smad, [3, 2, 4, 5] * self.distr.unit, rtol=0.05) # make sure the right type comes out - should be a Quantity because it's # now a summary statistic assert not isinstance(self.distr.pdf_mad, Distribution) assert isinstance(self.distr.pdf_mad, u.Quantity) assert not isinstance(self.distr.pdf_smad, Distribution) assert isinstance(self.distr.pdf_smad, u.Quantity) def test_percentile(self): expected = np.percentile(self.data, [10, 50, 90], axis=-1) * self.distr.unit percs = self.distr.pdf_percentiles([10, 50, 90]) assert_quantity_allclose(percs, expected) assert percs.shape == (3, 4) # make sure the right type comes out - should be a Quantity because it's # now a summary statistic assert not isinstance(percs, Distribution) assert isinstance(percs, u.Quantity) def test_add_quantity(self): distrplus = self.distr + [2000, 0, 0, 500] * u.pc expected = (np.median(self.data, axis=-1) + np.array([2, 0, 0, 0.5])) * self.distr.unit assert_quantity_allclose(distrplus.pdf_median, expected) expected = np.var(self.data, axis=-1) * self.distr.unit**2 assert_quantity_allclose(distrplus.pdf_var, expected) def test_add_distribution(self): another_data = (np.random.randn(4, 10000) * np.array([1000, .01, 80, 10])[:, np.newaxis] + np.array([2000, 0, 0, 500])[:, np.newaxis]) # another_data is in pc, but main distr is in kpc another_distr = Distribution(another_data * u.pc) combined_distr = self.distr + another_distr expected = np.median(self.data + another_data/1000, axis=-1) * self.distr.unit assert_quantity_allclose(combined_distr.pdf_median, expected) expected = np.var(self.data + another_data/1000, axis=-1) * self.distr.unit**2 assert_quantity_allclose(combined_distr.pdf_var, expected)
def test_quantity_init_T(): # Test that we can initialize directly from a Quantity pq = np.random.poisson(np.array([1, 5, 30, 400]), (1000, 4)) * u.ct Distribution(pq.T)
def test_quantity_init(): # Test that we can initialize directly from a Quantity pq = np.random.poisson(np.array([1, 5, 30, 400])[:, np.newaxis], (4, 1000)) * u.ct Distribution(pq)
def test_numpy_init_T(): rates = np.array([1, 5, 30, 400]) parr = np.random.poisson(rates, (1000, 4)) Distribution(parr.T)
def test_quantity_init_T(self): # Test that we can initialize directly from a Quantity pq = self.parr_t << u.ct Distribution(pq.T)
def test_numpy_init(): # Test that we can initialize directly from a Numpy array rates = np.array([1, 5, 30, 400])[:, np.newaxis] parr = np.random.poisson(rates, (4, 1000)) Distribution(parr)
def test_numpy_init_T(self): Distribution(self.parr_t.T)