Beispiel #1
0
    def test_compose_sparse(self):
        import numpy as nm
        import scipy.sparse as sps
        from sfepy.linalg import compose_sparse

        ok = True

        # basic
        ma = sps.csr_matrix([[1, 0], [0, 1]])
        mb = sps.coo_matrix([[1, 1]])
        mk = compose_sparse([[ma, mb.T], [mb, 0]])
        expected = nm.array([[1, 0, 1], [0, 1, 1], [1, 1, 0]])

        _ok = nm.alltrue(mk.toarray() == expected)
        self.report('basic: %s' % _ok)
        ok = ok and _ok

        # sizes and slices
        ma = sps.csr_matrix([[2, 3]])
        mb = sps.coo_matrix([[4, 5, 6]])

        mk = compose_sparse([[ma, mb]], col_sizes=[2, 3])
        expected = nm.array([[2, 3, 4, 5, 6]])

        _ok = nm.alltrue(mk.toarray() == expected)
        self.report('sizes: %s' % _ok)
        ok = ok and _ok

        i1 = slice(1, 3)
        i2 = slice(8, 11)
        mk = compose_sparse([[ma, mb]], col_sizes=[i1, i2])
        expected = nm.array([[0, 2, 3, 0, 0, 0, 0, 0, 4, 5, 6]])

        _ok = nm.alltrue(mk.toarray() == expected)
        self.report('slices: %s' % _ok)
        ok = ok and _ok

        # zero block sizes and slices
        mk = compose_sparse([[0, ma, 0, mb, 0]], col_sizes=[1, 2, 5, 3, 1])
        expected = nm.array([[0, 2, 3, 0, 0, 0, 0, 0, 4, 5, 6, 0]])

        _ok = nm.alltrue(mk.toarray() == expected)
        self.report('zero block sizes: %s' % _ok)
        ok = ok and _ok

        expected = nm.array([[0, 2, 3, 0, 4, 5, 6, 0, 0, 0, 0],
                             [0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6]])

        i0 = slice(0, 1)
        i1 = slice(1, 3)
        i2 = slice(4, 7)
        i3 = slice(8, 11)
        mk = compose_sparse([[0, ma, mb, 0], [0, 0, 0, mb]],
                            col_sizes=[i0, i1, i2, i3])

        _ok = nm.alltrue(mk.toarray() == expected)
        self.report('zero block slices: %s' % _ok)
        ok = ok and _ok

        return ok
Beispiel #2
0
    def compute_jacobian(self, vec_x, fun_smooth_grad, fun_a_grad, fun_b_grad,
                         vec_smooth_r, vec_a_r, vec_b_r):
        conf = self.conf

        mtx_s = fun_smooth_grad(vec_x)
        mtx_a = fun_a_grad(vec_x)
        mtx_b = fun_b_grad(vec_x)

        n_s = vec_smooth_r.shape[0]
        n_ns = vec_a_r.shape[0]

        if conf.semismooth:
            aa = nm.abs(vec_a_r)
            ab = nm.abs(vec_b_r)
            iz = nm.where((aa < (conf.macheps * max(aa.max(), 1.0)))
                          & (ab < (conf.macheps * max(ab.max(), 1.0))))[0]
            inz = nm.setdiff1d(nm.arange(n_ns), iz)

            output('non_active/active: %d/%d' % (len(inz), len(iz)))

            mul_a = nm.empty_like(vec_a_r)
            mul_b = nm.empty_like(mul_a)

            # Non-active part of the jacobian.
            if len(inz) > 0:
                a_r_nz = vec_a_r[inz]
                b_r_nz = vec_b_r[inz]

                sqrt_ab = nm.sqrt(a_r_nz**2.0 + b_r_nz**2.0)
                mul_a[inz] = (a_r_nz / sqrt_ab) - 1.0
                mul_b[inz] = (b_r_nz / sqrt_ab) - 1.0

            # Active part of the jacobian.
            if len(iz) > 0:
                vec_z = nm.zeros_like(vec_x)
                vec_z[n_s+iz] = 1.0

                mtx_a_z = mtx_a[iz]
                mtx_b_z = mtx_b[iz]

                sqrt_ab = nm.empty((iz.shape[0],), dtype=vec_a_r.dtype)
                for ir in range(len(iz)):
                    row_a_z = mtx_a_z[ir]
                    row_b_z = mtx_b_z[ir]
                    sqrt_ab[ir] = nm.sqrt((row_a_z * row_a_z.T).todense()
                                          + (row_b_z * row_b_z.T).todense())
                mul_a[iz] = ((mtx_a_z * vec_z) / sqrt_ab) - 1.0
                mul_b[iz] = ((mtx_b_z * vec_z) / sqrt_ab) - 1.0

        else:
            iz = nm.where(vec_a_r > vec_b_r)[0]
            mul_a = nm.zeros_like(vec_a_r)
            mul_b = nm.ones_like(mul_a)

            mul_a[iz] = 1.0
            mul_b[iz] = 0.0

        mtx_ns = sp.spdiags(mul_a, 0, n_ns, n_ns) * mtx_a \
                 + sp.spdiags(mul_b, 0, n_ns, n_ns) * mtx_b

        mtx_jac = compose_sparse([[mtx_s], [mtx_ns]]).tocsr()
        mtx_jac.sort_indices()

        return mtx_jac
