コード例 #1
0
    def test_pattern_array(self):
        array_pattern = paragami.NumericArrayPattern(
            shape=(4, ), lb=-1, ub=10.0)
        pattern_array = paragami.PatternArray((2, 3), array_pattern)
        valid_value = pattern_array.random()
        _test_pattern(self, pattern_array, valid_value)

        matrix_pattern = paragami.PSDSymmetricMatrixPattern(size=2)
        pattern_array = paragami.PatternArray((2, 3), matrix_pattern)
        valid_value = pattern_array.random()
        _test_pattern(self, pattern_array, valid_value)

        base_pattern_array = paragami.PatternArray((2, 1), matrix_pattern)
        pattern_array_array = paragami.PatternArray((1, 3), base_pattern_array)
        valid_value = pattern_array_array.random()
        _test_pattern(self, pattern_array_array, valid_value)

        # Test flat indices.
        matrix_pattern = paragami.PSDSymmetricMatrixPattern(size=2)
        pattern_array = paragami.PatternArray((2, 3), matrix_pattern)
        _test_array_flat_indices(self, pattern_array)

        self.assertTrue(
            paragami.PatternArray((3, 3), matrix_pattern) !=
            paragami.PatternArray((2, 3), matrix_pattern))

        self.assertTrue(
            paragami.PatternArray((2, 3), array_pattern) !=
            paragami.PatternArray((2, 3), matrix_pattern))

        pattern_array = paragami.PatternArray((2, 3), array_pattern)
        self.assertEqual((2, 3), pattern_array.array_shape())
        self.assertEqual((2, 3, 4), pattern_array.shape())
        self.assertTrue(array_pattern == pattern_array.base_pattern())

        # Test bad arguments.
        with self.assertRaisesRegex(NotImplementedError,
                                    'not numpy.ndarray types'):
            paragami.PatternArray((2, 3), paragami.PatternDict())

        pattern_array = paragami.PatternArray((2, 3), array_pattern)
        with self.assertRaisesRegex(ValueError, 'Wrong number of dimensions'):
            pattern_array.flatten(np.full((2, 3), 0), free=False)

        with self.assertRaisesRegex(ValueError, 'Wrong number of dimensions'):
            pattern_array.flatten(np.full((2, 3, 4, 5), 0), free=False)

        with self.assertRaisesRegex(ValueError, 'Wrong shape'):
            pattern_array.flatten(np.full((2, 3, 5), 0), free=False)

        with self.assertRaisesRegex(ValueError, 'Bad value'):
            pattern_array.flatten(np.full((2, 3, 4), -10), free=False)

        with self.assertRaisesRegex(ValueError, 'must be a 1d vector'):
            pattern_array.fold(np.full((24, 1), -10), free=False)

        with self.assertRaisesRegex(ValueError, 'Wrong size'):
            pattern_array.fold(np.full((25, ), -10), free=False)
コード例 #2
0
    def test_psdsymmetric_matrix_patterns(self):
        dim = 3
        valid_value = np.eye(dim) * 3 + np.full((dim, dim), 0.1)
        pattern = paragami.PSDSymmetricMatrixPattern(dim)
        _test_pattern(self, pattern, valid_value)

        pattern = paragami.PSDSymmetricMatrixPattern(dim, diag_lb=0.5)
        _test_pattern(self, pattern, valid_value)

        self.assertTrue(
            paragami.PSDSymmetricMatrixPattern(3) !=
            paragami.PSDSymmetricMatrixPattern(4))

        self.assertTrue(
            paragami.PSDSymmetricMatrixPattern(3, diag_lb=2) !=
            paragami.PSDSymmetricMatrixPattern(3))

        pattern = paragami.PSDSymmetricMatrixPattern(dim, diag_lb=0.5)
        self.assertEqual(dim, pattern.size())
        self.assertEqual((dim, dim), pattern.shape())
        self.assertEqual(0.5, pattern.diag_lb())

        # Test bad inputs.
        with self.assertRaisesRegex(ValueError, 'diagonal lower bound'):
            paragami.PSDSymmetricMatrixPattern(3, diag_lb=-1)

        pattern = paragami.PSDSymmetricMatrixPattern(3, diag_lb=0.5)
        with self.assertRaisesRegex(ValueError, 'The matrix is not of shape'):
            pattern.flatten(np.eye(4), free=False)

        with self.assertRaisesRegex(ValueError,
                                    'Diagonal is less than the lower bound'):
            pattern.flatten(0.25 * np.eye(3), free=False)

        with self.assertRaisesRegex(ValueError, 'not symmetric'):
            bad_mat = np.eye(3)
            bad_mat[0, 1] = 0.1
            pattern.flatten(bad_mat, free=False)

        flat_val = pattern.flatten(pattern.random(), free=False)
        with self.assertRaisesRegex(
                ValueError, 'The argument to fold must be a 1d vector'):
            pattern.fold(np.atleast_2d(flat_val), free=False)

        flat_val = pattern.flatten(np.eye(3), free=False)
        with self.assertRaisesRegex(ValueError, 'Wrong length'):
            pattern.fold(flat_val[-1], free=False)

        flat_val = 0.25 * flat_val
        with self.assertRaisesRegex(ValueError,
                                    'Diagonal is less than the lower bound'):
            pattern.fold(flat_val, free=False)

        # Test flat indices.
        pattern = paragami.PSDSymmetricMatrixPattern(3, diag_lb=0.5)
        _test_array_flat_indices(self, pattern)
