Ejemplo n.º 1
0
    def _multivariate_ls_fit(self):
        wy, wx = self._wy, self._wx
        k = len(wx)
        if self.constraints is not None:
            cons = self.constraints
            xpx_full = blocked_inner_prod(wx, eye(len(wx)))
            xpy = []
            for i in range(k):
                xpy.append(wx[i].T @ wy[i])
            xpy = np.vstack(xpy)
            xpy = cons.t.T @ xpy - cons.t.T @ xpx_full @ cons.a.T
            xpx = cons.t.T @ xpx_full @ cons.t
            params_c = np.linalg.solve(xpx, xpy)
            params = cons.t @ params_c + cons.a.T
        else:
            xpx = blocked_inner_prod(wx, eye(len(wx)))
            xpy = []
            for i in range(k):
                xpy.append(wx[i].T @ wy[i])
            xpy = np.vstack(xpy)
            xpx, xpy = xpx, xpy
            params = solve(xpx, xpy)

        beta = params
        loc = 0
        eps = []
        for i in range(k):
            nb = wx[i].shape[1]
            b = beta[loc:loc + nb]
            eps.append(wy[i] - wx[i] @ b)
            loc += nb
        eps = hstack(eps)

        return beta, eps
Ejemplo n.º 2
0
    def _cov(self, gls):
        x = self._x
        eps = self._eps
        k = len(x)
        sigma = self.sigma
        weights = inv(sigma) if gls else eye(k)
        xpx = blocked_inner_prod(x, weights)

        weights = inv_matrix_sqrt(sigma) if gls else eye(k)
        bigx = blocked_diag_product(x, weights)
        nobs = eps.shape[0]
        e = eps.T.ravel()[:, None]
        bigxe = bigx * e
        m = bigx.shape[1]
        xeex = zeros((m, m))
        for i in range(nobs):
            xe = bigxe[i::nobs].sum(0)[None, :]
            xeex += xe.T @ xe

        if self._constraints is None:
            xpxi = inv(xpx)
            cov = xpxi @ xeex @ xpxi
        else:
            cons = self._constraints
            xpx = cons.t.T @ xpx @ cons.t
            xpxi = inv(xpx)
            xeex = cons.t.T @ xeex @ cons.t
            cov = cons.t @ (xpxi @ xeex @ xpxi) @ cons.t.T

        cov = (cov + cov.T) / 2
        return cov
Ejemplo n.º 3
0
    def weight_matrix(
        self,
        x: Sequence[NDArray],
        z: Sequence[NDArray],
        eps: NDArray,
        *,
        sigma: ndarray,
    ) -> NDArray:
        """
        Construct a GMM weight matrix for a model.

        Parameters
        ----------
        x : list[ndarray]
            List of containing model regressors for each equation in the system
        z : list[ndarray]
            List of containing instruments for each equation in the system
        eps : ndarray
            Model errors (nobs by neqn)
        sigma : ndarray, default None
            Fixed covariance of model errors. If None, estimated from eps.

        Returns
        -------
        ndarray
            Covariance of GMM moment conditions.
        """
        nobs = z[0].shape[0]
        w = blocked_inner_prod(z, sigma) / nobs
        return w
Ejemplo n.º 4
0
    def _multivariate_ls_fit(self):
        wy, wx = self._wy, self._wx
        k = len(wx)
        if self.constraints is not None:
            cons = self.constraints
            x = blocked_diag_product(wx, eye(len(wx)))
            y = np.vstack(wy)
            xt = x @ cons.t
            # TODO: Make more memory efficient
            # Replace with t.T @ xpx @ t
            xpx = xt.T @ xt
            # Replace with t.T @ xpy - t.T @ xpx @ a.T
            xpy = xt.T @ (y - x @ cons.a.T)
            paramsc = np.linalg.solve(xpx, xpy)
            params = cons.t @ paramsc + cons.a.T
        else:
            xpx = blocked_inner_prod(wx, eye(len(wx)))
            xpy = []
            for i in range(k):
                xpy.append(wx[i].T @ wy[i])
            xpy = np.vstack(xpy)
            xpx, xpy = xpx, xpy
            params = solve(xpx, xpy)

        beta = params
        loc = 0
        eps = []
        for i in range(k):
            nb = wx[i].shape[1]
            b = beta[loc:loc + nb]
            eps.append(wy[i] - wx[i] @ b)
            loc += nb
        eps = hstack(eps)

        return beta, eps
Ejemplo n.º 5
0
    def _omega(self) -> NDArray:
        z = self._z
        nobs = z[0].shape[0]
        sigma = self._sigma
        omega = blocked_inner_prod(z, sigma)
        omega /= nobs

        return omega
Ejemplo n.º 6
0
    def _mvreg_cov(self) -> NDArray:
        x = self._x

        xeex = blocked_inner_prod(x, self._sigma)
        xpx = blocked_inner_prod(self._x, eye(len(x)))

        if self._constraints is None:
            xpxi = inv(xpx)
            cov = xpxi @ xeex @ xpxi
        else:
            cons = self._constraints
            xpx = cons.t.T @ xpx @ cons.t
            xpxi = inv(xpx)
            xeex = cons.t.T @ xeex @ cons.t
            cov = cons.t @ (xpxi @ xeex @ xpxi) @ cons.t.T

        cov = (cov + cov.T) / 2
        return cov
