def test_jsd(self): """evaluate jsd between identical, and non-identical distributions""" # case1 is testing if the jsd between two identical distributions is 0.0 case1 = [ [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], ] for index in range(len(case1[0])): case1[0][index] = 1.0 case1[1][index] = 1.0 assert_allclose( jsd(case1[0], case1[1], validate=True), 0.0, err_msg="Testing case1 for jsd failed", atol=self.atol, ) case1[0][index] = 0.0 case1[1][index] = 0.0 # case2 is testing the numerical output of jsd between two distant distributions case2 = [[1 / 10, 9 / 10, 0], [0, 1 / 10, 9 / 10]] assert_allclose( jsd(case2[0], case2[1], validate=True), 0.7655022032053593, err_msg="Testing case2 for jsd failed", atol=self.atol, ) # case3 is testing the numerical output of jsd between two distant distributions case3 = [[1.0, 0.0], [1 / 2, 1 / 2]] assert_allclose( jsd(case3[0], case3[1], validate=True), 0.3112781244591328, err_msg="Testing case3 for jsd failed", atol=self.atol, ) # case4 - the jsd between two identical uniform distributions is 0.0 case4 = [ [1 / 10] * 10, [1 / 10] * 10, ] assert_allclose( jsd(case4[0], case4[1], validate=True), 0.0, err_msg="Testing case4 for jsd failed", atol=self.atol, ) assert_allclose( jsd(case4[0], case4[0], validate=True), 0.0, err_msg="Testing case4 for jsd failed", atol=self.atol, )
def test_jsd(self): """case1 is testing if the jsd between two identical distributions is 0.0""" case1 = [ [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], ] for pointer in range(10): case1[0][pointer] = 1.0 case1[1][pointer] = 1.0 assert_allclose( jsd(case1[0], case1[1], validate=True), 0.0, err_msg="Testing case1 for jsd failed", ) case1[0][pointer] = 0.0 case1[1][pointer] = 0.0 """case2 is testing the numerical output of jsd between two random distributions""" case2 = [[1.0 / 10, 9.0 / 10, 0], [0, 1.0 / 10, 9.0 / 10]] assert_allclose( jsd(case2[0], case2[1], validate=True), 0.7655022032053593, err_msg="Testing case2 for jsd failed", ) """case3 is testing the numerical output of jsd between two random distributions""" case3 = [[1.0, 0.0], [0.5, 0.5]] assert_allclose( jsd(case3[0], case3[1], validate=True), 0.3112781244591328, err_msg="Testing case3 for jsd failed", ) """case4 is testing if the jsd between two identical uniform distributions is 0.0""" case4 = [ [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], ] assert_allclose( jsd(case4[0], case4[1], validate=True), 0.0, err_msg="Testing case4 for jsd failed", )
def test_jsd_precision(self): """handle case where the difference is incredibly small""" pi_0 = [ 0.4398948756903677, 0.1623791467423164, 0.31844113569205656, 0.07928484187525932, ] pi_1 = [ 0.43989487569036767, 0.16237914674231643, 0.3184411356920566, 0.07928484187525933, ] result = jsd(pi_0, pi_1) self.assertTrue(result >= 0)
def test_pairwise_jsd(self): """correctly constructs pairwise JSD dict""" from numpy.random import random from cogent3.maths.measure import jsd data = [[0.25, 0.25, 0.25, 0.25], [0.5, 0.5, 0, 0]] expect = jsd(data[0], data[1]) freqs = MotifFreqsArray(array(data), "ACGT") got = freqs.pairwise_jsd() assert_allclose(list(got.values())[0], expect) data = [] for _ in range(6): freqs = random(4) freqs = freqs / freqs.sum() data.append(freqs) freqs = MotifFreqsArray(array(data), "ACGT") pwise = freqs.pairwise_jsd() self.assertEqual(len(pwise), 6 * 6 - 6)
def test_jsd_validation(self): """jsd fails with malformed data""" freqs1 = random(5) normalised_freqs1 = freqs1 / freqs1.sum() two_dimensional_freqs1 = [freqs1, freqs1] shorter_freqs1 = freqs1[:4] freqs2 = random(5) normalised_freqs2 = freqs2 / freqs2.sum() two_dimensional_freqs2 = [freqs2, freqs2] shorter_freqs2 = freqs2[:4] with self.assertRaises(AssertionError): jsd( freqs1, two_dimensional_freqs2, validate=True ) # freqs1/freqs2 mismatched shape with self.assertRaises(AssertionError): jsd( two_dimensional_freqs1, freqs2, validate=True ) # freqs1/freqs2 mismatched shape with self.assertRaises(AssertionError): jsd(freqs1, shorter_freqs2, validate=True) # freqs1/freqs2 mismatched shape with self.assertRaises(AssertionError): jsd(shorter_freqs1, freqs2, validate=True) # freqs1/freqs2 mismatched shape with self.assertRaises(AssertionError): jsd( two_dimensional_freqs1, freqs2, validate=True ) # freqs1 has incorrect dimension with self.assertRaises(AssertionError): jsd( two_dimensional_freqs1, two_dimensional_freqs2, validate=True ) # freqs1 has incorrect dimension with self.assertRaises(AssertionError): jsd( freqs1, two_dimensional_freqs2, validate=True ) # freqs2 has incorrect dimension with self.assertRaises(AssertionError): jsd(freqs1, freqs2, validate=True) # invalid freqs1 with self.assertRaises(AssertionError): jsd(freqs1, normalised_freqs2, validate=True) # invalid freqs1 with self.assertRaises(AssertionError): jsd(normalised_freqs1, freqs2, validate=True) # invalid freqs2