コード例 #1
0
    def _get_derivatives_implied_cov(self):
        """
        Compute the derivatives for the implied covariance
        matrix (sigma).

        Returns
        -------
        loadings_dx : numpy array
            The derivative of the loadings matrix.
        factor_covs_dx : numpy array
            The derivative of the factor covariance matrix.
        error_covs_dx : numpy array
            The derivative of the error covariance matrix.
        """
        # meets all of our expected criteria
        check_is_fitted(self, 'loadings_')

        loadings = self.loadings_.copy()
        factor_covs = self.factor_varcovs_.copy()

        sym_lower_var_idx = get_symmetric_lower_idxs(self.model.n_variables)
        sym_upper_fac_idx = get_symmetric_upper_idxs(self.model.n_factors, diag=False)
        sym_lower_fac_idx = get_symmetric_lower_idxs(self.model.n_factors, diag=False)

        factors_diag = np.eye(self.model.n_factors)
        factors_diag_mult = factors_diag.dot(factor_covs).dot(factors_diag.T).dot(loadings.T)

        # calculate the derivative of the loadings matrix, using the commutation matrix
        loadings_dx = np.eye(self.model.n_variables**2) + commutation_matrix(self.model.n_variables,
                                                                             self.model.n_variables)
        loadings_dx = loadings_dx.dot(np.kron(factors_diag_mult, np.eye(self.model.n_variables)).T)

        # calculate the derivative of the factor_covs matrix
        factor_covs_dx = loadings.dot(factors_diag)
        factor_covs_dx = np.kron(factor_covs_dx, factor_covs_dx)

        off_diag = (factor_covs_dx[:, sym_lower_fac_idx] +
                    factor_covs_dx[:, sym_upper_fac_idx])

        combine_indices = np.concatenate([sym_upper_fac_idx, sym_lower_fac_idx])
        combine_diag = np.concatenate([off_diag, off_diag], axis=1)

        factor_covs_dx[:, combine_indices] = combine_diag
        factor_covs_dx = factor_covs_dx[:, :factor_covs.size]

        # calculate the derivative of the error_cov matrix,
        # which we assume will always be a diagonal matrix
        error_covs_dx = np.eye(self.model.n_variables**2)

        # make sure these matrices are symmetric
        loadings_dx = loadings_dx[sym_lower_var_idx, :]
        factor_covs_dx = factor_covs_dx[sym_lower_var_idx, :]
        error_covs_dx = error_covs_dx[sym_lower_var_idx, :]

        # we also want to calculate the derivative for the intercepts
        intercept_dx = np.zeros((loadings_dx.shape[0], self.model.n_variables), dtype=float)
        return (loadings_dx[:, self.model.loadings_free].copy(),
                factor_covs_dx[:, self.model.factor_covs_free].copy(),
                error_covs_dx[:, self.model.error_vars_free].copy(),
                intercept_dx)
コード例 #2
0
    def __init__(self,
                 loadings,
                 n_factors,
                 n_variables,
                 factor_names=None,
                 variable_names=None):

        assert isinstance(loadings, np.ndarray)
        assert loadings.shape[0] == n_variables
        assert loadings.shape[1] == n_factors

        self._loadings = loadings
        self._n_factors = n_factors
        self._n_variables = n_variables
        self._factor_names = factor_names
        self._variable_names = variable_names

        self._n_lower_diag = get_symmetric_lower_idxs(n_factors, False).shape[0]

        self._error_vars = np.full((n_variables, 1), np.nan)
        self._factor_covs = np.full((n_factors, n_factors), np.nan)

        self._loadings_free = get_free_parameter_idxs(loadings, eq=1)
        self._error_vars_free = merge_variance_covariance(self._error_vars)
        self._error_vars_free = get_free_parameter_idxs(self._error_vars_free, eq=-1)
        self._factor_covs_free = get_symmetric_lower_idxs(n_factors, False)
コード例 #3
0
def test_get_symmetric_lower_idxs_no_diag():

    expected = np.array([5, 10, 11, 15, 16, 17, 20, 21, 22, 23])

    output = get_symmetric_lower_idxs(5, diag=False)

    assert_array_equal(output, expected)
コード例 #4
0
def test_get_symmetric_lower_idxs():

    expected = np.array([0, 1, 2, 3, 4, 6, 7, 8, 9, 12, 13, 14, 18, 19, 24])

    output = get_symmetric_lower_idxs(5)

    assert_array_equal(output, expected)