def test_mpi_schur_complement(self):
        rank_by_index = list()
        for ndx in range(3):
            for _rank in range(size):
                if (ndx - _rank) % size == 0:
                    rank_by_index.append(_rank)
        rank_by_index.append(-1)

        A = MPIBlockMatrix(nbrows=4,
                           nbcols=4,
                           rank_ownership=[
                               rank_by_index, rank_by_index, rank_by_index,
                               rank_by_index
                           ],
                           mpi_comm=comm)
        if rank_by_index[0] == rank:
            A.set_block(
                0, 0, coo_matrix(np.array([[1, 1], [0, 1]], dtype=np.double)))
        if rank_by_index[1] == rank:
            A.set_block(
                1, 1, coo_matrix(np.array([[1, 0], [0, 1]], dtype=np.double)))
        if rank_by_index[2] == rank:
            A.set_block(
                2, 2, coo_matrix(np.array([[1, 0], [1, 1]], dtype=np.double)))
        A.set_block(3, 3,
                    coo_matrix(np.array([[0, 0], [0, 1]], dtype=np.double)))
        if rank_by_index[0] == rank:
            A.set_block(
                3, 0, coo_matrix(np.array([[0, -1], [0, 0]], dtype=np.double)))
        if rank_by_index[1] == rank:
            A.set_block(
                3, 1, coo_matrix(np.array([[-1, 0], [0, -1]],
                                          dtype=np.double)))
        if rank_by_index[2] == rank:
            A.set_block(
                3, 2, coo_matrix(np.array([[0, 0], [-1, 0]], dtype=np.double)))
        A.broadcast_block_sizes()

        local_A = BlockMatrix(4, 4)
        local_A.set_block(
            0, 0, coo_matrix(np.array([[1, 1], [0, 1]], dtype=np.double)))
        local_A.set_block(
            1, 1, coo_matrix(np.array([[1, 0], [0, 1]], dtype=np.double)))
        local_A.set_block(
            2, 2, coo_matrix(np.array([[1, 0], [1, 1]], dtype=np.double)))
        local_A.set_block(
            3, 3, coo_matrix(np.array([[0, 0], [0, 1]], dtype=np.double)))
        local_A.set_block(
            3, 0, coo_matrix(np.array([[0, -1], [0, 0]], dtype=np.double)))
        local_A.set_block(
            3, 1, coo_matrix(np.array([[-1, 0], [0, -1]], dtype=np.double)))
        local_A.set_block(
            3, 2, coo_matrix(np.array([[0, 0], [-1, 0]], dtype=np.double)))
        local_A.set_block(0, 3, local_A.get_block(3, 0).transpose(copy=True))
        local_A.set_block(1, 3, local_A.get_block(3, 1).transpose(copy=True))
        local_A.set_block(2, 3, local_A.get_block(3, 2).transpose(copy=True))

        rhs = MPIBlockVector(nblocks=4,
                             rank_owner=rank_by_index,
                             mpi_comm=comm)
        if rank_by_index[0] == rank:
            rhs.set_block(0, np.array([1, 0], dtype=np.double))
        if rank_by_index[1] == rank:
            rhs.set_block(1, np.array([0, 0], dtype=np.double))
        if rank_by_index[2] == rank:
            rhs.set_block(2, np.array([0, 1], dtype=np.double))
        rhs.set_block(3, np.array([1, 1], dtype=np.double))
        rhs.broadcast_block_sizes()

        local_rhs = BlockVector(4)
        local_rhs.set_block(0, np.array([1, 0], dtype=np.double))
        local_rhs.set_block(1, np.array([0, 0], dtype=np.double))
        local_rhs.set_block(2, np.array([0, 1], dtype=np.double))
        local_rhs.set_block(3, np.array([1, 1], dtype=np.double))

        x1 = np.linalg.solve(local_A.toarray(), local_rhs.flatten())

        solver_class = parapint.linalg.MPISchurComplementLinearSolver
        sc_solver = solver_class(
            subproblem_solvers={
                ndx: ScipyInterface(compute_inertia=True)
                for ndx in range(3)
            },
            schur_complement_solver=ScipyInterface(compute_inertia=True))
        sc_solver.do_symbolic_factorization(A)
        sc_solver.do_numeric_factorization(A)
        x2 = sc_solver.do_back_solve(rhs)

        self.assertTrue(np.allclose(x1, x2.make_local_copy().flatten()))

        inertia1 = sc_solver.get_inertia()
        eig = np.linalg.eigvals(local_A.toarray())
        pos = np.count_nonzero(eig > 0)
        neg = np.count_nonzero(eig < 0)
        zero = np.count_nonzero(eig == 0)
        inertia2 = (pos, neg, zero)
        self.assertEqual(inertia1, inertia2)

        sc_solver.do_numeric_factorization(A)
        x2 = sc_solver.do_back_solve(rhs)
        self.assertTrue(np.allclose(x1, x2.make_local_copy().flatten()))
Ejemplo n.º 2
0
nd = len(d_vars)
Ad = nlp.extract_submatrix_jacobian(pyomo_variables=d_vars,
                                    pyomo_constraints=[m.const1])
