예제 #1
0
def test_rv_linop_kroneckercov():
    """Create a random variable with linear operator mean and Kronecker product covariance."""
    def mv(v):
        return np.array([2 * v[0], 3 * v[1]])

    A = linear_operators.LinearOperator(shape=(2, 2), matvec=mv)
    V = linear_operators.Kronecker(A, A)
    probability.RandomVariable(distribution=probability.Normal(mean=A, cov=V))
예제 #2
0
    def _covariance_update(self, u, Ws):
        """Linear operator implementing the symmetric rank 2 covariance update (-= Ws u^T)."""
        def mv(x):
            return u @ (Ws.T @ x)

        def mm(X):
            return u @ (Ws.T @ X)

        return linear_operators.LinearOperator(shape=self.A_mean.shape,
                                               matvec=mv,
                                               matmat=mm)
예제 #3
0
    def _mean_update(self, u, v):
        """Linear operator implementing the symmetric rank 2 mean update (+= uv' + vu')."""
        def mv(x):
            return u @ (v.T @ x) + v @ (u.T @ x)

        def mm(X):
            return u @ (v.T @ X) + v @ (u.T @ X)

        return linear_operators.LinearOperator(shape=self.A_mean.shape,
                                               matvec=mv,
                                               matmat=mm)
예제 #4
0
    def _create_output_randvars(self, S=None, Y=None, Phi=None, Psi=None):
        """Return output random variables x, A, Ainv from their means and covariances."""

        _A_covfactor = self.A_covfactor
        _Ainv_covfactor = self.Ainv_covfactor

        # Set degrees of freedom based on uncertainty calibration in unexplored space
        if Phi is not None:

            def _mv(x):
                def _I_S_fun(x):
                    return x - S @ np.linalg.solve(S.T @ S, S.T @ x)

                return _I_S_fun(Phi @ _I_S_fun(x))

            I_S_Phi_I_S_op = linear_operators.LinearOperator(
                shape=self.A.shape, matvec=_mv)
            _A_covfactor = self.A_covfactor + I_S_Phi_I_S_op

        if Psi is not None:

            def _mv(x):
                def _I_Y_fun(x):
                    return x - Y @ np.linalg.solve(Y.T @ Y, Y.T @ x)

                return _I_Y_fun(Psi @ _I_Y_fun(x))

            I_Y_Psi_I_Y_op = linear_operators.LinearOperator(
                shape=self.A.shape, matvec=_mv)
            _Ainv_covfactor = self.Ainv_covfactor + I_Y_Psi_I_Y_op

        # Create output random variables
        A = probability.RandomVariable(
            shape=self.A_mean.shape,
            dtype=float,
            distribution=probability.Normal(
                mean=self.A_mean,
                cov=linear_operators.SymmetricKronecker(A=_A_covfactor)))
        cov_Ainv = linear_operators.SymmetricKronecker(A=_Ainv_covfactor)
        Ainv = probability.RandomVariable(shape=self.Ainv_mean.shape,
                                          dtype=float,
                                          distribution=probability.Normal(
                                              mean=self.Ainv_mean,
                                              cov=cov_Ainv))
        # Induced distribution on x via Ainv
        # Exp = x = A^-1 b, Cov = 1/2 (W b'Wb + Wbb'W)
        Wb = _Ainv_covfactor @ self.b
        bWb = np.squeeze(Wb.T @ self.b)

        def _mv(x):
            return 0.5 * (bWb * _Ainv_covfactor @ x + Wb @ (Wb.T @ x))

        cov_op = linear_operators.LinearOperator(
            shape=np.shape(_Ainv_covfactor),
            dtype=float,
            matvec=_mv,
            matmat=_mv)

        x = probability.RandomVariable(shape=(self.A_mean.shape[0], ),
                                       dtype=float,
                                       distribution=probability.Normal(
                                           mean=self.x.ravel(), cov=cov_op))
        return x, A, Ainv
예제 #5
0
def test_linop_construction():
    """Create linear operators via various construction methods."""

    # Custom linear operator
    linear_operators.LinearOperator(shape=(2, 2), matvec=mv)
예제 #6
0
    # Custom linear operator
    linear_operators.LinearOperator(shape=(2, 2), matvec=mv)

    # Scipy linear operator
    # scipy_linop = scipy.sparse.linalg.LinearOperator(shape=(2, 2), matvec=mv)
    # linear_operators.LinearOperator(scipy_linop)


# Linear operator arithmetic
np.random.seed(42)
scalars = [0, int(1), .1, -4.2, np.nan, np.inf]
arrays = [np.random.normal(size=[5, 4]), np.array([[3, 4],
                                                   [1, 5]])]
ops = [linear_operators.MatrixMult(np.array([[-1.5, 3],
                                             [0, -230]])),
       linear_operators.LinearOperator(shape=(2, 2), matvec=mv),
       linear_operators.Identity(shape=4),
       linear_operators.Kronecker(A=linear_operators.MatrixMult(np.array([[2, -3.5],
                                                                          [12, 6.5]])),
                                  B=linear_operators.Identity(shape=2)),
       linear_operators.SymmetricKronecker(A=linear_operators.MatrixMult(np.array([[1, -2],
                                                                                   [-2.2, 5]])),
                                           B=linear_operators.MatrixMult(np.array([[1, -3],
                                                                                   [0, -.5]])))]


@pytest.mark.parametrize("A, alpha", list(itertools.product(arrays, scalars)))
def test_scalar_mult(A, alpha):
    """Matrix linear operator multiplication with scalars."""
    Aop = linear_operators.MatrixMult(A)