コード例 #3
0
def get_regression_array_pattern(num_obs, x_obs_dim):
    """Get a paragami pattern for an array of approximate regression posteriors.

    Parameters
    -------------
    num_obs : `int`
        The number of distinct regressions.
    x_obs_dim : `int`
        The dimensionality of the regressors.

    Returns
    ----------
    reg_params_pattern : A paragami pattern.

    The field ``beta_mean`` is the ordinary regression
    coefficient, and ``beta_info`` is the estimated inverse covariance
    matrix.  The field ``y_info`` contains a point estimate for the
    inverse variance of each regressoin's residual.
    """
    reg_params_pattern = paragami.PatternDict()
    reg_params_pattern['beta_mean'] = \
        paragami.NumericArrayPattern(shape=(num_obs, x_obs_dim))
    reg_params_pattern['beta_info'] = \
        paragami.pattern_containers.PatternArray(
            array_shape=(num_obs, ),
            base_pattern=\
                paragami.PSDSymmetricMatrixPattern(size=x_obs_dim))
    reg_params_pattern['y_info'] = \
        paragami.NumericVectorPattern(length=num_obs, lb=0.0)
    return reg_params_pattern
コード例 #4
0
def get_prior_params_pattern(obs_dim, num_components):
    prior_params_pattern = paragami.PatternDict()
    prior_params_pattern['probs_alpha'] = \
        paragami.NumericVectorPattern(length=num_components, lb=0.0)
    prior_params_pattern['centroid_prior_mean'] = \
        paragami.NumericArrayPattern(shape=(num_components, obs_dim))
    prior_params_pattern['centroid_prior_info'] = \
        paragami.PSDSymmetricMatrixPattern(size=obs_dim)
    return prior_params_pattern
コード例 #5
0
ファイル: test_functions.py プロジェクト: rgiordan/paragami
def get_small_test_pattern():
    # autograd will pass invalid values, so turn off value checking.
    pattern = paragami.PatternDict()
    pattern['array'] = paragami.NumericArrayPattern((2, 3, 4),
                                                    lb=-1,
                                                    ub=10,
                                                    default_validate=False)
    pattern['mat'] = paragami.PSDSymmetricMatrixPattern(3,
                                                        default_validate=False)

    return pattern