xd_indices = nlp.get_primal_indices(d_vars)
b_vars = [m.x1]
nb= len(b_vars)
Ab = nlp.extract_submatrix_jacobian(pyomo_variables=b_vars,
                                    pyomo_constraints=[m.const1])
xb_indices = nlp.get_primal_indices(b_vars)

# null space matrix
Z = BlockMatrix(2,1)
Z[0,0] = spsolve(-Ab.tocsc(), Ad.tocsc())
Z[1,0] = identity(nd)
Z_sparse = Z.tocsr()
print("Null space matrix:\n",Z.toarray())

# computing reduced hessian with null space matriz
reduced_hessian = Z_sparse.T * H * Z_sparse
print("Reduced hessian matrix:\n",reduced_hessian.toarray())
print("Inverse reduced hessian:\n", inv(reduced_hessian).toarray())

# computing the reduced hessian with back solves
kkt_matrix = kkt.tocsc()
nvars = kkt_matrix.shape[1]
row = xd_indices
col = np.arange(nd)
data = np.ones(nd)

rhs = coo_matrix((data, (row, col)), shape=(nvars, nd))
backsolves = spsolve(kkt_matrix, rhs.tocsc())
Ejemplo n.º 3
0
class TestBlockMatrix(unittest.TestCase):
    def setUp(self):
        row = np.array([0, 3, 1, 2, 3, 0])
        col = np.array([0, 0, 1, 2, 3, 3])
        data = np.array([2., 1, 3, 4, 5, 1])
        m = coo_matrix((data, (row, col)), shape=(4, 4))

        self.block_m = m

        bm = BlockMatrix(2, 2)
        bm.name = 'basic_matrix'
        bm.set_block(0, 0, m.copy())
        bm.set_block(1, 1, m.copy())
        bm.set_block(0, 1, m.copy())
        self.basic_m = bm
        self.dense = np.zeros((8, 8))
        self.dense[0:4, 0:4] = m.toarray()
        self.dense[0:4, 4:8] = m.toarray()
        self.dense[4:8, 4:8] = m.toarray()

        self.composed_m = BlockMatrix(2, 2)
        self.composed_m.set_block(0, 0, self.block_m.copy())
        self.composed_m.set_block(1, 1, self.basic_m.copy())

    def test_name(self):
        self.assertEqual(self.basic_m.name, 'basic_matrix')
        self.basic_m.name = 'hola'
        self.assertEqual(self.basic_m.name, 'hola')

    def test_bshape(self):
        self.assertEqual(self.basic_m.bshape, (2, 2))

    def test_shape(self):
        shape = (self.block_m.shape[0] * 2, self.block_m.shape[1] * 2)
        self.assertEqual(self.basic_m.shape, shape)

    def test_tocoo(self):
        block = self.block_m
        m = self.basic_m
        scipy_mat = bmat([[block, block], [None, block]], format='coo')
        dinopy_mat = m.tocoo()
        drow = np.sort(dinopy_mat.row)
        dcol = np.sort(dinopy_mat.col)
        ddata = np.sort(dinopy_mat.data)
        srow = np.sort(scipy_mat.row)
        scol = np.sort(scipy_mat.col)
        sdata = np.sort(scipy_mat.data)
        self.assertListEqual(drow.tolist(), srow.tolist())
        self.assertListEqual(dcol.tolist(), scol.tolist())
        self.assertListEqual(ddata.tolist(), sdata.tolist())

    def test_tocsr(self):

        block = self.block_m
        m = self.basic_m
        scipy_mat = bmat([[block, block], [None, block]], format='csr')
        dinopy_mat = m.tocsr()
        dindices = np.sort(dinopy_mat.indices)
        dindptr = np.sort(dinopy_mat.indptr)
        ddata = np.sort(dinopy_mat.data)
        sindices = np.sort(scipy_mat.indices)
        sindptr = np.sort(scipy_mat.indptr)
        sdata = np.sort(scipy_mat.data)
        self.assertListEqual(dindices.tolist(), sindices.tolist())
        self.assertListEqual(dindptr.tolist(), sindptr.tolist())
        self.assertListEqual(ddata.tolist(), sdata.tolist())

    def test_tocsc(self):
        block = self.block_m
        m = self.basic_m
        scipy_mat = bmat([[block, block], [None, block]], format='csc')
        dinopy_mat = m.tocsc()
        dindices = np.sort(dinopy_mat.indices)
        dindptr = np.sort(dinopy_mat.indptr)
        ddata = np.sort(dinopy_mat.data)
        sindices = np.sort(scipy_mat.indices)
        sindptr = np.sort(scipy_mat.indptr)
        sdata = np.sort(scipy_mat.data)
        self.assertListEqual(dindices.tolist(), sindices.tolist())
        self.assertListEqual(dindptr.tolist(), sindptr.tolist())
        self.assertListEqual(ddata.tolist(), sdata.tolist())

    def test_multiply(self):

        # check scalar multiplication
        block = self.block_m
        m = self.basic_m * 5.0
        scipy_mat = bmat([[block, block], [None, block]], format='coo')
        mulscipy_mat = scipy_mat * 5.0
        dinopy_mat = m.tocoo()
        drow = np.sort(dinopy_mat.row)
        dcol = np.sort(dinopy_mat.col)
        ddata = np.sort(dinopy_mat.data)
        srow = np.sort(mulscipy_mat.row)
        scol = np.sort(mulscipy_mat.col)
        sdata = np.sort(mulscipy_mat.data)
        self.assertListEqual(drow.tolist(), srow.tolist())
        self.assertListEqual(dcol.tolist(), scol.tolist())
        self.assertListEqual(ddata.tolist(), sdata.tolist())

        m = 5.0 * self.basic_m
        dinopy_mat = m.tocoo()
        drow = np.sort(dinopy_mat.row)
        dcol = np.sort(dinopy_mat.col)
        ddata = np.sort(dinopy_mat.data)
        self.assertListEqual(drow.tolist(), srow.tolist())
        self.assertListEqual(dcol.tolist(), scol.tolist())
        self.assertListEqual(ddata.tolist(), sdata.tolist())

        # check dot product with block vector
        block = self.block_m
        m = self.basic_m
        scipy_mat = bmat([[block, block], [None, block]], format='coo')
        x = BlockVector(2)
        x.set_block(0, np.ones(block.shape[1], dtype=np.float64))
        x.set_block(1, np.ones(block.shape[1], dtype=np.float64))

        res_scipy = scipy_mat.dot(x.flatten())
        res_dinopy = m * x
        res_dinopy_flat = m * x.flatten()

        self.assertListEqual(res_dinopy.tolist(), res_scipy.tolist())
        self.assertListEqual(res_dinopy_flat.tolist(), res_scipy.tolist())

        dense_mat = dinopy_mat.toarray()
        self.basic_m *= 5.0
        self.assertTrue(np.allclose(dense_mat, self.basic_m.toarray()))

    def test_mul_sparse_matrix(self):
        m = self.basic_m

        flat_prod = m.tocoo() * m.tocoo()
        prod = m * m

        self.assertIsInstance(prod, BlockMatrix)
        self.assertTrue(np.allclose(flat_prod.toarray(), prod.toarray()))

        m2 = m.copy_structure()
        ones = np.ones(m.shape)
        m2.copyfrom(ones)
        flat_prod = m.tocoo() * m2.tocoo()
        prod = m * m2

        self.assertIsInstance(prod, BlockMatrix)
        self.assertTrue(np.allclose(flat_prod.toarray(), prod.toarray()))

    def test_getitem(self):

        m = BlockMatrix(3, 3)
        for i in range(3):
            for j in range(3):
                self.assertIsNone(m.get_block(i, j))

        m.set_block(0, 1, self.block_m)
        self.assertEqual(m.get_block(0, 1).shape, self.block_m.shape)

    def test_setitem(self):

        m = BlockMatrix(2, 2)
        m.set_block(0, 1, self.block_m)
        self.assertFalse(m.is_empty_block(0, 1))
        self.assertEqual(m._brow_lengths[0], self.block_m.shape[0])
        self.assertEqual(m._bcol_lengths[1], self.block_m.shape[1])
        self.assertEqual(m.get_block(0, 1).shape, self.block_m.shape)

    def test_coo_data(self):
        m = self.basic_m.tocoo()
        data = self.basic_m.coo_data()
        self.assertListEqual(m.data.tolist(), data.tolist())

    # ToDo: add tests for block matrices with block matrices in it
    # ToDo: add tests for matrices with zeros in the diagonal
    # ToDo: add tests for block matrices with coo and csc matrices

    def test_nnz(self):
        self.assertEqual(self.block_m.nnz * 3, self.basic_m.nnz)

    def test_block_shapes(self):
        shapes = self.basic_m.block_shapes()
        for i in range(self.basic_m.bshape[0]):
            for j in range(self.basic_m.bshape[1]):
                self.assertEqual(shapes[i][j], self.block_m.shape)

    def test_dot(self):
        A_dense = self.basic_m.toarray()
        A_block = self.basic_m
        x = np.ones(A_dense.shape[1])
        block_x = BlockVector(2)
        block_x.set_block(0, np.ones(self.block_m.shape[1]))
        block_x.set_block(1, np.ones(self.block_m.shape[1]))
        flat_res = A_block.dot(x).flatten()
        block_res = A_block.dot(block_x)
        self.assertTrue(np.allclose(A_dense.dot(x), flat_res))
        self.assertTrue(np.allclose(A_dense.dot(x), block_res.flatten()))
        self.assertEqual(block_res.bshape[0], 2)

        m = BlockMatrix(2, 2)
        sub_m = np.array([[1, 0], [0, 1]])
        sub_m = coo_matrix(sub_m)
        m.set_block(0, 1, sub_m.copy())
        m.set_block(1, 0, sub_m.copy())
        x = np.arange(4)
        res = m * x
        self.assertTrue(np.allclose(res.flatten(), np.array([2, 3, 0, 1])))

    def test_reset_brow(self):
        self.basic_m.reset_brow(0)
        for j in range(self.basic_m.bshape[1]):
            self.assertIsNone(self.basic_m.get_block(0, j))

    def test_reset_bcol(self):
        self.basic_m.reset_bcol(0)
        for j in range(self.basic_m.bshape[0]):
            self.assertIsNone(self.basic_m.get_block(j, 0))

    def test_to_scipy(self):

        block = self.block_m
        m = self.basic_m
        scipy_mat = bmat([[block, block], [None, block]], format='coo')
        dinopy_mat = m.tocoo()
        drow = np.sort(dinopy_mat.row)
        dcol = np.sort(dinopy_mat.col)
        ddata = np.sort(dinopy_mat.data)
        srow = np.sort(scipy_mat.row)
        scol = np.sort(scipy_mat.col)
        sdata = np.sort(scipy_mat.data)
        self.assertListEqual(drow.tolist(), srow.tolist())
        self.assertListEqual(dcol.tolist(), scol.tolist())
        self.assertListEqual(ddata.tolist(), sdata.tolist())

    def test_has_undefined_row_sizes(self):
        self.assertFalse(self.basic_m.has_undefined_row_sizes())

    def test_has_undefined_col_sizes(self):
        self.assertFalse(self.basic_m.has_undefined_col_sizes())

    def test_transpose(self):

        A_dense = self.basic_m.toarray()
        A_block = self.basic_m
        A_dense_t = A_dense.transpose()
        A_block_t = A_block.transpose()
        self.assertTrue(np.allclose(A_dense_t, A_block_t.toarray()))

        A_dense = self.composed_m.toarray()
        A_block = self.composed_m
        A_dense_t = A_dense.transpose()
        A_block_t = A_block.transpose()
        self.assertTrue(np.allclose(A_dense_t, A_block_t.toarray()))

    def test_repr(self):
        self.assertEqual(len(self.basic_m.__repr__()), 17)

    def test_set_item(self):

        self.basic_m.set_block(1, 0, None)
        self.assertIsNone(self.basic_m.get_block(1, 0))
        self.basic_m.set_block(1, 1, None)
        self.assertIsNone(self.basic_m.get_block(1, 1))
        self.assertEqual(self.basic_m._brow_lengths[1], self.block_m.shape[0])
        self.basic_m.set_block(1, 1, self.block_m)
        self.assertEqual(self.basic_m._brow_lengths[1], self.block_m.shape[0])

    def test_add(self):

        A_dense = self.basic_m.toarray()
        A_block = self.basic_m

        aa = A_dense + A_dense
        mm = A_block + A_block

        self.assertTrue(np.allclose(aa, mm.toarray()))

        mm = A_block.__radd__(A_block)
        self.assertTrue(np.allclose(aa, mm.toarray()))

        r = A_block + A_block.tocoo()
        dense_res = A_block.toarray() + A_block.toarray()
        self.assertIsInstance(r, BlockMatrix)
        self.assertTrue(np.allclose(r.toarray(), dense_res))

        r = A_block.tocoo() + A_block
        dense_res = A_block.toarray() + A_block.toarray()
        #self.assertIsInstance(r, BlockMatrix)
        self.assertTrue(np.allclose(r.toarray(), dense_res))

        r = A_block + 2 * A_block.tocoo()
        dense_res = A_block.toarray() + 2 * A_block.toarray()
        self.assertIsInstance(r, BlockMatrix)
        self.assertTrue(np.allclose(r.toarray(), dense_res))

        r = 2 * A_block.tocoo() + A_block
        dense_res = 2 * A_block.toarray() + A_block.toarray()
        #self.assertIsInstance(r, BlockMatrix)
        self.assertTrue(np.allclose(r.toarray(), dense_res))

        r = A_block.T + A_block.tocoo()
        dense_res = A_block.toarray().T + A_block.toarray()
        self.assertIsInstance(r, BlockMatrix)
        self.assertTrue(np.allclose(r.toarray(), dense_res))

        with self.assertRaises(Exception) as context:
            mm = A_block.__radd__(A_block.toarray())

        with self.assertRaises(Exception) as context:
            mm = A_block + A_block.toarray()

        with self.assertRaises(Exception) as context:
            mm = A_block + 1.0

    def test_add_copy(self):
        """
        The purpose of this test is to ensure that copying happens correctly when block matrices are added.
        For example, when adding

        [A  B   +  [D  0
         0  C]      E  F]

        we want to make sure that E and B both get copied in the result rather than just placed in the result.
        """
        bm = self.basic_m.copy()
        bmT = bm.transpose()
        res = bm + bmT
        self.assertIsNot(res.get_block(1, 0), bmT.get_block(1, 0))
        self.assertIsNot(res.get_block(0, 1), bm.get_block(0, 1))
        self.assertTrue(
            np.allclose(res.toarray(), self.dense + self.dense.transpose()))

    def test_sub(self):

        A_dense = self.basic_m.toarray()
        A_block = self.basic_m
        A_block2 = 2 * self.basic_m

        aa = A_dense - A_dense
        mm = A_block - A_block

        self.assertTrue(np.allclose(aa, mm.toarray()))

        mm = A_block2 - A_block.tocoo()
        self.assertTrue(np.allclose(A_block.toarray(), mm.toarray()))

        mm = A_block2.tocoo() - A_block
        self.assertTrue(np.allclose(A_block.toarray(), mm.toarray()))

        mm = A_block2.T - A_block.tocoo()
        dense_r = A_block2.toarray().T - A_block.toarray()
        self.assertTrue(np.allclose(dense_r, mm.toarray()))

        with self.assertRaises(Exception) as context:
            mm = A_block - A_block.toarray()

        with self.assertRaises(Exception) as context:
            mm = A_block - 1.0

        with self.assertRaises(Exception) as context:
            mm = 1.0 - A_block

    def test_sub_copy(self):
        """
        The purpose of this test is to ensure that copying happens correctly when block matrices are subtracted.
        For example, when subtracting

        [A  B   -  [D  0
         0  C]      E  F]

        we want to make sure that E and B both get copied in the result rather than just placed in the result.
        """
        bm = self.basic_m.copy()
        bmT = 2 * bm.transpose()
        res = bm - bmT
        self.assertIsNot(res.get_block(1, 0), bmT.get_block(1, 0))
        self.assertIsNot(res.get_block(0, 1), bm.get_block(0, 1))
        self.assertTrue(
            np.allclose(res.toarray(),
                        self.dense - 2 * self.dense.transpose()))

    def test_neg(self):

        A_dense = self.basic_m.toarray()
        A_block = self.basic_m

        aa = -A_dense
        mm = -A_block

        self.assertTrue(np.allclose(aa, mm.toarray()))

    def test_copyfrom(self):
        bm0 = self.basic_m.copy()
        bm = bm0.copy_structure()
        self.assertFalse(np.allclose(bm.toarray(), self.dense))
        bm.copyfrom(bm0.tocoo())
        self.assertTrue(np.allclose(bm.toarray(), self.dense))

        flat = np.ones((8, 8))
        bm.copyfrom(flat)
        self.assertTrue(np.allclose(flat, bm.toarray()))

        bm.copyfrom(bm0)
        self.assertTrue(np.allclose(bm.toarray(), self.dense))

        bm.get_block(0, 0).data.fill(1.0)
        self.assertAlmostEqual(bm0.toarray()[0, 0],
                               2)  # this tests that a deep copy was done
        self.assertAlmostEqual(bm.toarray()[0, 0], 1)

        bm.copyfrom(bm0, deep=False)
        bm.get_block(0, 0).data.fill(1.0)
        self.assertAlmostEqual(bm0.toarray()[0, 0],
                               1)  # this tests that a shallow copy was done
        self.assertAlmostEqual(bm.toarray()[0, 0], 1)

    def test_copyto(self):
        bm0 = self.basic_m.copy()
        coo = bm0.tocoo()
        coo.data.fill(1.0)
        csr = coo.tocsr()
        csc = coo.tocsc()
        self.assertFalse(np.allclose(coo.toarray(), self.dense))
        self.assertFalse(np.allclose(csr.toarray(), self.dense))
        self.assertFalse(np.allclose(csc.toarray(), self.dense))
        bm0.copyto(coo)
        bm0.copyto(csr)
        bm0.copyto(csc)
        self.assertTrue(np.allclose(coo.toarray(), self.dense))
        self.assertTrue(np.allclose(csr.toarray(), self.dense))
        self.assertTrue(np.allclose(csc.toarray(), self.dense))

        flat = np.ones((8, 8))
        bm0.copyto(flat)
        self.assertTrue(np.allclose(flat, self.dense))

        bm = bm0.copy_structure()
        bm0.copyto(bm)
        self.assertTrue(np.allclose(bm.toarray(), self.dense))

        bm.get_block(0, 0).data.fill(1.0)
        self.assertAlmostEqual(bm0.toarray()[0, 0],
                               2)  # this tests that a deep copy was done
        self.assertAlmostEqual(bm.toarray()[0, 0], 1)

        bm0.copyto(bm, deep=False)
        bm.get_block(0, 0).data.fill(1.0)
        self.assertAlmostEqual(bm0.toarray()[0, 0],
                               1)  # this tests that a shallow copy was done
        self.assertAlmostEqual(bm.toarray()[0, 0], 1)

    def test_copy(self):
        clone = self.basic_m.copy()
        self.assertTrue(np.allclose(clone.toarray(), self.dense))
        clone.get_block(0, 0).data.fill(1)
        self.assertAlmostEqual(clone.toarray()[0, 0], 1)
        self.assertAlmostEqual(self.basic_m.toarray()[0, 0], 2)

        bm = self.basic_m.copy()
        clone = bm.copy(deep=False)
        self.assertTrue(np.allclose(clone.toarray(), self.dense))
        clone.get_block(0, 0).data.fill(1)
        self.assertAlmostEqual(clone.toarray()[0, 0], 1)
        self.assertAlmostEqual(bm.toarray()[0, 0], 1)

    def test_iadd(self):

        A_dense = self.basic_m.toarray()
        A_block = self.basic_m.copy()
        A_dense += A_dense
        A_block += A_block

        self.assertTrue(np.allclose(A_block.toarray(), A_dense))

        A_dense = self.basic_m.toarray()
        A_block = self.basic_m.copy()
        A_dense += A_dense
        A_block += A_block.tocoo()

        self.assertTrue(np.allclose(A_block.toarray(), A_dense))

        A_dense = self.basic_m.toarray()
        A_block = self.basic_m.copy()
        A_block += 2 * A_block.tocoo()

        self.assertTrue(np.allclose(A_block.toarray(), 3 * A_dense))

        with self.assertRaises(Exception) as context:
            A_block += 1.0

    def test_isub(self):

        A_dense = self.basic_m.toarray()
        A_block = self.basic_m
        A_dense -= A_dense
        A_block -= A_block

        self.assertTrue(np.allclose(A_block.toarray(), A_dense))

        A_dense = self.basic_m.toarray()
        A_block = self.basic_m
        A_dense -= A_dense
        A_block -= A_block.tocoo()

        self.assertTrue(np.allclose(A_block.toarray(), A_dense))

        A_dense = self.basic_m.toarray()
        A_block = self.basic_m.copy()
        A_block -= 2 * A_block.tocoo()

        self.assertTrue(np.allclose(A_block.toarray(), -A_dense))

        with self.assertRaises(Exception) as context:
            A_block -= 1.0

    def test_imul(self):

        A_dense = self.basic_m.toarray()
        A_block = self.basic_m
        print(A_dense)
        print(A_block.toarray())
        A_dense *= 3
        print(A_dense)
        print(A_block.toarray())
        A_block *= 3.
        print(A_dense)
        print(A_block.toarray())

        self.assertTrue(np.allclose(A_block.toarray(), A_dense))

        with self.assertRaises(Exception) as context:
            A_block *= A_block

        with self.assertRaises(Exception) as context:
            A_block *= A_block.tocoo()

        with self.assertRaises(Exception) as context:
            A_block *= A_block.toarray()

    def test_itruediv(self):

        A_dense = self.basic_m.toarray()
        A_block = self.basic_m.copy()
        A_dense /= 3
        A_block /= 3.

        self.assertTrue(np.allclose(A_block.toarray(), A_dense))

        with self.assertRaises(Exception) as context:
            A_block /= A_block

        with self.assertRaises(Exception) as context:
            A_block /= A_block.tocoo()

        with self.assertRaises(Exception) as context:
            A_block /= A_block.toarray()

    def test_truediv(self):

        A_dense = self.basic_m.toarray()
        A_block = self.basic_m
        B_block = A_block / 3.
        self.assertTrue(np.allclose(B_block.toarray(), A_dense / 3.))

        with self.assertRaises(Exception) as context:
            b = A_block / A_block

        with self.assertRaises(Exception) as context:
            b = A_block / A_block.tocoo()

        with self.assertRaises(Exception) as context:
            b = A_block / A_block.toarray()

        with self.assertRaises(Exception) as context:
            B_block = 3. / A_block

    def test_eq(self):

        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            A_flat = self.basic_m.tocoo()
            A_block = self.basic_m

            A_bool_flat = A_flat == 2.0
            A_bool_block = A_block == 2.0

            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

            A_bool_flat = A_flat == A_flat
            A_bool_block = A_block == A_block

            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

            A_bool_flat = 2.0 != A_flat
            A_bool_block = 2.0 != A_block
            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

    def test_ne(self):

        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            A_flat = self.basic_m.tocoo()
            A_block = self.basic_m

            A_bool_flat = A_flat != 2.0
            A_bool_block = A_block != 2.0
            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

            A_bool_flat = 2.0 != A_flat
            A_bool_block = 2.0 != A_block
            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

            A_bool_flat = A_flat != A_flat
            A_bool_block = A_block != A_block

            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

    def test_le(self):

        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            A_flat = self.basic_m.tocoo()
            A_block = self.basic_m

            A_bool_flat = A_flat <= 2.0
            A_bool_block = A_block <= 2.0
            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

            # A_bool_flat = 2.0 <= A_flat
            # A_bool_block = 2.0 <= A_block
            # self.assertTrue(np.allclose(A_bool_flat.toarray(),
            #                             A_bool_block.toarray()))

            A_bool_flat = A_flat <= A_flat
            A_bool_block = A_block <= A_block

            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

            A_bool_flat = A_flat <= 2 * A_flat
            A_bool_block = A_block <= 2 * A_block

            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

            A_bool_flat = 2.0 >= A_flat
            A_bool_block = 2.0 >= A_block
            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

    def test_lt(self):

        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            A_flat = self.basic_m.tocoo()
            A_block = self.basic_m

            A_bool_flat = A_flat < 2.0
            A_bool_block = A_block < 2.0

            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

            # A_bool_flat = 2.0 <= A_flat
            # A_bool_block = 2.0 <= A_block
            # self.assertTrue(np.allclose(A_bool_flat.toarray(),
            #                             A_bool_block.toarray()))

            A_bool_flat = A_flat < A_flat
            A_bool_block = A_block < A_block

            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

            A_bool_flat = A_flat < 2 * A_flat
            A_bool_block = A_block < 2 * A_block

            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

            A_bool_flat = 2.0 > A_flat
            A_bool_block = 2.0 > A_block
            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

    def test_ge(self):

        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            A_flat = self.basic_m.tocoo()
            A_block = self.basic_m

            A_bool_flat = A_flat >= 2.0
            A_bool_block = A_block >= 2.0
            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

            A_bool_flat = 2.0 <= A_flat
            A_bool_block = 2.0 <= A_block
            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

            A_bool_flat = A_flat >= A_flat
            A_bool_block = A_block >= A_block

            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

            A_bool_flat = A_flat >= 0.5 * A_flat
            A_bool_block = A_block >= 0.5 * A_block

            self.assertTrue(
                np.allclose(A_bool_flat.toarray(), A_bool_block.toarray()))

    def test_gt(self):

        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            A = self.basic_m.copy()
            B = 2 * A.transpose()

            res = A > B
            expected = A.toarray() > B.toarray()
            self.assertTrue(np.allclose(res.toarray(), expected))

    def test_abs(self):

        row = np.array([0, 3, 1, 2, 3, 0])
        col = np.array([0, 0, 1, 2, 3, 3])
        data = -1.0 * np.array([2., 1, 3, 4, 5, 1])
        m = coo_matrix((data, (row, col)), shape=(4, 4))

        self.block_m = m

        bm = BlockMatrix(2, 2)
        bm.set_block(0, 0, m)
        bm.set_block(1, 1, m)
        bm.set_block(0, 1, m)

        abs_flat = abs(bm.tocoo())
        abs_mat = abs(bm)

        self.assertIsInstance(abs_mat, BlockMatrix)
        self.assertTrue(np.allclose(abs_flat.toarray(), abs_mat.toarray()))

    def test_getcol(self):

        m = self.basic_m

        flat_mat = m.tocoo()
        flat_col = flat_mat.getcol(2)
        block_col = m.getcol(2)
        self.assertTrue(
            np.allclose(flat_col.toarray().flatten(), block_col.flatten()))

        flat_col = flat_mat.getcol(4)
        block_col = m.getcol(4)
        self.assertTrue(
            np.allclose(flat_col.toarray().flatten(), block_col.flatten()))

        flat_col = flat_mat.getcol(6)
        block_col = m.getcol(6)
        self.assertTrue(
            np.allclose(flat_col.toarray().flatten(), block_col.flatten()))

    def test_getrow(self):

        m = self.basic_m

        flat_mat = m.tocoo()
        flat_row = flat_mat.getrow(2)
        block_row = m.getrow(2)
        self.assertTrue(
            np.allclose(flat_row.toarray().flatten(), block_row.flatten()))

        flat_row = flat_mat.getrow(7)
        block_row = m.getrow(7)
        self.assertTrue(
            np.allclose(flat_row.toarray().flatten(), block_row.flatten()))

    def test_nonzero(self):

        m = self.basic_m
        flat_mat = m.tocoo()
        flat_row, flat_col = flat_mat.nonzero()
        with self.assertRaises(Exception) as context:
            block_row, block_col = m.nonzero()

    def test_get_block_column_index(self):

        m = BlockMatrix(2, 4)
        m.set_block(0, 0, coo_matrix((3, 2)))
        m.set_block(0, 1, coo_matrix((3, 4)))
        m.set_block(0, 2, coo_matrix((3, 3)))
        m.set_block(0, 3, coo_matrix((3, 6)))
        m.set_block(1, 3, coo_matrix((5, 6)))

        bcol = m.get_block_column_index(8)
        self.assertEqual(bcol, 2)
        bcol = m.get_block_column_index(5)
        self.assertEqual(bcol, 1)
        bcol = m.get_block_column_index(14)
        self.assertEqual(bcol, 3)

    def test_get_block_row_index(self):

        m = BlockMatrix(2, 4)
        m.set_block(0, 0, coo_matrix((3, 2)))
        m.set_block(0, 1, coo_matrix((3, 4)))
        m.set_block(0, 2, coo_matrix((3, 3)))
        m.set_block(0, 3, coo_matrix((3, 6)))
        m.set_block(1, 3, coo_matrix((5, 6)))

        brow = m.get_block_row_index(0)
        self.assertEqual(brow, 0)
        brow = m.get_block_row_index(6)
        self.assertEqual(brow, 1)

    def test_matrix_multiply(self):
        """
        Test

        [A  B  C   *  [G  J   = [A*G + B*H + C*I    A*J + B*K + C*L
         D  E  F]      H  K      D*G + E*H + F*I    D*J + E*K + F*L]
                       I  L]
        """
        np.random.seed(0)
        A = sp.csr_matrix(np.random.normal(0, 10, (2, 2)))
        B = sp.csr_matrix(np.random.normal(0, 10, (2, 2)))
        C = sp.csr_matrix(np.random.normal(0, 10, (2, 2)))
        D = sp.csr_matrix(np.random.normal(0, 10, (2, 2)))
        E = sp.csr_matrix(np.random.normal(0, 10, (2, 2)))
        F = sp.csr_matrix(np.random.normal(0, 10, (2, 2)))
        G = sp.csr_matrix(np.random.normal(0, 10, (2, 2)))
        H = sp.csr_matrix(np.random.normal(0, 10, (2, 2)))
        I = sp.csr_matrix(np.random.normal(0, 10, (2, 2)))
        J = sp.csr_matrix(np.random.normal(0, 10, (2, 2)))
        K = sp.csr_matrix(np.random.normal(0, 10, (2, 2)))
        L = sp.csr_matrix(np.random.normal(0, 10, (2, 2)))

        bm1 = BlockMatrix(2, 3)
        bm2 = BlockMatrix(3, 2)

        bm1.set_block(0, 0, A)
        bm1.set_block(0, 1, B)
        bm1.set_block(0, 2, C)
        bm1.set_block(1, 0, D)
        bm1.set_block(1, 1, E)
        bm1.set_block(1, 2, F)

        bm2.set_block(0, 0, G)
        bm2.set_block(1, 0, H)
        bm2.set_block(2, 0, I)
        bm2.set_block(0, 1, J)
        bm2.set_block(1, 1, K)
        bm2.set_block(2, 1, L)

        got = (bm1 * bm2).toarray()
        exp00 = (A * G + B * H + C * I).toarray()
        exp01 = (A * J + B * K + C * L).toarray()
        exp10 = (D * G + E * H + F * I).toarray()
        exp11 = (D * J + E * K + F * L).toarray()
        exp = np.zeros((4, 4))
        exp[0:2, 0:2] = exp00
        exp[0:2, 2:4] = exp01
        exp[2:4, 0:2] = exp10
        exp[2:4, 2:4] = exp11

        self.assertTrue(np.allclose(got, exp))

    def test_dimensions(self):
        bm = BlockMatrix(2, 2)
        self.assertTrue(bm.has_undefined_row_sizes())
        self.assertTrue(bm.has_undefined_col_sizes())
        with self.assertRaises(NotFullyDefinedBlockMatrixError):
            shape = bm.shape
        with self.assertRaises(NotFullyDefinedBlockMatrixError):
            bm.set_block(0, 0, BlockMatrix(2, 2))
        with self.assertRaises(NotFullyDefinedBlockMatrixError):
            row_sizes = bm.row_block_sizes()
        with self.assertRaises(NotFullyDefinedBlockMatrixError):
            col_sizes = bm.col_block_sizes()
        bm2 = BlockMatrix(2, 2)
        bm2.set_block(0, 0, coo_matrix((2, 2)))
        bm2.set_block(1, 1, coo_matrix((2, 2)))
        bm3 = bm2.copy()
        bm.set_block(0, 0, bm2)
        bm.set_block(1, 1, bm3)
        self.assertFalse(bm.has_undefined_row_sizes())
        self.assertFalse(bm.has_undefined_col_sizes())
        self.assertEqual(bm.shape, (8, 8))
        bm.set_block(0, 0, None)
        self.assertFalse(bm.has_undefined_row_sizes())
        self.assertFalse(bm.has_undefined_col_sizes())
        self.assertEqual(bm.shape, (8, 8))
        self.assertTrue(np.all(bm.row_block_sizes() == np.ones(2) * 4))
        self.assertTrue(np.all(bm.col_block_sizes() == np.ones(2) * 4))
        self.assertTrue(
            np.all(bm.row_block_sizes(copy=False) == np.ones(2) * 4))
        self.assertTrue(
            np.all(bm.col_block_sizes(copy=False) == np.ones(2) * 4))

    def test_transpose_with_empty_rows(self):
        m = BlockMatrix(2, 2)
        m.set_row_size(0, 2)
        m.set_row_size(1, 2)
        m.set_col_size(0, 2)
        m.set_col_size(1, 2)
        mt = m.transpose()
        self.assertEqual(mt.get_row_size(0), 2)
        self.assertEqual(mt.get_row_size(1), 2)
        self.assertEqual(mt.get_col_size(0), 2)
        self.assertEqual(mt.get_col_size(1), 2)
Ejemplo n.º 4
0
x = nlp.x_init()
y = compute_init_lam(nlp, x=x)

J = nlp.jacobian_g(x)
H = nlp.hessian_lag(x, y)

M = BlockSymMatrix(2)
M[0, 0] = H
M[1, 0] = J

Np = BlockMatrix(2, 1)
Np[0, 0] = nlp.Hessian_lag(x, y, variables_cols=[m.eta1, m.eta2])
Np[1, 0] = nlp.Jacobian_g(x, variables=[m.eta1, m.eta2])

M_array = M.toarray()
Np_array = Np.toarray()

ds = np.linalg.solve(M_array, Np_array)

print(nlp.variable_order())

#################################################################

p0 = np.array([aml.value(m.nominal_eta1), aml.value(m.nominal_eta2)])
p = np.array([4.45, 1.05])
dp = p - p0
dx = ds.dot(dp)[0:nlp.nx]
new_x = x + dx
print(new_x)

#################################################################