Beispiel #3
0
    def compute_jacobian(self, vec_x, fun_smooth_grad, fun_a_grad, fun_b_grad,
                         vec_smooth_r, vec_a_r, vec_b_r):
        conf = self.conf

        mtx_s = fun_smooth_grad(vec_x)
        mtx_a = fun_a_grad(vec_x)
        mtx_b = fun_b_grad(vec_x)

        n_s = vec_smooth_r.shape[0]
        n_ns = vec_a_r.shape[0]

        if conf.semismooth:
            aa = nm.abs(vec_a_r)
            ab = nm.abs(vec_b_r)
            iz = nm.where((aa < (conf.macheps * max(aa.max(), 1.0)))
                          & (ab < (conf.macheps * max(ab.max(), 1.0))))[0]
            inz = nm.setdiff1d(nm.arange(n_ns), iz)

            output('non_active/active: %d/%d' % (len(inz), len(iz)))

            mul_a = nm.empty_like(vec_a_r)
            mul_b = nm.empty_like(mul_a)

            # Non-active part of the jacobian.
            if len(inz) > 0:
                a_r_nz = vec_a_r[inz]
                b_r_nz = vec_b_r[inz]

                sqrt_ab = nm.sqrt(a_r_nz**2.0 + b_r_nz**2.0)
                mul_a[inz] = (a_r_nz / sqrt_ab) - 1.0
                mul_b[inz] = (b_r_nz / sqrt_ab) - 1.0

            # Active part of the jacobian.
            if len(iz) > 0:
                vec_z = nm.zeros_like(vec_x)
                vec_z[n_s+iz] = 1.0

                mtx_a_z = mtx_a[iz]
                mtx_b_z = mtx_b[iz]

                sqrt_ab = nm.empty((iz.shape[0],), dtype=vec_a_r.dtype)
                for ir in range(len(iz)):
                    row_a_z = mtx_a_z[ir]
                    row_b_z = mtx_b_z[ir]
                    sqrt_ab[ir] = nm.sqrt((row_a_z * row_a_z.T).todense()
                                          + (row_b_z * row_b_z.T).todense())
                mul_a[iz] = ((mtx_a_z * vec_z) / sqrt_ab) - 1.0
                mul_b[iz] = ((mtx_b_z * vec_z) / sqrt_ab) - 1.0

        else:
            iz = nm.where(vec_a_r > vec_b_r)[0]
            mul_a = nm.zeros_like(vec_a_r)
            mul_b = nm.ones_like(mul_a)

            mul_a[iz] = 1.0
            mul_b[iz] = 0.0

        mtx_ns = sp.spdiags(mul_a, 0, n_ns, n_ns) * mtx_a \
                 + sp.spdiags(mul_b, 0, n_ns, n_ns) * mtx_b

        mtx_jac = compose_sparse([[mtx_s], [mtx_ns]]).tocsr()
        mtx_jac.sort_indices()

        return mtx_jac
Beispiel #4
0
    def test_compose_sparse(self):
        import numpy as nm
        import scipy.sparse as sps
        from sfepy.linalg import compose_sparse

        ok = True

        # basic
        ma = sps.csr_matrix([[1, 0], [0, 1]])
        mb = sps.coo_matrix([[1, 1]])
        mk = compose_sparse([[ma, mb.T], [mb, 0]])
        expected = nm.array([[1, 0, 1],
                             [0, 1, 1],
                             [1, 1, 0]])

        _ok = nm.alltrue(mk.toarray() == expected)
        self.report('basic: %s' % _ok)
        ok = ok and _ok

        # sizes and slices
        ma = sps.csr_matrix([[2, 3]])
        mb = sps.coo_matrix([[4, 5, 6]])

        mk = compose_sparse([[ma, mb]], col_sizes=[2, 3])
        expected = nm.array([[2, 3, 4, 5, 6]])

        _ok = nm.alltrue(mk.toarray() == expected)
        self.report('sizes: %s' % _ok)
        ok = ok and _ok

        i1 = slice(1, 3)
        i2 = slice(8, 11)
        mk = compose_sparse([[ma, mb]], col_sizes=[i1, i2])
        expected = nm.array([[0, 2, 3, 0, 0, 0, 0, 0, 4, 5, 6]])

        _ok = nm.alltrue(mk.toarray() == expected)
        self.report('slices: %s' % _ok)
        ok = ok and _ok

        # zero block sizes and slices
        mk = compose_sparse([[0, ma, 0, mb, 0]], col_sizes=[1, 2, 5, 3, 1])
        expected = nm.array([[0, 2, 3, 0, 0, 0, 0, 0, 4, 5, 6, 0]])

        _ok = nm.alltrue(mk.toarray() == expected)
        self.report('zero block sizes: %s' % _ok)
        ok = ok and _ok

        expected = nm.array([[0, 2, 3, 0, 4, 5, 6, 0, 0, 0, 0],
                             [0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6]])

        i0 = slice(0, 1)
        i1 = slice(1, 3)
        i2 = slice(4, 7)
        i3 = slice(8, 11)
        mk = compose_sparse([[0, ma, mb, 0],
                             [0, 0, 0, mb]], col_sizes=[i0, i1, i2, i3])

        _ok = nm.alltrue(mk.toarray() == expected)
        self.report('zero block slices: %s' % _ok)
        ok = ok and _ok

        return ok