コード例 #6
0
def get_default_prior_params(dim):
    """
    Returns a paragami patterned dictionary
    that stores the prior parameters.

    Default prior parameters are those set for the experiments in
    "Evaluating Sensitivity to the Stick Breaking Prior in
    Bayesian Nonparametrics"
    https://arxiv.org/abs/1810.06587

    Parameters
    ----------
    dim : int
        Dimension of the datapoints.

    Returns
    -------
    prior_params_dict : dictionary
        A dictionary that contains the prior parameters.

    prior_params_paragami : paragami Patterned Dictionary
        A paragami patterned dictionary that contains the prior parameters.

    """

    prior_params_dict = dict()
    prior_params_paragami = paragami.PatternDict()

    # DP prior parameter
    prior_params_dict['alpha'] = np.array([3.0])
    prior_params_paragami['alpha'] = \
        paragami.NumericArrayPattern(shape=(1, ), lb = 0.0)

    # prior on the centroids
    prior_params_dict['prior_centroid_mean'] = np.array([0.0])
    prior_params_paragami['prior_centroid_mean'] = \
        paragami.NumericArrayPattern(shape=(1, ))

    prior_params_dict['prior_centroid_info'] = np.array([0.1])
    prior_params_paragami['prior_centroid_info'] = \
        paragami.NumericArrayPattern(shape=(1, ), lb = 0.0)

    # prior on the variance
    prior_params_dict['prior_gamma_df'] = np.array([8.0])
    prior_params_paragami['prior_gamma_df'] = \
        paragami.NumericArrayPattern(shape=(1, ), lb = 0.0)

    prior_params_dict['prior_gamma_inv_scale'] = 0.62 * np.eye(dim)
    prior_params_paragami['prior_gamma_inv_scale'] = \
        paragami.PSDSymmetricMatrixPattern(size=dim)

    return prior_params_dict, prior_params_paragami
コード例 #7
0
def get_vb_params_paragami_object(dim, k_approx):
    """
    Returns a paragami patterned dictionary
    that stores the variational parameters.

    Parameters
    ----------
    dim : int
        Dimension of the datapoints.
    k_approx : int
        Number of components in the model.

    Returns
    -------
    vb_params_dict : dictionary
        A dictionary that contains the variational parameters.

    vb_params_paragami : paragami patterned dictionary
        A paragami patterned dictionary that contains the variational parameters.

    """

    vb_params_paragami = paragami.PatternDict()

    # cluster centroids
    vb_params_paragami['centroids'] = \
        paragami.NumericArrayPattern(shape=(dim, k_approx))

    # BNP sticks
    # variational distribution for each stick is logitnormal
    vb_params_paragami['stick_propn_mean'] = \
        paragami.NumericArrayPattern(shape = (k_approx - 1,))
    vb_params_paragami['stick_propn_info'] = \
        paragami.NumericArrayPattern(shape = (k_approx - 1,), lb = 1e-4)

    # cluster covariances
    vb_params_paragami['gamma'] = \
        paragami.pattern_containers.PatternArray(array_shape = (k_approx, ), \
                    base_pattern = paragami.PSDSymmetricMatrixPattern(size=dim))

    vb_params_dict = vb_params_paragami.random()

    return vb_params_dict, vb_params_paragami
コード例 #8
0
ファイル: test_functions.py プロジェクト: rgiordan/paragami
def get_test_pattern():
    # autograd will pass invalid values, so turn off value checking.
    pattern = paragami.PatternDict()
    pattern['array'] = paragami.NumericArrayPattern((2, 3, 4),
                                                    lb=-1,
                                                    ub=20,
                                                    default_validate=False)
    pattern['mat'] = paragami.PSDSymmetricMatrixPattern(3,
                                                        default_validate=False)
    pattern['simplex'] = paragami.SimplexArrayPattern(2, (3, ),
                                                      default_validate=False)
    subdict = paragami.PatternDict()
    subdict['array2'] = paragami.NumericArrayPattern((2, ),
                                                     lb=-3,
                                                     ub=10,
                                                     default_validate=False)
    pattern['dict'] = subdict

    return pattern
コード例 #9
0
    def test_json_files(self):
        pattern = paragami.PatternDict()
        pattern['num'] = paragami.NumericArrayPattern((1, 2))
        pattern['mat'] = paragami.PSDSymmetricMatrixPattern(5)

        val_folded = pattern.random()
        extra = np.random.random(5)

        outfile_name = '/tmp/paragami_test_' + str(np.random.randint(1e6))

        paragami.save_folded(outfile_name, val_folded, pattern, extra=extra)

        val_folded_loaded, pattern_loaded, data = \
            paragami.load_folded(outfile_name + '.npz')

        self.assertTrue(pattern_loaded == pattern)
        self.assertTrue(val_folded.keys() == val_folded_loaded.keys())
        for keyname in val_folded.keys():
            assert_array_almost_equal(
                val_folded[keyname], val_folded_loaded[keyname])
        assert_array_almost_equal(extra, data['extra'])