Ejemplo n.º 7
0
    def _omega(self) -> Float64Array:
        z = self._z
        nobs = z[0].shape[0]
        sigma = self._sigma
        assert sigma is not None
        omega = blocked_inner_prod(z, sigma)
        omega /= nobs

        return omega
Ejemplo n.º 8
0
    def _gls_cov(self) -> NDArray:
        x = self._x
        sigma = self._sigma
        sigma_inv = inv(sigma)

        xpx = blocked_inner_prod(x, sigma_inv)
        # Handles case where sigma_inv is not inverse of full_sigma
        xeex = blocked_inner_prod(x, sigma_inv @ self._full_sigma @ sigma_inv)
        if self._constraints is None:
            xpxi = inv(xpx)
            cov = xpxi @ xeex @ xpxi
        else:
            cons = self._constraints
            xpx = cons.t.T @ xpx @ cons.t
            xpxi = inv(xpx)
            xeex = cons.t.T @ xeex @ cons.t
            cov = cons.t @ (xpxi @ xeex @ xpxi) @ cons.t.T

        cov = (cov + cov.T) / 2
        return cov
Ejemplo n.º 9
0
    def _gls_estimate(self, eps, nobs, total_cols, ci, full_cov, debiased):
        """Core estimation routine for iterative GLS"""
        wx, wy = self._wx, self._wy
        sigma = self._sigma
        if sigma is None:
            sigma = eps.T @ eps / nobs
            sigma *= self._sigma_scale(debiased)

        if not full_cov:
            sigma = diag(diag(sigma))
        sigma_inv = inv(sigma)

        k = len(wy)
        if self.constraints is not None:
            cons = self.constraints
            sigma_m12 = inv_matrix_sqrt(sigma)
            x = blocked_diag_product(wx, sigma_m12)
            y = blocked_column_product(wy, sigma_m12)
            xt = x @ cons.t
            xpx = xt.T @ xt
            xpy = xt.T @ (y - x @ cons.a.T)
            paramsc = solve(xpx, xpy)
            params = cons.t @ paramsc + cons.a.T
        else:
            xpx = blocked_inner_prod(wx, sigma_inv)
            xpy = zeros((total_cols, 1))
            for i in range(k):
                sy = zeros((nobs, 1))
                for j in range(k):
                    sy += sigma_inv[i, j] * wy[j]
                xpy[ci[i]:ci[i + 1]] = wx[i].T @ sy

            params = solve(xpx, xpy)

        beta = params

        loc = 0
        for j in range(k):
            _wx = wx[j]
            _wy = wy[j]
            kx = _wx.shape[1]
            eps[:, [j]] = _wy - _wx @ beta[loc:loc + kx]
            loc += kx

        return beta, eps, sigma
Ejemplo n.º 10
0
def test_inner_product(data):
    y, x, sigma = data
    efficient = blocked_inner_prod(x, sigma)
    nobs = x[0].shape[0]
    omega = np.kron(sigma, np.eye(nobs))
    k = len(x)
    bigx = []
    for i in range(k):
        row = []
        for j in range(k):
            if i == j:
                row.append(x[i])
            else:
                row.append(np.zeros((nobs, x[j].shape[1])))
        bigx.append(np.hstack(row))
    bigx = np.vstack(bigx)
    expected = bigx.T @ omega @ bigx
    assert_allclose(efficient, expected)
Ejemplo n.º 11
0
    def _cov(self, gls):
        x = self._x
        nobs = x[0].shape[0]
        k = len(x)
        sigma = self.sigma
        weights = inv(sigma) if gls else eye(k)
        xpx = blocked_inner_prod(x, weights) / nobs
        xeex = self._xeex()

        if self._constraints is None:
            xpxi = inv(xpx)
            cov = xpxi @ xeex @ xpxi
        else:
            cons = self._constraints
            xpx = cons.t.T @ xpx @ cons.t
            xpxi = inv(xpx)
            xeex = cons.t.T @ xeex @ cons.t
            cov = cons.t @ (xpxi @ xeex @ xpxi) @ cons.t.T

        cov = (cov + cov.T) / 2
        return cov / nobs
Ejemplo n.º 12
0
    def weight_matrix(self, x, z, eps, *, sigma=None):
        """
        Parameters
        ----------
        x : ndarray
            List of containing model regressors for each equation in the system
        z : ndarray
            List of containing instruments for each equation in the system
        eps : ndarray
            Model errors (nobs by neqn)
        sigma : ndarray
            Fixed covariance of model errors

        Returns
        -------
        weight : ndarray
            Covariance of GMM moment conditions.
        """
        nobs = z[0].shape[0]
        w = blocked_inner_prod(z, sigma) / nobs
        return w