コード例 #10
0
    def test_dictionary_patterns(self):
        def test_pattern(dict_pattern, dict_val):
            # autograd can't differentiate the folding of a dictionary
            # because it involves assignment to elements of a dictionary.
            _test_pattern(self, dict_pattern, dict_val,
                          check_equal=check_dict_equal,
                          jacobian_ad_test=False)

        def check_dict_equal(dict1, dict2):
            self.assertEqual(dict1.keys(), dict2.keys())
            for key in dict1:
                if type(dict1[key]) is collections.OrderedDict:
                    check_dict_equal(dict1[key], dict2[key])
                else:
                    assert_array_almost_equal(dict1[key], dict2[key])

        print('dictionary pattern test: one element')
        dict_pattern = paragami.PatternDict()
        dict_pattern['a'] = \
            paragami.NumericArrayPattern((2, 3, 4), lb=-1, ub=2)
        test_pattern(dict_pattern, dict_pattern.random())

        print('dictionary pattern test: two elements')
        dict_pattern['b'] = \
            paragami.NumericArrayPattern((5, ), lb=-1, ub=10)
        test_pattern(dict_pattern, dict_pattern.random())

        print('dictionary pattern test: third matrix element')
        dict_pattern['c'] = \
            paragami.PSDSymmetricMatrixPattern(size=3)
        test_pattern(dict_pattern, dict_pattern.random())

        print('dictionary pattern test: sub-dictionary')
        subdict = paragami.PatternDict()
        subdict['suba'] = paragami.NumericArrayPattern((2, ))
        dict_pattern['d'] = subdict
        test_pattern(dict_pattern, dict_pattern.random())

        # Test flat indices.
        _test_array_flat_indices(self, dict_pattern)

        # Test keys.
        self.assertEqual(list(dict_pattern.keys()), ['a', 'b', 'c', 'd'])

        # Check that it works with ordinary dictionaries, not only OrderedDict.
        print('dictionary pattern test: non-ordered dictionary')
        test_pattern(dict_pattern, dict(dict_pattern.random()))

        # Check deletion and non-equality.
        print('dictionary pattern test: deletion')
        old_dict_pattern = copy.deepcopy(dict_pattern)
        del dict_pattern['b']
        self.assertTrue(dict_pattern != old_dict_pattern)
        test_pattern(dict_pattern, dict_pattern.random())

        # Check modifying an existing array element.
        print('dictionary pattern test: modifying array')
        dict_pattern['a'] = paragami.NumericArrayPattern((2, ), lb=-1, ub=2)
        test_pattern(dict_pattern, dict_pattern.random())

        # Check modifying an existing dictionary element.
        print('dictionary pattern test: modifying sub-dictionary')
        dict_pattern['d'] = \
            paragami.NumericArrayPattern((4, ), lb=-1, ub=10)
        test_pattern(dict_pattern, dict_pattern.random())

        # Check locking
        dict_pattern.lock()

        with self.assertRaises(ValueError):
            del dict_pattern['b']

        with self.assertRaises(ValueError):
            dict_pattern['new'] = \
                paragami.NumericArrayPattern((4, ))

        with self.assertRaises(ValueError):
            dict_pattern['a'] = \
                paragami.NumericArrayPattern((4, ))

        # Check invalid values.
        bad_dict = dict_pattern.random()
        del bad_dict['a']
        with self.assertRaisesRegex(ValueError, 'not in folded_val dictionary'):
            dict_pattern.flatten(bad_dict, free=True)

        bad_dict = dict_pattern.random()
        bad_dict['a'] = np.array(-10)
        with self.assertRaisesRegex(ValueError, 'is not valid'):
            dict_pattern.flatten(bad_dict, free=True)

        free_val = np.random.random(dict_pattern.flat_length(True))
        with self.assertRaisesRegex(ValueError,
                                    'argument to fold must be a 1d vector'):
            dict_pattern.fold(np.atleast_2d(free_val), free=True)

        with self.assertRaisesRegex(ValueError,
                                    'Wrong size for pattern dictionary'):
            dict_pattern.fold(free_val[-1], free=True)