예제 #1
0
class TestCloop(TestBlas):
    """Testing norm, matmul, rmatmul and rtrue_tdivide
    """

    def setUp(self):
        super().setUp()
        self.gfm = gfc

    @hy.given(hn.broadcastable('(a,b),(a,b)', 'd'))
    def test_rtrue_divide_returns_expected_shapes(self, arrays):
        a_bs, m_bs = arrays

        a_bs[np.abs(a_bs) < 1e-5] += 1.
        expect = utn.array_return_shape('(),()->()', a_bs, m_bs)
        self.assertArrayShape(self.gfm.rtrue_divide(a_bs, m_bs), expect)
        with self.assertRaisesRegex(*utn.broadcast_err):
            self.gfm.rtrue_divide(*utn.make_bad_broadcast(m_bs, a_bs))

    @hy.given(hn.broadcastable('(a,b),(a,b)', None))
    def test_rtrue_divide_returns_expected_values(self, arrays):
        a_bs, m_bs = arrays

        expect = utn.array_return_shape('(),()->()', a_bs, m_bs)
        zout = np.empty(expect, m_bs.dtype)
        a_bs[np.abs(a_bs) < 1e-5] += 1.
        zres = self.gfm.rtrue_divide(a_bs, m_bs, out=zout)
        zzz = m_bs / a_bs
        self.assertArrayAllClose(zres, zzz)
        self.assertArrayAllClose(zout, zzz)
class TestSolveVal(TestCaseNumpy):
    """Testing (r)solve, (r)solve_lu and (r)lu_solve"""
    @hy.given(hn.broadcastable('(a,a),(a,b),(b,a)', None))
    def test_solve_returns_expected_values(self, arrays):
        m_ss, m_sb, m_bs = arrays
        hy.assume(hn.all_well_behaved(m_ss))
        cond = np.linalg.cond(m_ss).max()

        x_sb = gfl.solve(m_ss, m_sb)
        # with self.subTest(msg='solve'):
        self.assertArrayAllClose(m_ss @ x_sb, m_sb, cond=cond)
        x_bs = gfl.rsolve(m_bs, m_ss)
        # with self.subTest(msg='rsolve'):
        self.assertArrayAllClose(x_bs @ m_ss, m_bs, cond=cond)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,a)', None))
    def test_solve_lu_returns_expected_values(self, arrays):
        m_ss, m_sb, m_bs = arrays
        hy.assume(hn.all_well_behaved(m_ss))
        cond = np.linalg.cond(m_ss).max()

        x0_sb = gfl.solve(m_ss, m_sb)
        x_sb, x_f, i_p = gfl.solve_lu(m_ss, m_sb)
        # with self.subTest('solve0'):
        self.assertArrayAllClose(x_sb, x0_sb, cond=cond)
        xx_sb = gfl.lu_solve(x_f, i_p, m_sb)
        # with self.subTest('solve(lu)'):
        self.assertArrayAllClose(xx_sb, x0_sb, cond=cond)
        x_bs = gfl.rlu_solve(m_bs, x_f, i_p)
        # with self.subTest('rsolve(lu)'):
        self.assertArrayAllClose(x_bs @ m_ss, m_bs, cond=cond)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,a)', None))
    def test_rsolve_lu_returns_expected_values(self, arrays):
        m_ss, m_sb, m_bs = arrays
        hy.assume(hn.all_well_behaved(m_ss))
        cond = np.linalg.cond(m_ss).max()

        x0_bs = gfl.rsolve(m_bs, m_ss)
        x_bs, x_f, i_p = gfl.rsolve_lu(m_bs, m_ss)
        # with self.subTest('rsolve0'):
        self.assertArrayAllClose(x_bs, x0_bs, cond=cond)
        xx_bs = gfl.rlu_solve(m_bs, x_f, i_p)
        # with self.subTest('rsolve(rlu)'):
        self.assertArrayAllClose(xx_bs, x0_bs, cond=cond)
        x_sb = gfl.lu_solve(x_f, i_p, m_sb)
        # with self.subTest('solve(rlu)'):
        self.assertArrayAllClose(m_ss @ x_sb, m_sb, cond=cond)

    @expectedFailure
    @errstate
    @hy.given(hn.constant('(a,a)', None, min_side=2))
    def test_solve_raises_with_low_rank(self, ones_ss):
        with self.assertRaisesRegex(*utn.invalid_err):
            gfl.solve(ones_ss, ones_ss[..., :2])
예제 #3
0
class TestPinv(TestCaseNumpy):
    """Testing gufuncs_lapack.pinv, pinv_qr and qr_pinv
    """
    @hy.given(hn.broadcastable('(a,b)', None))
    def test_pinv_returns_expected_values_wide(self, m_sb):
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb))
        cond = np.linalg.cond(m_sb).max()

        id_s = np.identity(m_sb.shape[-2], m_sb.dtype)
        # with self.subTest(msg='wide'):
        wide_p = gfl.pinv(m_sb)
        self.assertArrayAllClose(m_sb @ wide_p, id_s, cond=cond)
        # with self.subTest(msg='wide,+qr'):
        wide_pq, wide_f, wide_tau = gfl.pinv_qrm(m_sb)
        # actually want lq here
        qrf, tau = gfl.lq_rawm(m_sb)
        # qrf = la.dagger(qrf)
        self.assertArrayAllClose(wide_pq, wide_p, cond=cond)
        self.assertArrayAllClose(wide_f, qrf, cond=cond)
        self.assertArrayAllClose(wide_tau, tau, cond=cond)
        # with self.subTest(msg='wide,-qr'):
        wide_qp = gfl.qr_pinv(wide_f, wide_tau)
        self.assertArrayAllClose(wide_qp, wide_p, cond=cond)

    @hy.given(hn.broadcastable('(a,b)', None))
    def test_pinv_returns_expected_values_tall(self, m_bs):
        hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_bs))
        cond = np.linalg.cond(m_bs).max()

        # with self.subTest(msg='tall'):
        tall_p = gfl.pinv(m_bs)
        id_s = np.identity(m_bs.shape[-1], m_bs.dtype)
        self.assertArrayAllClose(tall_p @ m_bs, id_s, cond=cond)
        # with self.subTest(msg='tall,+qr'):
        tall_pq, tall_f, tall_tau = gfl.pinv_qrn(m_bs)
        qrf, tau = gfl.qr_rawn(m_bs)
        self.assertArrayAllClose(tall_pq, tall_p, cond=cond)
        self.assertArrayAllClose(tall_f, qrf, cond=cond)
        self.assertArrayAllClose(tall_tau, tau, cond=cond)
        # with self.subTest(msg='tall,-qr'):
        tall_qp = gfl.qr_pinv(tall_f, tall_tau)
        self.assertArrayAllClose(tall_qp, tall_p, cond=cond)
예제 #4
0
class TestQRPinvShape(TestCaseNumpy):
    """Testing gufuncs_lapack.qr_*, lq_*, pinv, pinv_qr and qr_pinv
    """
    @errstate
    @hy.given(hn.broadcastable('(a,b),(b,a)', 'd'))
    def test_qr_returns_expected_shapes(self, arrays):
        m_sb, m_bs = arrays
        wide, tall = [arr.shape for arr in arrays]
        hy.assume(hn.wide(m_sb))

        # with self.subTest(msg='wide'):
        self.assertArrayShapesAre(gfl.qr_m(m_sb), (utn.chop(wide), wide))
        self.assertArrayShape(gfl.qr_rm(m_sb), wide)
        with self.assertRaisesRegex(*utn.invalid_err):
            gfl.qr_n(m_sb)
        # with self.subTest(msg='tall'):
        self.assertArrayShapesAre(gfl.qr_n(m_bs), (tall, utn.chop(tall)))
        self.assertArrayShape(gfl.qr_rn(m_bs), utn.chop(tall))
        # with self.subTest(msg='complete'):
        self.assertArrayShapesAre(gfl.qr_m(m_bs), (utn.grow(tall), tall))
        # with self.subTest(msg='raw'):
        self.assertArrayShapesAre(gfl.qr_rawm(m_sb),
                                  (utn.trnsp(wide), wide[:-1]))
        self.assertArrayShapesAre(gfl.qr_rawn(m_bs),
                                  (utn.trnsp(tall), utn.drop(tall)))

    @errstate
    @hy.given(hn.broadcastable('(a,b),(b,a)', 'd'))
    def test_lq_returns_expected_shapes(self, arrays):
        m_sb, m_bs = arrays
        wide, tall = [arr.shape for arr in arrays]
        hy.assume(hn.wide(m_sb))

        # with self.subTest(msg='wide'):
        self.assertArrayShapesAre(gfl.lq_m(m_sb), (utn.chop(wide), wide))
        self.assertArrayShape(gfl.lq_lm(m_sb), utn.chop(wide))
        # with self.subTest(msg='tall'):
        self.assertArrayShapesAre(gfl.lq_n(m_bs), (tall, utn.chop(tall)))
        self.assertArrayShape(gfl.lq_ln(m_bs), tall)
        with self.assertRaisesRegex(*utn.invalid_err):
            gfl.lq_m(m_bs)
        # with self.subTest(msg='complete'):
        self.assertArrayShapesAre(gfl.lq_n(m_sb), (wide, utn.grow(wide)))
        # with self.subTest(msg='raw'):
        self.assertArrayShapesAre(gfl.lq_rawm(m_sb),
                                  (utn.trnsp(wide), wide[:-1]))
        self.assertArrayShapesAre(gfl.lq_rawn(m_bs),
                                  (utn.trnsp(tall), utn.drop(tall)))

    @hy.given(hn.broadcastable('(a,b),(b,a)', 'd'))
    def test_pinv_returns_expected_shapes(self, arrays):
        m_sb, m_bs = arrays
        wide, tall = [arr.shape for arr in arrays]
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_bs, m_sb))

        # with self.subTest(msg='wide'):
        self.assertArrayShape(gfl.pinv(m_sb), utn.trnsp(wide))
        # with self.subTest(msg='tall'):
        self.assertArrayShape(gfl.pinv(m_bs), utn.trnsp(tall))
        # with self.subTest(msg='wide,+qr'):
        self.assertArrayShapesAre(
            gfl.pinv_qrm(m_sb), (utn.trnsp(wide), utn.trnsp(wide), wide[:-1]))
        # with self.subTest(msg='tall,+qr'):
        self.assertArrayShapesAre(
            gfl.pinv_qrn(m_bs),
            (utn.trnsp(tall), utn.trnsp(tall), utn.drop(tall)))
        # with self.subTest(msg='wide,-qr'):
        _, m_sb_f, m_sb_tau = gfl.pinv_qrm(m_sb)
        self.assertArrayShape(gfl.qr_pinv(m_sb_f, m_sb_tau), utn.trnsp(wide))
        # with self.subTest(msg='tall,-qr'):
        _, m_bs_f, m_bs_tau = gfl.pinv_qrn(m_bs)
        self.assertArrayShape(gfl.qr_pinv(m_bs_f, m_bs_tau), utn.trnsp(tall))
예제 #5
0
class TestLQ(TestCaseNumpy):
    """Testing gufuncs_lapack.lq_*
    """
    @hy.given(hn.broadcastable('(a,b)', None))
    def test_lq_returns_expected_values_with_wide(self, m_sb):
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb))
        cond = np.linalg.cond(m_sb).max()

        left, unitary = gfl.lq_m(m_sb)
        wide = left @ unitary
        eye = unitary @ la.dagger(unitary)
        id_s = np.identity(m_sb.shape[-2], m_sb.dtype)
        # with self.subTest(msg='lq'):
        self.assertArrayAllClose(wide, m_sb, cond=cond)
        # with self.subTest(msg='Q Q^T'):
        self.assertArrayAllClose(id_s, eye, cond=cond)

    @hy.given(hn.broadcastable('(a,b)', None))
    def test_lq_returns_expected_values_with_tall(self, m_bs):
        hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_bs))
        cond = np.linalg.cond(m_bs).max()

        left, unitary = gfl.lq_n(m_bs)
        tall = left @ unitary
        eye = unitary @ la.dagger(unitary)
        eyet = la.dagger(unitary) @ unitary
        id_s = np.identity(m_bs.shape[-1], m_bs.dtype)
        # with self.subTest(msg='lq'):
        self.assertArrayAllClose(tall, m_bs, cond=cond)
        # with self.subTest(msg='Q Q^T'):
        self.assertArrayAllClose(id_s, eye, cond=cond)
        # with self.subTest(msg='Q^T Q'):
        self.assertArrayAllClose(id_s, eyet, cond=cond)

    @hy.given(hn.broadcastable('(a,b)', None))
    def test_lq_complete_returns_expected_values(self, m_sb):
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb))
        cond = np.linalg.cond(m_sb).max()

        left, unitary = gfl.lq_n(m_sb)
        wide = left @ unitary
        eye = unitary @ la.dagger(unitary)
        eyet = la.dagger(unitary) @ unitary
        id_b = np.identity(m_sb.shape[-1], m_sb.dtype)
        # with self.subTest(msg='lq'):
        self.assertArrayAllClose(wide, m_sb, cond=cond)
        # with self.subTest(msg='Q Q^T'):
        self.assertArrayAllClose(id_b, eye, cond=cond)
        # with self.subTest(msg='Q^T Q'):
        self.assertArrayAllClose(id_b, eyet, cond=cond)

    @hy.given(hn.broadcastable('(a,b),(b,a)', None))
    def test_lq_l_returns_expected_values(self, arrays):
        m_sb, m_bs = arrays
        hy.assume(hn.all_well_behaved(m_bs, m_sb))
        hy.assume(hn.wide(m_sb))

        # with self.subTest(msg='l_m'):
        cond = np.linalg.cond(m_sb).max()
        left = gfl.lq_lm(m_sb)
        llo = gfl.lq_m(m_sb)[0]
        self.assertArrayAllClose(left, llo, cond=cond)
        # with self.subTest(msg='l_n'):
        cond = np.linalg.cond(m_bs).max()
        left = gfl.lq_ln(m_bs)
        llo = gfl.lq_n(m_bs)[0]
        self.assertArrayAllClose(left, llo, cond=cond)

    @hy.given(hn.broadcastable('(a,b)', None))
    def test_lq_rawm_returns_expected_values(self, m_sb):
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb))
        cond = np.linalg.cond(m_sb).max()

        llo = gfl.lq_m(m_sb)[0]
        num = llo.shape[-2]
        ht_sb, tau = gfl.lq_rawm(m_sb)
        h_sb = la.transpose(ht_sb)
        vecs = np.triu(h_sb, 1)
        vecs[(..., ) + np.diag_indices(num)] = 1
        vnorm = gfb.norm(la.col(tau) * vecs, axis=-1)**2
        left = np.tril(h_sb)
        # with self.subTest(msg='raw_m'):
        self.assertArrayAllClose(left[..., :num], llo, cond=cond)
        # with self.subTest(msg='tau_m'):
        self.assertArrayAllClose(vnorm, 2 * tau.real, cond=cond)
        for k in range(num):
            vvv = vecs[..., num - k - 1:num - k, :]
            ttt = la.scalar(tau[..., -k - 1])
            left -= ttt.conj() * (left @ la.dagger(vvv)) * vvv
        # with self.subTest(msg='h_m'):
        self.assertArrayAllClose(left, m_sb, cond=cond)

    @hy.given(hn.broadcastable('(a,b)', None))
    def test_lq_rawn_returns_expected_values(self, m_bs):
        hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_bs))
        cond = np.linalg.cond(m_bs).max()

        llo = gfl.lq_n(m_bs)[0]
        num = llo.shape[-1]
        ht_bs, tau = gfl.lq_rawn(m_bs)
        h_bs = la.transpose(ht_bs)
        vecs = np.triu(h_bs, 1)
        vecs[(..., ) + np.diag_indices(num)] = 1
        vnorm = gfb.norm(la.col(tau) * vecs[..., :num, :], axis=-1)**2
        left = np.tril(h_bs)
        # with self.subTest(msg='raw_n'):
        self.assertArrayAllClose(left, llo, cond=cond)
        # with self.subTest(msg='tau_n'):
        self.assertArrayAllClose(vnorm, 2 * tau.real, cond=cond)
        for k in range(num):
            vvv = vecs[..., num - k - 1:num - k, :]
            ttt = la.scalar(tau[..., -k - 1])
            left -= ttt.conj() * (left @ la.dagger(vvv)) * vvv
        # with self.subTest(msg='h_n'):
        self.assertArrayAllClose(left, m_bs, cond=cond)
예제 #6
0
class TestQR(TestCaseNumpy):
    """Testing gufuncs_lapack.qr_*
    """
    @hy.given(hn.broadcastable('(a,b)', None))
    def test_qr_returns_expected_values_with_wide(self, m_sb):
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb))
        cond = np.linalg.cond(m_sb).max()

        unitary, right = gfl.qr_m(m_sb)
        wide = unitary @ right
        eye = la.dagger(unitary) @ unitary
        eyet = unitary @ la.dagger(unitary)
        id_s = np.identity(m_sb.shape[-2], m_sb.dtype)
        # with self.subTest(msg='qr'):
        self.assertArrayAllClose(wide, m_sb, cond=cond)
        # with self.subTest(msg='Q^T Q'):
        self.assertArrayAllClose(id_s, eye, cond=cond)
        # with self.subTest(msg='Q Q^T'):
        self.assertArrayAllClose(id_s, eyet, cond=cond)

    @hy.given(hn.broadcastable('(a,b)', None))
    def test_qr_returns_expected_values_with_tall(self, m_bs):
        hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_bs))
        cond = np.linalg.cond(m_bs).max()

        unitary, right = gfl.qr_n(m_bs)
        tall = unitary @ right
        eye = la.dagger(unitary) @ unitary
        id_s = np.identity(m_bs.shape[-1], m_bs.dtype)
        # with self.subTest(msg='qr'):
        self.assertArrayAllClose(tall, m_bs, cond=cond)
        # with self.subTest(msg='Q^T Q'):
        self.assertArrayAllClose(id_s, eye, cond=cond)

    @hy.given(hn.broadcastable('(a,b)', None))
    def test_qr_complete_returns_expected_values(self, m_bs):
        hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_bs))
        cond = np.linalg.cond(m_bs).max()

        unitary, right = gfl.qr_m(m_bs)
        tall = unitary @ right
        eye = la.dagger(unitary) @ unitary
        eyet = unitary @ la.dagger(unitary)
        id_b = np.identity(m_bs.shape[-2], m_bs.dtype)
        # with self.subTest(msg='qr'):
        self.assertArrayAllClose(tall, m_bs, cond=cond)
        # with self.subTest(msg='Q^T Q'):
        self.assertArrayAllClose(id_b, eye, cond=cond)
        # with self.subTest(msg='Q Q^T'):
        self.assertArrayAllClose(id_b, eyet, cond=cond)

    @hy.given(hn.broadcastable('(a,b),(b,a)', None))
    def test_qr_r_returns_expected_values(self, arrays):
        m_sb, m_bs = arrays
        hy.assume(hn.all_well_behaved(m_sb, m_bs))
        hy.assume(hn.wide(m_sb))

        # with self.subTest(msg='r_m'):
        cond = np.linalg.cond(m_sb).max()
        right = gfl.qr_rm(m_sb)
        rrr = gfl.qr_m(m_sb)[1]
        self.assertArrayAllClose(right, rrr, cond=cond)
        # with self.subTest(msg='r_n'):
        cond = np.linalg.cond(m_bs).max()
        right = gfl.qr_rn(m_bs)
        rrr = gfl.qr_n(m_bs)[1]
        self.assertArrayAllClose(right, rrr, cond=cond)

    @hy.given(hn.broadcastable('(a,b)', None))
    def test_qr_rawm_returns_expected_values(self, m_sb):
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb))
        cond = np.linalg.cond(m_sb).max()

        rrr = gfl.qr_m(m_sb)[1]
        num = rrr.shape[-2]
        ht_sb, tau = gfl.qr_rawm(m_sb)
        h_sb = la.transpose(ht_sb)
        vecs = np.tril(h_sb, -1)
        vecs[(..., ) + np.diag_indices(num)] = 1
        vnorm = gfb.norm(la.row(tau) * vecs[..., :num], axis=-2)**2
        right = np.triu(h_sb)
        # with self.subTest(msg='raw_m'):
        self.assertArrayAllClose(right, rrr, cond=cond)
        self.assertArrayAllClose(vnorm, 2 * tau.real, cond=cond)
        for k in range(num):
            vvv = vecs[..., num - k - 1:num - k]
            ttt = la.scalar(tau[..., -k - 1])
            right -= ttt * vvv * (la.dagger(vvv) @ right)
        # with self.subTest(msg='h_m'):
        self.assertArrayAllClose(right, m_sb, cond=cond)

    @hy.given(hn.broadcastable('(a,b)', None))
    def test_qr_rawn_returns_expected_values(self, m_bs):
        hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_bs))
        cond = np.linalg.cond(m_bs).max()

        rrr = gfl.qr_n(m_bs)[1]
        num = rrr.shape[-1]
        ht_bs, tau = gfl.qr_rawn(m_bs)
        h_bs = la.transpose(ht_bs)
        vecs = np.tril(h_bs, -1)
        vecs[(..., ) + np.diag_indices(num)] = 1
        vnorm = gfb.norm(la.row(tau) * vecs, axis=-2)**2
        right = np.triu(h_bs)
        # with self.subTest(msg='raw_n'):
        self.assertArrayAllClose(right[..., :num, :], rrr, cond=cond)
        self.assertArrayAllClose(vnorm, 2 * tau.real, cond=cond)
        for k in range(num):
            vvv = vecs[..., num - k - 1:num - k]
            ttt = la.scalar(tau[..., -k - 1])
            right -= ttt * vvv * (la.dagger(vvv) @ right)
        # with self.subTest(msg='h_n'):
        self.assertArrayAllClose(right, m_bs, cond=cond)
예제 #7
0
class TestLstsqShape(TestCaseNumpy):
    """Testing (r)lstsq, (r)lstsq_qr? and (r)qr_lstsq"""
    @errstate
    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', 'd'))
    def test_lstsq_returns_expected_shape(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.wide(m_sb))

        # with self.subTest('overconstrained'):
        expect = utn.array_return_shape('(m,n),(m,p)->(n,p)', m_bs, m_bb)
        self.assertArrayShape(gfl.lstsq(m_bs, m_bb), expect)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.lstsq(m_bs, m_sb)
        with self.assertRaisesRegex(*utn.broadcast_err):
            gfl.lstsq(*utn.make_bad_broadcast(m_bs, m_bb))
        # with self.subTest('underconstrained'):
        expect = utn.array_return_shape('(m,n),(m,p)->(n,p)', m_sb, m_ss)
        self.assertArrayShape(gfl.lstsq(m_sb, m_ss), expect)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.lstsq(m_sb, m_bs)
        with self.assertRaisesRegex(*utn.broadcast_err):
            gfl.lstsq(*utn.make_bad_broadcast(m_sb, m_ss))

    @errstate
    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', 'd'))
    def test_rlstsq_returns_expected_shape(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.wide(m_sb))

        # with self.subTest('underconstrained'):
        expect = utn.array_return_shape('(m,n),(p,n)->(m,p)', m_ss, m_bs)
        self.assertArrayShape(gfl.rlstsq(m_ss, m_bs), expect)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rlstsq(m_sb, m_bs)
        with self.assertRaisesRegex(*utn.broadcast_err):
            gfl.rlstsq(*utn.make_bad_broadcast(m_ss, la.transpose(m_sb)))
        # with self.subTest('overconstrained'):
        expect = utn.array_return_shape('(m,n),(p,n)->(m,p)', m_bb, m_sb)
        self.assertArrayShape(gfl.rlstsq(m_bb, m_sb), expect)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rlstsq(m_bs, m_sb)
        with self.assertRaisesRegex(*utn.broadcast_err):
            gfl.rlstsq(*utn.make_bad_broadcast(m_bb, la.transpose(m_bs)))

    @hy.given(hn.broadcastable('(a,b),(b,b),(b,a)', 'd'), qr_funcs)
    def test_lstsq_qr_returns_expected_shape_tall(self, arrays, fun):
        m_sb, m_bb, m_bs = arrays
        hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_bs))
        tall = m_bs.shape

        expect = utn.array_return_shape('(m,n),(m,p)->(n,p),(n,m)', m_bs, m_bb)
        tau = expect[1][:-2] + tau_len(m_bs, fun)
        result = fun(m_bs, m_bb)
        self.assertArrayShapesAre(result, expect + (tau, ))
        self.assertArrayShapesAre(unbroadcast_factors(m_bs, *result[1:]),
                                  (utn.trnsp(tall), tall[:-2] + tau[-1:]))
        with self.assertRaisesRegex(*utn.core_dim_err):
            fun(m_bs, m_sb)
        with self.assertRaisesRegex(*utn.broadcast_err):
            fun(*utn.make_bad_broadcast(m_bs, m_bb))

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', 'd'), qr_funcs)
    def test_qr_lstsq_returns_expected_shape_tall(self, arrays, fun):
        m_ss, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_bs))

        _, x_f, tau = fun(m_bs, m_bb)
        expect = utn.array_return_shape('(n,m),(m,p)->(n,p)', x_f, m_bb)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, m_bb), expect)
        expect = utn.array_return_shape('(m,n),(n,p)->(m,p)', m_ss, x_f)
        self.assertArrayShape(gfl.rqr_lstsq(m_ss, x_f, tau), expect)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.qr_lstsq(x_f, tau, m_sb)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rqr_lstsq(m_sb, x_f, tau)
        with self.assertRaisesRegex(*utn.broadcast_err):
            gfl.qr_lstsq(x_f, *utn.make_bad_broadcast(tau, m_bb, (1, 2)))
        x_f, tau = unbroadcast_factors(m_bs, x_f, tau)
        expect = utn.array_return_shape('(m,n),(p,n)->(m,p)', m_ss, m_bs)
        self.assertArrayShape(gfl.rqr_lstsq(m_ss, x_f, tau), expect)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,a)', 'd'), qr_funcs)
    def test_lstsq_qr_returns_expected_shape_wide(self, arrays, fun):
        m_ss, m_sb, m_bs = arrays
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb))
        wide = m_sb.shape

        expect = utn.array_return_shape('(m,n),(m,p)->(n,p),(n,m)', m_sb, m_ss)
        tau = expect[1][:-2] + tau_len(m_sb, fun)
        result = fun(m_sb, m_ss)
        self.assertArrayShapesAre(result, expect + (tau, ))
        self.assertArrayShapesAre(unbroadcast_factors(m_sb, *result[1:]),
                                  (utn.trnsp(wide), wide[:-2] + tau[-1:]))
        with self.assertRaisesRegex(*utn.core_dim_err):
            fun(m_sb, m_bs)
        with self.assertRaisesRegex(*utn.broadcast_err):
            fun(*utn.make_bad_broadcast(m_sb, m_ss))

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b)', 'd'), qr_funcs)
    def test_qr_lstsq_returns_expected_shape_wide(self, arrays, fun):
        m_ss, m_sb, m_bb = arrays
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb))

        _, x_f, tau = fun(m_sb, m_ss)
        expect = utn.array_return_shape('(n,m),(m,p)->(n,p)', x_f, m_ss)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, m_ss), expect)
        expect = utn.array_return_shape('(m,n),(n,p)->(m,p)', m_bb, x_f)
        self.assertArrayShape(gfl.rqr_lstsq(m_bb, x_f, tau), expect)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.qr_lstsq(x_f, tau, m_bb)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rqr_lstsq(m_ss, x_f, tau)
        with self.assertRaisesRegex(*utn.broadcast_err):
            gfl.qr_lstsq(x_f, *utn.make_bad_broadcast(tau, m_ss, (1, 2)))
        x_f, tau = unbroadcast_factors(m_sb, x_f, tau)
        expect = utn.array_return_shape('(m,n),(p,n)->(m,p)', m_bb, m_sb)
        self.assertArrayShape(gfl.rqr_lstsq(m_bb, x_f, tau), expect)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,a)', 'd'), rqr_funcs)
    def test_rlstsq_qr_returns_expected_shape_tall(self, arrays, fun):
        m_ss, m_sb, m_bs = arrays
        hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_bs))
        tall = m_bs.shape

        expect = utn.array_return_shape('(m,n),(p,n)->(m,p),(n,p)', m_ss, m_bs)
        tau = expect[1][:-2] + tau_len(m_bs, fun)
        result = fun(m_ss, m_bs)
        self.assertArrayShapesAre(result, expect + (tau, ))
        self.assertArrayShapesAre(unbroadcast_factors(m_bs, *result[1:]),
                                  (utn.trnsp(tall), tall[:-2] + tau[-1:]))
        with self.assertRaisesRegex(*utn.core_dim_err):
            fun(m_sb, m_bs)
        with self.assertRaisesRegex(*utn.broadcast_err):
            fun(*utn.make_bad_broadcast(m_ss, la.transpose(m_sb)))

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', 'd'), rqr_funcs)
    def test_rqr_lstsq_returns_expected_shape_tall(self, arrays, fun):
        m_ss, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_bs))

        _, x_f, tau = fun(m_ss, m_bs)
        expect = utn.array_return_shape('(n,m),(m,p)->(n,p)', x_f, m_bb)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, m_bb), expect)
        expect = utn.array_return_shape('(m,n),(n,p)->(m,p)', m_ss, x_f)
        self.assertArrayShape(gfl.rqr_lstsq(m_ss, x_f, tau), expect)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.qr_lstsq(x_f, tau, m_sb)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rqr_lstsq(m_sb, x_f, tau)
        with self.assertRaisesRegex(*utn.broadcast_err):
            gfl.qr_lstsq(x_f, *utn.make_bad_broadcast(tau, m_bb, (1, 2)))
        x_f, tau = unbroadcast_factors(m_bs, x_f, tau)
        expect = utn.array_return_shape('(m,n),(m,p)->(n,p)', m_bs, m_bb)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, m_bb), expect)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', 'd'), rqr_funcs)
    def test_rlstsq_qr_returns_expected_shape_wide(self, arrays, fun):
        _, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb))
        wide = m_sb.shape

        expect = utn.array_return_shape('(m,n),(p,n)->(m,p),(n,p)', m_bb, m_sb)
        tau = expect[1][:-2] + tau_len(m_sb, fun)
        result = fun(m_bb, m_sb)
        self.assertArrayShapesAre(result, expect + (tau, ))
        self.assertArrayShapesAre(unbroadcast_factors(m_sb, *result[1:]),
                                  (utn.trnsp(wide), wide[:-2] + tau[-1:]))
        with self.assertRaisesRegex(*utn.core_dim_err):
            fun(m_bs, m_sb)
        with self.assertRaisesRegex(*utn.broadcast_err):
            fun(*utn.make_bad_broadcast(m_bb, la.transpose(m_bs)))

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', 'd'), rqr_funcs)
    def test_rqr_lstsq_returns_expected_shape_wide(self, arrays, fun):
        m_ss, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb))

        _, x_f, tau = fun(m_bb, m_sb)
        expect = utn.array_return_shape('(n,m),(m,p)->(n,p)', x_f, m_ss)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, m_ss), expect)
        expect = utn.array_return_shape('(m,n),(n,p)->(m,p)', m_bb, x_f)
        self.assertArrayShape(gfl.rqr_lstsq(m_bb, x_f, tau), expect)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.qr_lstsq(x_f, tau, m_bs)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rqr_lstsq(m_bs, x_f, tau)
        with self.assertRaisesRegex(*utn.broadcast_err):
            gfl.qr_lstsq(x_f, *utn.make_bad_broadcast(tau, m_ss, (1, 2)))
        x_f, tau = unbroadcast_factors(m_sb, x_f, tau)
        expect = utn.array_return_shape('(m,n),(m,p)->(n,p)', m_sb, m_ss)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, m_ss), expect)
예제 #8
0
class TestLstsqVal(TestCaseNumpy):
    """Testing (r)lstsq, (r)lstsq_qr? and (r)qr_lstsq"""
    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', None))
    def test_lstsq_returns_expected_values(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.wide(m_sb))
        cond_bs = np.linalg.cond(m_bs).max()
        cond_sb = np.linalg.cond(m_sb).max()

        # overconstrained
        x_sb = gfl.lstsq(m_bs, m_bb)
        m_bst = la.dagger(m_bs)
        # with self.subTest(msg='lstsq(over)'):
        self.assertArrayAllClose(m_bst @ m_bs @ x_sb,
                                 m_bst @ m_bb,
                                 cond=cond_bs)
        x_bs = gfl.rlstsq(m_bb, m_sb)
        m_sbt = la.dagger(m_sb)
        # with self.subTest(msg='rlstsq(over)'):
        self.assertArrayAllClose(x_bs @ m_sb @ m_sbt,
                                 m_bb @ m_sbt,
                                 cond=cond_sb)
        # underconstrained
        x_bs = gfl.lstsq(m_sb, m_ss)
        # with self.subTest(msg='lstsq(under)'):
        self.assertArrayAllClose(m_sb @ x_bs, m_ss, cond=cond_sb)
        x_sb = gfl.rlstsq(m_ss, m_bs)
        # with self.subTest(msg='rlstsq(under)'):
        self.assertArrayAllClose(x_sb @ m_bs, m_ss, cond=cond_bs)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', None), qr_funcs)
    def test_lstsq_qr_returns_expected_values_with_tall(self, arrays, fun):
        m_ss, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_bs))
        cond = np.linalg.cond(m_bs).max()

        # overconstrained
        x0_sb = gfl.lstsq(m_bs, m_bb)
        # overconstrained
        x_sb, x_f, tau = fun(m_bs, m_bb)
        # with self.subTest('lstsq_qr(over,' + suffix):
        self.assertArrayAllClose(x_sb, x0_sb, cond=cond)
        # overconstrained
        xx_sb = gfl.qr_lstsq(x_f, tau, m_bb)
        # with self.subTest('qr_lstsq(over,' + suffix):
        self.assertArrayAllClose(xx_sb, x0_sb, cond=cond)
        # underconstrained
        y_sb = gfl.rqr_lstsq(m_ss, x_f, tau)
        # with self.subTest('rqr_lstsq(under,' + suffix):
        self.assertArrayAllClose(y_sb @ m_bs, m_ss, cond=cond)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b)', None), rqr_funcs)
    def test_rlstsq_qr_returns_expected_values_with_wide(self, arrays, fun):
        m_ss, m_sb, m_bb = arrays
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb))
        cond = np.linalg.cond(m_sb).max()

        # overconstrained
        x0_bs = gfl.rlstsq(m_bb, m_sb)
        # overconstrained
        x_bs, x_f, tau = fun(m_bb, m_sb)
        # with self.subTest('rlstsq_qr(under,' + suffix):
        self.assertArrayAllClose(x_bs, x0_bs, cond=cond)
        # overconstrained
        xx_bs = gfl.rqr_lstsq(m_bb, x_f, tau)
        # with self.subTest('rqr_rlstsq(under,' + suffix):
        self.assertArrayAllClose(xx_bs, x0_bs, cond=cond)
        # underconstrained
        y_bs = gfl.qr_lstsq(x_f, tau, m_ss)
        # with self.subTest('qr_rlstsq(over,' + suffix):
        self.assertArrayAllClose(m_sb @ y_bs, m_ss, cond=cond)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b)', None), qr_funcs)
    def test_lstsq_qr_returns_expected_values_with_wide(self, arrays, fun):
        m_ss, m_sb, m_bb = arrays
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb))
        cond = np.linalg.cond(m_sb).max()

        # underconstrained
        x0_bs = gfl.lstsq(m_sb, m_ss)
        # underconstrained
        x_bs, x_f, tau = fun(m_sb, m_ss)
        # with self.subTest('lstsq_qr(under,' + suffix):
        self.assertArrayAllClose(x_bs, x0_bs, cond=cond)
        # underconstrained
        xx_bs = gfl.qr_lstsq(x_f, tau, m_ss)
        # with self.subTest('qr_lstsq(under,' + suffix):
        self.assertArrayAllClose(xx_bs, x0_bs, cond=cond)
        # overconstrained
        y_bs = gfl.rqr_lstsq(m_bb, x_f, tau)
        m_sbt = la.dagger(m_sb)
        # with self.subTest('rqr_lstsq(over,' + suffix):
        self.assertArrayAllClose(y_bs @ m_sb @ m_sbt, m_bb @ m_sbt, cond=cond)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', None), rqr_funcs)
    def test_rlstsq_qr_returns_expected_values_with_tall(self, arrays, fun):
        m_ss, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_bs))
        cond = np.linalg.cond(m_bs).max()

        # underconstrained
        x0_sb = gfl.rlstsq(m_ss, m_bs)
        # underconstrained
        x_sb, x_f, tau = fun(m_ss, m_bs)
        # with self.subTest('rlstsq_qr(over,' + suffix):
        self.assertArrayAllClose(x_sb, x0_sb, cond=cond)
        # underconstrained
        xx_sb = gfl.rqr_lstsq(m_ss, x_f, tau)
        # with self.subTest('rqr_rlstsq(over,' + suffix):
        self.assertArrayAllClose(xx_sb, x0_sb, cond=cond)
        # overconstrained
        y_sb = gfl.qr_lstsq(x_f, tau, m_bb)
        m_bst = la.dagger(m_bs)
        # with self.subTest('qr_rlstsq(under,' + suffix):
        self.assertArrayAllClose(m_bst @ m_bs @ y_sb, m_bst @ m_bb, cond=cond)

    @expectedFailure
    @errstate
    @hy.given(hn.constant('(a,b)', None, min_side=2))
    def test_lstsq_qr_raises_with_low_rank(self, ones_bs):
        hy.assume(hn.tall(ones_bs))

        with self.assertRaisesRegex(*utn.invalid_err):
            gfl.lstsq_qrn(ones_bs, ones_bs[..., :2])
예제 #9
0
class TestQRLstsqVectors(TestCaseNumpy):
    """Testing (r)qr_lstsq with vectors"""
    @hy.given(hn.broadcastable('(a,b),(b,a),(a),(b)', 'd'), qr_funcs)
    def test_qr_lstsq_flexible_signature_with_vectors_mv(self, arrays, fun):
        m_sb, m_bs = arrays[:-2]
        v_s, v_b = hn.core_only(*arrays[-2:], dims=1)
        wide, tall = [arr.shape for arr in arrays[:-2]]
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_bs, m_sb))
        off_b, y_one = utn.make_off_by_one(m_sb, m_bs)

        _, x_f, tau = fun(m_bs, v_b)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, v_b), utn.drop(tall))
        self.assertArrayShape(gfl.rqr_lstsq(v_s, x_f, tau), tall[:-1])

        _, x_f, tau = fun(m_sb, v_s)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, v_s), utn.drop(wide))
        self.assertArrayShape(gfl.rqr_lstsq(v_b, x_f, tau), wide[:-1])
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.qr_lstsq(x_f, tau, v_b)
        with self.assertRaisesRegex(*utn.core_dim_err):
            # This would succeed/broadcast error if interpreted as Mv:
            gfl.qr_lstsq(x_f[off_b], tau[off_b], m_bs[y_one])

    @hy.given(hn.broadcastable('(a,b),(b,a),(a)', 'd'), qr_funcs)
    def test_qr_lstsq_flexible_signature_with_vectors_vm(self, arrays, fun):
        m_sb, m_bs = hn.core_only(*arrays[:-1])
        v_s = hn.core_only(arrays[-1], dims=1)
        wide, tall = [arr.shape[-2:] for arr in arrays[:-1]]
        hy.assume(hn.wide(m_sb))
        hy.assume(la.norm(v_s) > 0.)

        _, x_f, tau = fun(v_s, m_sb)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, m_sb), utn.drop(wide))
        expect = utn.array_return_shape('(m,n),(n,p)->(m,p)', m_bs, m_sb)[:-1]
        self.assertArrayShape(gfl.rqr_lstsq(m_bs, x_f, tau), expect)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.qr_lstsq(x_f, tau, m_bs)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, v_s), wide[:-2])

        # with broadcasting
        m_sb, m_bs = arrays[:-1]
        wide, tall = [arr.shape for arr in arrays[:-1]]

        _, x_f, tau = fun(v_s, m_sb)
        x_f, tau = unbroadcast_factors(v_s, x_f, tau)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, m_sb), utn.drop(wide))
        self.assertArrayShape(gfl.rqr_lstsq(m_bs, x_f, tau), tall[:-1])

    @hy.given(hn.vectors, hn.vectors, qr_funcs)
    def test_qr_lstsq_flexible_signature_with_vectors_vv(self, v_s, v_b, fun):
        hy.assume(len(v_s) != len(v_b))
        hy.assume(la.norm(v_s) > 0.)

        _, x_f, tau = fun(v_s, v_s)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, v_s), ())
        self.assertArrayShape(gfl.rqr_lstsq(v_s, x_f, tau), ())
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.qr_lstsq(x_f, tau, v_b)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rqr_lstsq(v_b, x_f, tau)

    @hy.given(hn.broadcastable('(a,b),(b,a),(a)', 'd'), rqr_funcs)
    def test_rqr_lstsq_flexible_signature_with_vectors_mv(self, arrays, fun):
        m_sb, m_bs = hn.core_only(*arrays[:-1])
        v_s = hn.core_only(arrays[-1], dims=1)
        wide, tall = [arr.shape[-2:] for arr in arrays[:-1]]
        hy.assume(hn.wide(m_sb))
        hy.assume(la.norm(v_s) > 0.)

        _, x_f, tau = fun(m_bs, v_s)
        expect = utn.array_return_shape('(m,n),(n,p)->(m,p)', m_bs, m_sb)[:-1]
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, m_sb), expect)
        self.assertArrayShape(gfl.rqr_lstsq(m_bs, x_f, tau), tall[:-1])
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.qr_lstsq(x_f, tau, m_bs)
        self.assertArrayShape(gfl.rqr_lstsq(v_s, x_f, tau), tall[:-2])

        m_sb, m_bs = arrays[:-1]
        wide, tall = [arr.shape for arr in arrays[:-1]]

        _, x_f, tau = fun(m_bs, v_s)
        x_f, tau = unbroadcast_factors(v_s, x_f, tau)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, m_sb), utn.drop(wide))
        self.assertArrayShape(gfl.rqr_lstsq(m_bs, x_f, tau), tall[:-1])

    @hy.given(hn.broadcastable('(a,b),(b,a),(a),(b)', 'd'), rqr_funcs)
    def test_rqr_lstsq_flexible_signature_with_vectors_vm(self, arrays, fun):
        m_sb, m_bs = arrays[:-2]
        v_s, v_b = hn.core_only(*arrays[-2:], dims=1)
        wide, tall = [arr.shape for arr in arrays[:-2]]
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_bs, m_sb))
        off_b, y_one = utn.make_off_by_one(m_sb, m_bs)

        _, x_f, tau = fun(v_s, m_bs)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, v_b), utn.drop(tall))
        self.assertArrayShape(gfl.rqr_lstsq(v_s, x_f, tau), tall[:-1])

        _, x_f, tau = fun(v_b, m_sb)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, v_s), utn.drop(wide))
        self.assertArrayShape(gfl.rqr_lstsq(v_b, x_f, tau), wide[:-1])
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rqr_lstsq(v_s, x_f, tau)
        with self.assertRaisesRegex(*utn.core_dim_err):
            # This would succeed/broadcast error if interpreted as Mv:
            gfl.rqr_lstsq(m_bs[y_one], x_f[off_b], tau[off_b])

    @hy.given(hn.vectors, hn.vectors, qr_funcs)
    def test_rqr_lstsq_flexible_signature_with_vectors_vv(self, v_s, v_b, fun):
        hy.assume(len(v_s) != len(v_b))
        hy.assume(la.norm(v_s) > 0.)

        _, x_f, tau = fun(v_s, v_s)
        self.assertArrayShape(gfl.qr_lstsq(x_f, tau, v_s), ())
        self.assertArrayShape(gfl.rqr_lstsq(v_s, x_f, tau), ())
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.qr_lstsq(x_f, tau, v_b)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rqr_lstsq(v_b, x_f, tau)
예제 #10
0
class TestBlas(TestCaseNumpy):
    """Testing norm, matmul and rmatmul"""

    def setUp(self):
        super().setUp()
        self.gfm = gfb

    @hy.given(hn.matrices_b)
    def test_norm_returns_expected_shapes(self, m_bs):
        v_s = m_bs[(0,) * (m_bs.ndim - 1)]
        tall = m_bs.shape

        self.assertArrayShape(self.gfm.norm(m_bs), tall[:-1])
        self.assertArrayShape(self.gfm.norm(m_bs, axis=-2), utn.drop(tall))
        self.assertArrayShape(self.gfm.norm(v_s, keepdims=True), (1,))
        self.assertArrayShape(self.gfm.norm(v_s), ())

    @hy.given(hn.broadcastable('(a,b)', None))
    def test_norm_returns_expected_values(self, m_bs: np.ndarray):
        nout = np.empty_like(m_bs[..., 0].real)
        nrms = self.gfm.norm(m_bs, out=nout)
        norms = np.sqrt((np.abs(m_bs)**2).sum(-1))
        self.assertArrayAllClose(nrms, norms)
        self.assertArrayAllClose(nout, norms)

    @hy.given(hn.broadcastable('(a,b),(b,c)', 'd'))
    def test_matmul_returns_expected_shapes(self, arrays):
        m_sb, m_bs = arrays
        hy.assume(hn.nonsquare(m_sb))
        hy.assume(hn.nonsquare(m_bs))

        expect = utn.array_return_shape('(a,b),(b,c)->(a,c)', m_sb, m_bs)
        self.assertArrayShape(self.gfm.matmul(m_sb, m_bs), expect)
        with self.assertRaisesRegex(*utn.core_dim_err):
            self.gfm.matmul(m_bs, m_bs)
        with self.assertRaisesRegex(*utn.broadcast_err):
            self.gfm.matmul(*utn.make_bad_broadcast(m_sb, m_bs))

    @hy.given(hn.broadcastable('(a,b),(b,c)', None))
    def test_matmul_returns_expected_values(self, arrays):
        m_sb, m_bs = arrays
        expect = utn.array_return_shape('(a,b),(b,c)->(a,c)', m_sb, m_bs)

        pout = np.empty(expect, m_sb.dtype)
        pres = self.gfm.matmul(m_sb, m_bs, out=pout)
        prod = np.matmul(m_sb, m_bs)
        self.assertArrayAllClose(pres, prod)
        self.assertArrayAllClose(pout, prod)

    @hy.given(hn.broadcastable('(a,b),(b,c)', 'd'))
    def test_rmatmul_returns_expected_shapes(self, arrays):
        m_sb, m_bs = arrays
        hy.assume(hn.nonsquare(m_sb))
        hy.assume(hn.nonsquare(m_bs))

        expect = utn.array_return_shape('(a,b),(b,c)->(a,c)', m_sb, m_bs)
        self.assertArrayShape(self.gfm.rmatmul(m_bs, m_sb), expect)
        with self.assertRaisesRegex(*utn.core_dim_err):
            self.gfm.rmatmul(m_bs, m_bs)
        with self.assertRaisesRegex(*utn.broadcast_err):
            self.gfm.rmatmul(*utn.make_bad_broadcast(m_bs, m_sb))

    @hy.given(hn.broadcastable('(a,b),(b,c)', None))
    def test_rmatmul_returns_expected_values(self, arrays):
        m_sb, m_bs = arrays
        expect = utn.array_return_shape('(a,b),(b,c)->(a,c)', m_sb, m_bs)

        pout = np.empty(expect, m_sb.dtype)
        pres = self.gfm.rmatmul(m_bs, m_sb, out=pout)
        prod = np.matmul(m_sb, m_bs)
        self.assertArrayAllClose(pres, prod)
        self.assertArrayAllClose(pout, prod)
예제 #11
0
class TestValue(TestCaseNumpy):
    """Testing values returned by linalg functions"""
    @hy.given(hn.broadcastable('(a,b),(b,a)', None))
    def test_functions_matmul(self, arrays):
        m_sb, m_bs = arrays

        # with self.subTest('matmul'):
        self.assertArrayAllClose(la.matmul(m_bs, m_sb), gf.matmul(m_bs, m_sb))
        # with self.subTest('rmatmul'):
        self.assertArrayAllClose(gf.rmatmul(m_bs, m_sb), gf.matmul(m_sb, m_bs))

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,a)', None))
    def test_functions_solve(self, arrays):
        m_ss, m_sb, m_bs = arrays
        hy.assume(hn.all_well_behaved(m_ss))
        cond = np.linalg.cond(m_ss).max()

        # with self.subTest('solve'):
        self.assertArrayAllClose(la.solve(m_ss, m_sb),
                                 gf.solve(m_ss, m_sb),
                                 cond=cond)
        slv_sh = utn.array_return_shape('(a,a),(a,b)->(a,b)', m_ss, m_sb)
        slv_out = np.empty(slv_sh, m_ss.dtype)
        slv_r = la.solve(m_ss, m_sb, out=slv_out)
        self.assertArrayAllClose(slv_out, slv_r)
        # with self.subTest('rsolve'):
        self.assertArrayAllClose(la.rsolve(m_bs, m_ss),
                                 gf.rsolve(m_bs, m_ss),
                                 cond=cond)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a),(b)', None))
    def test_functions_lstsq(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays[:-1]
        v_b = hn.core_only(arrays[-1], dims=1)
        hy.assume(hn.wide(m_sb))
        cond_sb = np.linalg.cond(m_sb).max()
        cond_bs = np.linalg.cond(m_bs).max()

        # with self.subTest('lstsq'):
        self.assertArrayAllClose(la.lstsq(m_bs, m_bb),
                                 gf.lstsq(m_bs, m_bb),
                                 cond=cond_bs)
        self.assertArrayAllClose(la.lstsq(m_sb, m_ss),
                                 gf.lstsq(m_sb, m_ss),
                                 cond=cond_sb)
        lsq_sh = utn.array_return_shape('(a,b),(a,c)->(b,c)', m_bs, m_bb)
        lsq_out = np.empty(lsq_sh, m_bs.dtype)
        lsq_r = la.lstsq(m_bs, m_bb, out=lsq_out)
        self.assertArrayAllClose(lsq_out, lsq_r)
        # with self.subTest('rlstsq'):
        self.assertArrayAllClose(la.rlstsq(m_ss, m_bs),
                                 gf.rlstsq(m_ss, m_bs),
                                 cond=cond_bs)
        self.assertArrayAllClose(la.rlstsq(v_b, m_sb),
                                 gf.rlstsq(v_b, m_sb),
                                 cond=cond_sb)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', None))
    def test_functions_matldiv(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.all_well_behaved(m_ss))
        hy.assume(hn.wide(m_sb))

        # with self.subTest('solve'):
        self.assertArrayAllClose(la.matldiv(m_ss, m_sb), gf.solve(m_ss, m_sb))
        slv_sh = utn.array_return_shape('(a,a),(a,b)->(a,b)', m_ss, m_sb)
        slv_out = np.empty(slv_sh, m_ss.dtype)
        slv_r = la.matldiv(m_ss, m_sb, out=slv_out)
        cond = np.linalg.cond(m_ss).max()
        self.assertArrayAllClose(slv_out, slv_r, cond=cond)
        # with self.subTest('lstsq'):
        cond = np.linalg.cond(m_bs).max()
        self.assertArrayAllClose(la.matldiv(m_bs, m_bb),
                                 gf.lstsq(m_bs, m_bb),
                                 cond=cond)
        cond = np.linalg.cond(m_sb).max()
        self.assertArrayAllClose(la.matldiv(m_sb, m_ss),
                                 gf.lstsq(m_sb, m_ss),
                                 cond=cond)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,a),(b)', None))
    def test_functions_matrdiv(self, arrays):
        m_ss, m_sb, m_bs = arrays[:-1]
        v_b = hn.core_only(arrays[-1], dims=1)
        hy.assume(hn.all_well_behaved(m_ss))
        hy.assume(hn.wide(m_sb))

        # with self.subTest('rsolve'):
        cond = np.linalg.cond(m_ss).max()
        self.assertArrayAllClose(la.matrdiv(m_bs, m_ss),
                                 gf.rsolve(m_bs, m_ss),
                                 cond=cond)
        # with self.subTest('rlstsq'):
        cond = np.linalg.cond(m_bs).max()
        self.assertArrayAllClose(la.matrdiv(m_ss, m_bs),
                                 gf.rlstsq(m_ss, m_bs),
                                 cond=cond)
        cond = np.linalg.cond(m_sb).max()
        self.assertArrayAllClose(la.matrdiv(v_b, m_sb),
                                 gf.rlstsq(v_b, m_sb),
                                 cond=cond)

    @hy.given(hn.broadcastable('(a,b),(b,a)', None))
    def test_qr(self, arrays):
        m_sb, m_bs = arrays
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb, m_bs))
        box = np.s_[..., :m_sb.shape[-2], :]
        cond_sb = np.linalg.cond(m_sb).max()
        cond_bs = np.linalg.cond(m_bs).max()

        # with self.subTest("reduced"):
        unitary, right = la.qr(m_bs, 'reduced')
        self.assertArrayAllClose(unitary @ right, m_bs, cond=cond_bs)
        unitary, right = la.qr(m_sb, 'reduced')
        self.assertArrayAllClose(unitary @ right, m_sb, cond=cond_sb)
        # with self.subTest("complete"):
        unitary, right = la.qr(m_bs, 'complete')
        self.assertArrayAllClose(unitary @ right, m_bs, cond=cond_bs)
        unitary, right = la.qr(m_sb, 'complete')
        self.assertArrayAllClose(unitary @ right, m_sb, cond=cond_sb)
        # with self.subTest("r/raw"):
        right = la.qr(m_bs, 'r')
        hhold, _ = la.qr(m_bs, 'raw')
        self.assertArrayAllClose(right,
                                 np.triu(la.transpose(hhold))[box],
                                 cond=cond_bs)
        right = la.qr(m_sb, 'r')
        hhold, _ = la.qr(m_sb, 'raw')
        self.assertArrayAllClose(right,
                                 np.triu(la.transpose(hhold)),
                                 cond=cond_sb)

    @hy.given(hn.broadcastable('(a,b),(b,a)', None))
    def test_lq(self, arrays):
        m_sb, m_bs = arrays
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb, m_bs))
        box = np.s_[..., :m_sb.shape[-2]]
        cond_sb = np.linalg.cond(m_sb).max()
        cond_bs = np.linalg.cond(m_bs).max()

        # with self.subTest("reduced"):
        left, unitary = la.lq(m_bs, 'reduced')
        self.assertArrayAllClose(left @ unitary, m_bs, cond=cond_bs)
        left, unitary = la.lq(m_sb, 'reduced')
        self.assertArrayAllClose(left @ unitary, m_sb, cond=cond_sb)
        # with self.subTest("complete"):
        left, unitary = la.lq(m_bs, 'complete')
        self.assertArrayAllClose(left @ unitary, m_bs, cond=cond_bs)
        left, unitary = la.lq(m_sb, 'complete')
        self.assertArrayAllClose(left @ unitary, m_sb, cond=cond_sb)
        # with self.subTest("l/raw"):
        left = la.lq(m_bs, 'l')
        hhold, _ = la.lq(m_bs, 'raw')
        self.assertArrayAllClose(left, np.tril(la.transpose(hhold)))
        left = la.lq(m_sb, 'l')
        hhold, _ = la.lq(m_sb, 'raw')
        self.assertArrayAllClose(left, np.tril(la.transpose(hhold))[box])

    @hy.given(hn.broadcastable('(a,b),(b,a)', None))
    def test_lqr(self, arrays):
        m_sb, m_bs = arrays
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb, m_bs))
        box = np.s_[..., :m_sb.shape[-2], :]
        cond_sb = np.linalg.cond(m_sb).max()
        cond_bs = np.linalg.cond(m_bs).max()

        # with self.subTest("reduced"):
        unitary, right = la.lqr(m_bs, 'reduced')
        self.assertArrayAllClose(unitary @ right, m_bs, cond=cond_bs)
        left, unitary = la.lqr(m_sb, 'reduced')
        self.assertArrayAllClose(left @ unitary, m_sb, cond=cond_sb)
        # with self.subTest("complete"):
        unitary, right = la.lqr(m_bs, 'complete')
        self.assertArrayAllClose(unitary @ right, m_bs, cond=cond_bs)
        left, unitary = la.lqr(m_sb, 'complete')
        self.assertArrayAllClose(left @ unitary, m_sb, cond=cond_sb)
        # with self.subTest("r/l/raw"):
        right = la.lqr(m_bs, 'r')
        hhold, _ = la.lqr(m_bs, 'raw')
        self.assertArrayAllClose(right,
                                 np.triu(la.transpose(hhold))[box],
                                 cond=cond_bs)
        left = la.lqr(m_sb, 'r')
        hhold, _ = la.lqr(m_sb, 'raw')
        self.assertArrayAllClose(left,
                                 np.tril(la.transpose(hhold))[box[:-1]],
                                 cond=cond_sb)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,a)', None))
    def test_lu(self, arrays):
        m_ss, m_sb, m_bs = arrays
        box = np.s_[..., :m_sb.shape[-2], :]
        hy.assume(hn.wide(m_sb))

        # with self.subTest("square"):
        cond = np.linalg.cond(m_ss).max()
        lower, upper, piv = la.lu(m_ss, 'separate')
        luf, piv = la.lu(m_ss, 'raw')
        luf = la.transpose(luf)
        self.assertArrayAllClose(lower @ upper, gf.pivot(m_ss, piv), cond=cond)
        self.assertArrayAllClose(tril(lower), tril(luf), cond=cond)
        self.assertArrayAllClose(upper, np.triu(luf), cond=cond)
        # with self.subTest("wide"):
        cond = np.linalg.cond(m_bs).max()
        lower, upper, piv = la.lu(m_bs, 'separate')
        luf, piv = la.lu(m_bs, 'raw')
        luf = la.transpose(luf)
        self.assertArrayAllClose(tril(lower), tril(luf), cond=cond)
        self.assertArrayAllClose(upper, np.triu(luf)[box], cond=cond)
        # with self.subTest("wide"):
        cond = np.linalg.cond(m_sb).max()
        lower, upper, piv = la.lu(m_sb, 'separate')
        luf, piv = la.lu(m_sb, 'raw')
        luf = la.transpose(luf)
        self.assertArrayAllClose(tril(lower), tril(luf)[box[:-1]], cond=cond)
        self.assertArrayAllClose(upper, np.triu(luf), cond=cond)

    @expectedFailure
    @errstate
    @hy.given(hn.constant('(a,a)', ['d', 'D'], min_side=2))
    def test_low_rank(self, ones_ss):
        unitary, right = la.qr(ones_ss)
        self.assertArrayAllClose(unitary @ right, ones_ss)
        lower, upper, _ = la.lu(ones_ss)
        self.assertArrayAllClose(lower @ upper, ones_ss)
        with self.assertRaisesRegex(*utn.invalid_err):
            la.solve(ones_ss, ones_ss[..., :2])
class TestSolveVectors(TestCaseNumpy):
    """Testing (r)solve, (r)solve_lu and (r)lu_solve with vectors"""
    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a),(a)', 'd'))
    def test_solve_flexible_signature_with_vectors(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays[:-1]
        v_s = hn.core_only(arrays[-1], dims=1)
        hy.assume(hn.nonsquare(m_sb))
        hy.assume(hn.all_well_behaved(m_ss))
        off_b, y_one = utn.make_off_by_one(m_bb, m_sb)

        # with self.subTest('solve'):
        self.assertArrayShape(gfl.solve(m_ss, v_s), m_ss.shape[:-1])
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.solve(m_bb, v_s)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.solve(m_bs, v_s)
        with self.assertRaisesRegex(*utn.core_dim_err):
            # This would succeed/broadcast error if interpreted as Mv:
            gfl.solve(m_bb[off_b], m_sb[y_one])

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a),(a)', 'd'))
    def test_solve_lu_flexible_signature_with_vectors(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays[:-1]
        v_s = hn.core_only(arrays[-1], dims=1)
        hy.assume(hn.nonsquare(m_sb))
        hy.assume(hn.all_well_behaved(m_ss))
        off_b, y_one = utn.make_off_by_one(m_bb, m_sb)

        # with self.subTest('solve_lu'):
        self.assertArrayShapesAre(gfl.solve_lu(
            m_ss, v_s), (m_ss.shape[:-1], m_ss.shape, m_ss.shape[:-1]))
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.solve_lu(m_bb, v_s)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.solve_lu(m_bs, v_s)
        with self.assertRaisesRegex(*utn.core_dim_err):
            # This would succeed/broadcast error if interpreted as Mv:
            gfl.solve_lu(m_bb[off_b], m_sb[y_one])

    @hy.given(hn.broadcastable('(a,a),(a),(b)', 'd'))
    def test_lu_solve_flexible_signature_with_vectors(self, arrays):
        m_ss = arrays[0]
        v_s, v_b = hn.core_only(*arrays[1:], dims=1)
        hy.assume(len(v_s) != len(v_b))
        hy.assume(hn.all_well_behaved(m_ss))

        # with self.subTest('lu_solve'):
        _, x_f, i_p = gfl.solve_lu(m_ss, v_s)
        self.assertArrayShape(gfl.lu_solve(x_f, i_p, v_s), m_ss.shape[:-1])
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.lu_solve(x_f, i_p, v_b)
        # with self.subTest('rlu_solve'):
        self.assertArrayShape(gfl.rlu_solve(v_s, x_f, i_p), m_ss.shape[:-1])
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rlu_solve(v_b, x_f, i_p)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(a)', 'd'))
    def test_rsolve_flexible_signature_with_vectors(self, arrays):
        m_ss, m_sb, m_bb = arrays[:-1]
        v_s = hn.core_only(arrays[-1], dims=1)
        hy.assume(hn.nonsquare(m_sb))
        hy.assume(hn.all_well_behaved(m_ss))
        off_b, y_one = utn.make_off_by_one(m_ss, m_sb)

        # with self.subTest('rsolve'):
        self.assertArrayShape(gfl.rsolve(v_s, m_ss), m_ss.shape[:-1])
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rsolve(v_s, m_bb)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rsolve(v_s, m_sb)
        with self.assertRaisesRegex(*utn.core_dim_err):
            # This would succeed/broadcast error if interpreted as vM:
            gfl.rsolve(m_sb[y_one], m_ss[off_b])

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(a)', 'd'))
    def test_rsolve_lu_flexible_signature_with_vectors(self, arrays):
        m_ss, m_sb, m_bb = arrays[:-1]
        v_s = hn.core_only(arrays[-1], dims=1)
        hy.assume(hn.nonsquare(m_sb))
        hy.assume(hn.all_well_behaved(m_ss))

        # with self.subTest('rsolve_lu'):
        self.assertArrayShapesAre(gfl.rsolve_lu(
            v_s, m_ss), (m_ss.shape[:-1], m_ss.shape, m_ss.shape[:-1]))
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rsolve_lu(v_s, m_bb)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rsolve_lu(v_s, m_sb)
        with self.assertRaisesRegex(*utn.core_dim_err):
            # This would succeed/broadcast error if interpreted as vM:
            gfl.rsolve_lu(m_sb, m_ss)

    @hy.given(hn.broadcastable('(a,a),(a,b),(a),(b)', 'd'))
    def test_rlu_solve_flexible_signature_with_vectors(self, arrays):
        m_ss, m_sb = arrays[:-2]
        v_s, v_b = hn.core_only(*arrays[-2:], dims=1)
        hy.assume(hn.nonsquare(m_sb))
        hy.assume(hn.all_well_behaved(m_ss))
        off_b, y_one = utn.make_off_by_one(m_ss, m_sb)

        # with self.subTest('rlu_solve'):
        _, x_f, i_p = gfl.rsolve_lu(v_s, m_ss)
        self.assertArrayShape(gfl.rlu_solve(v_s, x_f, i_p), m_ss.shape[:-1])
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rlu_solve(v_b, x_f, i_p)
        with self.assertRaisesRegex(*utn.core_dim_err):
            # This would succeed/broadcast error if interpreted as vM:
            gfl.rlu_solve(m_sb[y_one], x_f[off_b], i_p[off_b])
        self.assertArrayShape(gfl.lu_solve(x_f, i_p, v_s), m_ss.shape[:-1])
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.lu_solve(x_f, i_p, v_b)
class TestLU(TestCaseNumpy):
    """Testing LU decomposition"""
    @hy.given(hn.broadcastable('(a,b),(b,b),(b,a)', 'd'))
    def test_lu_basic_returns_expected_shapes(self, arrays):
        m_sb, m_bb, m_bs = arrays
        wide, big, tall = [arr.shape for arr in arrays]
        hy.assume(hn.wide(m_sb))

        # with self.subTest(msg="square"):
        self.assertArrayShapesAre(gfl.lu_m(m_bb), (big, big, big[:-1]))
        self.assertArrayShapesAre(gfl.lu_n(m_bb), (big, big, big[:-1]))
        # with self.subTest(msg="wide"):
        self.assertArrayShapesAre(gfl.lu_m(m_sb),
                                  (utn.chop(wide), wide, wide[:-1]))
        self.assertArrayShapesAre(gfl.lu_n(m_sb),
                                  (wide, utn.grow(wide), utn.drop(wide)))
        # with self.subTest(msg="tall"):
        self.assertArrayShapesAre(gfl.lu_m(m_bs),
                                  (utn.grow(tall), tall, tall[:-1]))
        self.assertArrayShapesAre(gfl.lu_n(m_bs),
                                  (tall, utn.chop(tall), utn.drop(tall)))

    @hy.given(hn.broadcastable('(a,b),(b,b),(b,a)', 'd'))
    def test_lu_raw_returns_expected_shapes(self, arrays):
        m_sb, m_bb, m_bs = arrays
        wide, big, tall = [arr.shape for arr in arrays]
        hy.assume(hn.wide(m_sb))

        # with self.subTest(msg="square"):
        self.assertArrayShapesAre(gfl.lu_rawm(m_bb), (big, big[:-1]))
        # with self.subTest(msg="wide"):
        self.assertArrayShapesAre(gfl.lu_rawm(m_sb),
                                  (utn.trnsp(wide), wide[:-1]))
        # with self.subTest(msg="tall"):
        self.assertArrayShapesAre(gfl.lu_rawn(m_bs),
                                  (utn.trnsp(tall), utn.drop(tall)))

    @hy.given(hn.broadcastable('(a,a)', None))
    def test_lu_basic_returns_expected_values_square(self, m_bb):
        big = m_bb.shape
        cond = np.linalg.cond(m_bb).max()

        sq_l, sq_u, sq_ip = gfl.lu_m(m_bb)
        squ = gfl.rpivot(sq_l @ sq_u, sq_ip)
        sqp = gfl.pivot(m_bb, sq_ip)
        dinds = (..., ) + np.diag_indices(big[-1], 2)  # to check l
        uinds = (..., ) + np.triu_indices(big[-1], 1)  # to check l
        linds = (..., ) + np.tril_indices(big[-1], -1)  # to check u
        # with self.subTest(msg="square"):
        self.assertArrayAllClose(sq_l[dinds], 1.)
        self.assertArrayAllClose(sq_l[uinds], 0.)
        self.assertArrayAllClose(sq_u[linds], 0.)
        self.assertArrayAllClose(sq_l @ sq_u, sqp, cond=cond)
        self.assertArrayAllClose(squ, m_bb, cond=cond)

    @hy.given(hn.broadcastable('(a,b)', None))
    def test_lu_basic_returns_expected_values_wide(self, m_sb):
        wide = m_sb.shape
        hy.assume(hn.wide(m_sb))
        cond = np.linalg.cond(m_sb).max()

        wd_l, wd_u, wd_ip = gfl.lu_m(m_sb)
        wid = gfl.rpivot(wd_l @ wd_u, wd_ip)
        wdp = gfl.pivot(m_sb, wd_ip)
        dinds = (..., ) + np.diag_indices(wide[-2], 2)  # to check l
        uinds = (..., ) + np.triu_indices(wide[-2], 1, wide[-2])  # to check l
        linds = (..., ) + np.tril_indices(wide[-2], -1, wide[-1])  # to check u
        # with self.subTest(msg="wide"):
        self.assertArrayAllClose(wd_l[dinds], 1.)
        self.assertArrayAllClose(wd_l[uinds], 0.)
        self.assertArrayAllClose(wd_u[linds], 0.)
        self.assertArrayAllClose(wd_l @ wd_u, wdp, cond=cond)
        self.assertArrayAllClose(wid, m_sb, cond=cond)

    @hy.given(hn.broadcastable('(a,b)', None))
    def test_lu_basic_returns_expected_values_tall(self, m_bs):
        tall = m_bs.shape
        hy.assume(hn.tall(m_bs))
        cond = np.linalg.cond(m_bs).max()

        tl_l, tl_u, tl_ip = gfl.lu_n(m_bs)
        tal = gfl.rpivot(tl_l @ tl_u, tl_ip)
        tlp = gfl.pivot(m_bs, tl_ip)
        dinds = (..., ) + np.diag_indices(tall[-1], 2)  # to check l
        uinds = (..., ) + np.triu_indices(tall[-2], 1, tall[-1])  # to check l
        linds = (..., ) + np.tril_indices(tall[-1], -1, tall[-1])  # to check u
        # with self.subTest(msg="tall"):
        self.assertArrayAllClose(tl_l[dinds], 1.)
        self.assertArrayAllClose(tl_l[uinds], 0.)
        self.assertArrayAllClose(tl_u[linds], 0.)
        self.assertArrayAllClose(tl_l @ tl_u, tlp, cond=cond)
        self.assertArrayAllClose(tal, m_bs, cond=cond)

    @hy.given(hn.broadcastable('(a,a)', None))
    def test_lu_raw_returns_expected_values_square(self, m_bb):
        sq_l, sq_u, sq_ip0 = gfl.lu_m(m_bb)
        sq_f, sq_ip = gfl.lu_rawm(m_bb)
        sq_f = la.transpose(sq_f)
        linds = (..., ) + np.tril_indices(m_bb.shape[-1], -1)
        uinds = (..., ) + np.triu_indices(m_bb.shape[-1], 0)
        # with self.subTest(msg="square"):
        cond = np.linalg.cond(m_bb).max()
        self.assertArrayAllClose(sq_f[linds], sq_l[linds], cond=cond)
        self.assertArrayAllClose(sq_f[uinds], sq_u[uinds], cond=cond)
        self.assertEqual(sq_ip, sq_ip0)

    @hy.given(hn.broadcastable('(a,b)', None))
    def test_lu_raw_returns_expected_values_wide(self, m_sb):
        wide = m_sb.shape
        hy.assume(hn.wide(m_sb))
        cond = np.linalg.cond(m_sb).max()

        wd_l, wd_u, wd_ip0 = gfl.lu_m(m_sb)
        wd_f, wd_ip = gfl.lu_rawm(m_sb)
        wd_f = la.transpose(wd_f)
        linds = (..., ) + np.tril_indices(wide[-2], -1, wide[-1])
        uinds = (..., ) + np.triu_indices(wide[-2], 0, wide[-1])
        # with self.subTest(msg="wide"):
        self.assertArrayAllClose(wd_f[linds], wd_l[linds], cond=cond)
        self.assertArrayAllClose(wd_f[uinds], wd_u[uinds], cond=cond)
        self.assertEqual(wd_ip, wd_ip0)

    @hy.given(hn.broadcastable('(a,b)', None))
    def test_lu_raw_returns_expected_values_tall(self, m_bs):
        tall = m_bs.shape
        hy.assume(hn.tall(m_bs))
        cond = np.linalg.cond(m_bs).max()

        tl_l, tl_u, tl_ip0 = gfl.lu_n(m_bs)
        tl_f, tl_ip = gfl.lu_rawn(m_bs)
        tl_f = la.transpose(tl_f)
        linds = (..., ) + np.tril_indices(tall[-2], -1, tall[-1])
        uinds = (..., ) + np.triu_indices(tall[-2], 0, tall[-1])
        # with self.subTest(msg="tall"):
        self.assertArrayAllClose(tl_f[linds], tl_l[linds], cond=cond)
        self.assertArrayAllClose(tl_f[uinds], tl_u[uinds], cond=cond)
        self.assertEqual(tl_ip, tl_ip0)

    @hy.given(hn.broadcastable('(a,a)', 'd'))
    def test_inv_returns_expected_shapes(self, m_bb):
        big = m_bb.shape
        hy.assume(hn.all_well_behaved(m_bb))

        # with self.subTest(msg='inv'):
        self.assertArrayShape(gfl.inv(m_bb), big)
        # with self.subTest(msg='inv,+lu'):
        _, square_f, square_ip = gfl.inv_lu(m_bb)
        self.assertArrayShapesAre(gfl.inv_lu(m_bb), (big, big, big[:-1]))
        # with self.subTest(msg='inv,-lu'):
        self.assertArrayShape(gfl.lu_inv(square_f, square_ip), big)

    @hy.given(hn.broadcastable('(a,a)', None))
    def test_inv_returns_expected_values(self, m_bb):
        hy.assume(hn.all_well_behaved(m_bb))
        cond = np.linalg.cond(m_bb).max()

        # with self.subTest(msg='inv'):
        id_b = np.identity(m_bb.shape[-1], m_bb.dtype)
        square_i = gfl.inv(m_bb)
        self.assertArrayAllClose(m_bb @ square_i, id_b, cond=cond)
        self.assertArrayAllClose(square_i @ m_bb, id_b, cond=cond)
        # with self.subTest(msg='inv,+lu'):
        square_if, square_f, square_ip = gfl.inv_lu(m_bb)
        luf, ipr = gfl.lu_rawn(m_bb)
        self.assertArrayAllClose(square_if, square_i, cond=cond)
        self.assertArrayAllClose(square_f, luf)
        self.assertEqual(square_ip, ipr)
        # with self.subTest(msg='inv,-lu'):
        square_fi = gfl.lu_inv(square_f, square_ip)
        self.assertArrayAllClose(square_fi, square_i, cond=cond)
class TestSolveShape(TestCaseNumpy):
    """Testing (r)solve, (r)solve_lu and (r)lu_solve"""
    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', 'd'))
    def test_solve_returns_expected_shapes(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.nonsquare(m_sb))
        hy.assume(hn.all_well_behaved(m_ss))

        expect = utn.array_return_shape('(a,a),(a,b)->(a,b)', m_ss, m_sb)
        self.assertArrayShape(gfl.solve(m_ss, m_sb), expect)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.solve(m_bb, m_sb)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.solve(m_bs, m_sb)
        with self.assertRaisesRegex(*utn.broadcast_err):
            gfl.solve(*utn.make_bad_broadcast(m_ss, m_sb))

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', 'd'))
    def test_rsolve_returns_expected_shapes(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.nonsquare(m_sb))
        hy.assume(hn.all_well_behaved(m_bb))

        expect = utn.array_return_shape('(a,b),(b,b)->(a,b)', m_sb, m_bb)
        self.assertArrayShape(gfl.rsolve(m_sb, m_bb), expect)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rsolve(m_bs, m_bb)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rsolve(m_bs, m_sb)
        with self.assertRaisesRegex(*utn.broadcast_err):
            gfl.rsolve(*utn.make_bad_broadcast(m_bs, m_ss))

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', 'd'))
    def test_solve_lu_returns_expected_shapes(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.nonsquare(m_sb))
        hy.assume(hn.all_well_behaved(m_ss))

        expect = utn.array_return_shape('(a,a),(a,b)->(a,b)', m_ss, m_sb)
        expect_f = expect[:-2] + 2 * m_ss.shape[-1:]
        result = gfl.solve_lu(m_ss, m_sb)
        self.assertArrayShapesAre(result, (expect, expect_f, expect_f[:-1]))
        self.assertArrayShapesAre(unbroadcast_factors(m_ss, *result[1:]),
                                  (m_ss.shape, m_ss.shape[:-1]))
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.solve_lu(m_bb, m_sb)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.solve_lu(m_bs, m_sb)
        with self.assertRaisesRegex(*utn.broadcast_err):
            gfl.solve_lu(*utn.make_bad_broadcast(m_ss, m_sb))

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', 'd'))
    def test_lu_solve_returns_expected_shapes(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.nonsquare(m_sb))
        hy.assume(hn.all_well_behaved(m_ss))

        _, x_f, i_p = gfl.solve_lu(m_ss, m_sb)
        expect = utn.array_return_shape('(a,a),(a,b)->(a,b)', m_ss, m_sb)
        self.assertArrayShape(gfl.lu_solve(x_f, i_p, m_sb), expect)
        expect = utn.array_return_shape('(a,b),(b,b)->(a,b)', m_bs, x_f)
        self.assertArrayShape(gfl.rlu_solve(m_bs, x_f, i_p), expect)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.lu_solve(x_f, i_p, m_bb)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rlu_solve(m_sb, x_f, i_p)
        _, x_f, i_p = gfl.solve_lu(m_ss, m_sb)
        with self.assertRaisesRegex(*utn.broadcast_err):
            gfl.lu_solve(x_f, *utn.make_bad_broadcast(i_p, m_sb, (1, 2)))
        x_f, i_p = unbroadcast_factors(m_ss, x_f, i_p)
        expect = utn.array_return_shape('(a,b),(b,b)->(a,b)', m_bs, m_ss)
        self.assertArrayShape(gfl.rlu_solve(m_bs, x_f, i_p), expect)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', 'd'))
    def test_rsolve_lu_returns_expected_shapes(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.nonsquare(m_sb))
        hy.assume(hn.all_well_behaved(m_bb))

        expect = utn.array_return_shape('(a,b),(b,b)->(a,b)', m_sb, m_bb)
        expect_f = expect[:-2] + m_bb.shape[-2:]
        result = gfl.rsolve_lu(m_sb, m_bb)
        self.assertArrayShapesAre(result, (expect, expect_f, expect_f[:-1]))
        self.assertArrayShapesAre(unbroadcast_factors(m_bb, *result[1:]),
                                  (m_bb.shape, m_bb.shape[:-1]))
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rsolve_lu(m_bs, m_bb)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rsolve_lu(m_bs, m_sb)
        with self.assertRaisesRegex(*utn.broadcast_err):
            gfl.rsolve_lu(*utn.make_bad_broadcast(m_bs, m_ss))

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a)', 'd'))
    def test_rlu_solve_returns_expected_shapes(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays
        hy.assume(hn.nonsquare(m_sb))
        hy.assume(hn.all_well_behaved(m_bb))

        _, x_f, i_p = gfl.rsolve_lu(m_sb, m_bb)
        expect = utn.array_return_shape('(a,b),(b,b)->(a,b)', m_sb, x_f)
        self.assertArrayShape(gfl.rlu_solve(m_sb, x_f, i_p), expect)
        expect = utn.array_return_shape('(a,a),(a,b)->(a,b)', x_f, m_bs)
        self.assertArrayShape(gfl.lu_solve(x_f, i_p, m_bs), expect)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rlu_solve(m_ss, x_f, i_p)
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.lu_solve(x_f, i_p, m_sb)
        _, x_f, i_p = gfl.rsolve_lu(m_sb, m_bb)
        with self.assertRaisesRegex(*utn.broadcast_err):
            gfl.rlu_solve(*utn.make_bad_broadcast(m_sb, x_f), i_p)
        x_f, i_p = unbroadcast_factors(m_bb, x_f, i_p)
        expect = utn.array_return_shape('(a,a),(a,b)->(a,b)', m_bb, m_bs)
        self.assertArrayShape(gfl.lu_solve(x_f, i_p, m_bs), expect)
class TestArray(TestCaseNumpy):
    """Testing lnarray"""
    @hy.given(hn.broadcastable('(a,b),(b,a),(a,a),(b,b)', 'd'))
    def test_return_array_types(self, arrays):
        m_sb_n, m_bs_n = arrays[:2]
        m_sb, m_bs, m_ss, m_bb = view_as(*arrays)
        m_bs_m, m_ss_m, m_bb_m = hn.core_only(m_bs, m_ss, m_bb)
        hy.assume(hn.all_well_behaved(m_ss, m_bb))
        hy.assume(m_sb.ndim != m_ss.ndim - 1)  # np..solve's broadcasting issue

        self.assertIsInstance(m_sb @ m_bs, la.lnarray)
        self.assertIsInstance(m_sb_n @ m_bs, la.lnarray)
        expect = utn.array_return_shape('(a,b),(b,c)->(a,c)', m_bs, m_sb)
        tw_o = np.empty(expect, m_bs.dtype)
        tw_r = la.matmul(m_bs, m_sb_n, tw_o)
        self.assertIsInstance(tw_r, np.ndarray)
        self.assertIsInstance(tw_o, np.ndarray)
        self.assertIsInstance(np.matmul(m_bs, m_sb_n), np.ndarray)
        self.assertIsInstance(la.solve(m_ss, m_sb_n), la.lnarray)
        self.assertIsInstance(nl.solve(m_ss, m_sb_n), np.ndarray)
        self.assertIsInstance(la.lstsq(m_bs, m_bb), la.lnarray)
        self.assertIsInstance(
            nl.lstsq(m_bs_m, m_bb_m, rcond=None)[0], np.ndarray)
        self.assertIsInstance(la.lu(m_ss)[0], la.lnarray)
        self.assertIsInstance(la.lu(m_bs_n)[0], np.ndarray)
        self.assertIsInstance(la.qr(m_ss)[0], la.lnarray)
        self.assertIsInstance(la.qr(m_bs_n)[0], np.ndarray)
        self.assertIsInstance(la.lq(m_ss)[0], la.lnarray)
        self.assertIsInstance(la.lq(m_bs_n)[0], np.ndarray)
        self.assertIsInstance(la.lqr(m_ss)[0], la.lnarray)
        self.assertIsInstance(la.lqr(m_bs_n)[0], np.ndarray)
        self.assertIsInstance(nl.qr(m_ss_m)[0], np.ndarray)

    @hy.given(hn.broadcastable('(a,b),(b,b)', 'D'))
    def test_lnarray_shape_methods(self, arrays):
        m_bs, m_ss = view_as(*arrays)
        tall, smol = m_bs.shape, m_ss.shape
        hy.assume(hn.tall(m_bs))
        hy.assume(np.max(np.abs(m_bs.imag)) > .01)
        hy.assume(np.max(np.abs(m_bs.real)) / np.max(np.abs(m_bs.imag)) < 1e3)

        expect = utn.trnsp(tall)
        self.assertArrayShape(m_bs.t, expect)
        self.assertArrayShape(m_bs.h, expect)
        self.assertArrayNotAllClose(m_bs.t, m_bs.h)
        self.assertArrayShape(m_ss.c, smol + (1, ))
        self.assertArrayShape(m_bs.c.uc, tall)
        expect = insert(smol)
        self.assertArrayShape(m_ss.r, expect)
        self.assertArrayShape(m_bs.r.ur, tall)
        self.assertArrayShape(m_ss.s, smol + (1, 1))
        self.assertArrayShape(m_bs.s.us, tall)

        # expect = smol[:1] + (1,) + smol[1:2] + (1,) + smol[2:]
        expect = insert(insert(smol, 2), 1)
        self.assertArrayShape(m_ss.expand_dims((1, 3)), expect)
        expect = tall[:1] + (np.prod(tall[1:4]), ) + tall[4:]
        self.assertArrayShape(m_bs.flattish(1, 4), expect)
        with self.assertRaisesRegex(ValueError, "repeated axis"):
            m_bs.expand_dims((m_bs.ndim - 1, -3))
        half = (m_bs.ndim + 2) // 2 + 1
        with self.assertRaises(ValueError):
            (m_bs.s).flattish(half, -half)

    @hy.given(hn.broadcastable('(a,b),(b,b),(b)', None))
    def test_lnarray_operations_return_expected_values(self, arrays):
        m_bs, m_ss, vec = view_as(*arrays)
        m_bs_m = hn.core_only(m_bs)
        vec = hn.core_only(vec, dims=1)
        hy.assume(hn.tall(m_bs))
        hy.assume(m_ss.ndim != 3)  # causes np..solve's broadcasting issue
        hy.assume(hn.all_well_behaved(m_ss, m_bs_m))

        expect = utn.array_return_shape('(a,b),(b,c)->(a,c)', m_bs, m_ss)
        ts_o = np.empty(expect, m_ss.dtype)
        ts_r = la.matmul(m_bs, m_ss, ts_o)
        self.assertArrayAllClose(ts_r, ts_o)
        self.assertArrayAllClose(m_bs @ m_ss, np.matmul(m_bs, m_ss))
        self.assertArrayAllClose(m_bs @ m_ss, np.matmul(m_bs, m_ss))
        self.assertArrayAllClose(m_bs @ vec, np.matmul(m_bs, vec))
        cond = np.linalg.cond(m_ss).max()
        self.assertArrayAllClose(gf.solve(m_ss, vec),
                                 nl.solve(m_ss, vec.c).uc,
                                 cond=cond)
        cond = np.linalg.cond(m_bs_m).max()
        self.assertArrayAllClose(gf.lstsq(m_bs_m.t, vec),
                                 nl.lstsq(m_bs_m.t, vec, rcond=None)[0],
                                 cond=cond)
        self.assertArrayAllClose(gf.rmatmul(m_ss, m_bs), np.matmul(m_bs, m_ss))
class TestPinvarray(TestCaseNumpy):
    """test pinvarray & invarray classes
    """
    @hy.given(hn.broadcastable('(a,a),(b,a)', ['d', 'D']))
    def test_pinvarray_attribute_types(self, arrays):
        m_ss, m_bs = view_as(*arrays)
        hy.assume(hn.all_well_behaved(m_ss))

        self.assertIsInstance(m_ss.pinv, la.pinvarray)
        self.assertIsInstance(m_ss.inv, la.invarray)
        self.assertIs(m_ss.pinv.dtype, m_bs.dtype)
        self.assertIsInstance(m_ss.pinv.pinv, la.lnarray)
        self.assertIsInstance(m_ss.inv.inv, la.lnarray)
        self.assertIsInstance(m_ss.pinv(), la.lnarray)
        self.assertIsInstance(m_ss.inv(), la.lnarray)

        m_bs_p = la.pinvarray(m_bs)
        self.assertIsInstance(m_bs_p, la.pinvarray)
        self.assertIsInstance(m_bs_p.pinv, la.lnarray)
        self.assertIsInstance(2 * m_bs_p, la.pinvarray)
        self.assertIsInstance((2 * m_bs_p).pinv, la.lnarray)
        pout = la.pinvarray(np.empty_like(m_bs))
        np.multiply(2, m_bs_p, pout)
        self.assertIsInstance(pout, la.pinvarray)
        self.assertIsInstance(pout.pinv, la.lnarray)
        with self.assertRaises(AttributeError):
            m_bs_p.inv  # pylint: disable=no-member,pointless-statement
        with self.assertRaises(TypeError):
            m_ss.inv.pinv  # pylint: disable=pointless-statement

    @hy.given(hn.matrices_b)
    def test_pinvarray_shape_methods(self, array):
        m_bs = array.view(la.lnarray)
        hy.assume(hn.nonsquare(m_bs))
        hy.assume(hn.all_well_behaved(m_bs))
        m_bs_p = m_bs.pinv
        expect = utn.trnsp(m_bs.shape)

        self.assertEqual(m_bs_p.ndim, len(expect))
        self.assertEqual(m_bs_p.shape, expect)
        self.assertEqual(m_bs_p.size, np.prod(expect))
        self.assertArrayShape(m_bs_p(), expect)
        with self.assertRaises(ValueError):
            m_bs.inv  # pylint: disable=pointless-statement
        m_bs_p = m_bs.c.pinv
        expect = insert(m_bs.shape)
        now_expect = expect[1::-1] + expect[2:]
        self.assertArrayShape(m_bs_p.swapaxes(0, 1), now_expect)
        now_expect = expect[2::-1] + expect[3:]
        self.assertArrayShape(m_bs_p.swapaxes(0, 2), now_expect)
        now_expect = utn.trnsp(expect)
        self.assertArrayShape(m_bs_p.swapaxes(-1, -2), now_expect)

    @hy.given(hn.broadcastable('(a,b),(b,a),(b,a)', None))
    def test_pinvarray_in_functions(self, arrays):
        m_sb, high, m_bs = view_as(*arrays)
        # hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_bs))
        cond = np.linalg.cond(m_bs).max()

        self.assertArrayAllClose(gf.matmul(m_bs.pinv, high),
                                 gf.lstsq(m_bs, high),
                                 cond=cond)
        self.assertArrayAllClose(gf.matmul(m_sb, m_bs.pinv.t),
                                 gf.rlstsq(m_sb, m_bs.t),
                                 cond=cond)
        xpout = la.pinvarray(np.empty_like(m_bs))
        m_bs_p = np.multiply(m_bs.pinv, 2, out=xpout)
        self.assertArrayAllClose(m_bs_p.pinv, xpout.pinv)
        self.assertArrayAllClose(m_bs_p.pinv, m_bs / 2)
        with self.assertRaises(TypeError):
            gf.matmul(m_bs.pinv, m_sb.pinv)
        self.assertArrayAllClose(gf.lstsq(m_sb.pinv, high),
                                 gf.matmul(m_sb, high))
        with self.assertRaises(TypeError):
            gf.lstsq(high, m_sb.pinv)
        self.assertArrayAllClose(gf.rlstsq(high.t, m_sb.t.pinv),
                                 gf.matmul(high.t, m_sb.t))
        with self.assertRaises(TypeError):
            gf.rlstsq(m_sb.t.pinv, high.t)
        with self.assertRaises(TypeError):
            gf.rmatmul(m_sb.pinv, m_bs.pinv)
        with self.assertRaises(TypeError):
            gf.solve(m_sb.pinv, high)
        with self.assertRaises(TypeError):
            gf.rsolve(m_sb, m_bs.pinv)

    @hy.given(hn.broadcastable('(a,a),(b,a),(a,b),(a,a)', None))
    def test_invarray_in_functions(self, arrays):
        m_ss, m_bs, m_sb, mini = view_as(*arrays)
        # hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_ss, mini))

        cond = np.linalg.cond(m_ss).max()
        self.assertArrayAllClose(gf.matmul(m_ss.inv, m_sb),
                                 gf.solve(m_ss, m_sb),
                                 cond=cond)
        self.assertArrayAllClose(gf.matmul(m_bs, m_ss.inv),
                                 gf.rsolve(m_bs, m_ss),
                                 cond=cond)
        self.assertArrayAllClose(
            gf.matmul(m_ss.inv, mini.inv).inv, mini @ m_ss)
        self.assertArrayAllClose(gf.solve(m_ss.inv, m_sb),
                                 gf.matmul(m_ss, m_sb))
        self.assertArrayAllClose(
            gf.solve(mini, m_ss.inv).inv, gf.matmul(m_ss, mini))
        self.assertArrayAllClose(gf.solve(mini.inv, m_ss.inv),
                                 gf.rsolve(mini, m_ss),
                                 cond=cond)
        self.assertArrayAllClose(gf.rsolve(m_ss, mini.inv),
                                 gf.matmul(m_ss, mini))
        self.assertArrayAllClose(
            gf.rsolve(mini.inv, m_ss).inv, gf.matmul(m_ss, mini))
        cond = np.linalg.cond(mini).max()
        self.assertArrayAllClose(gf.rsolve(mini.inv, m_ss.inv),
                                 gf.solve(mini, m_ss),
                                 cond=cond)
        self.assertArrayAllClose(gf.rmatmul(m_ss, mini.inv),
                                 gf.solve(mini, m_ss),
                                 cond=cond)
        self.assertArrayAllClose(gf.rmatmul(mini.inv, m_ss),
                                 gf.rsolve(m_ss, mini),
                                 cond=cond)
        self.assertArrayAllClose(
            gf.rmatmul(mini.inv, m_ss.inv).inv, mini @ m_ss)

    @hy.given(hn.broadcastable('(a,a),(b,a),(a,b),(a,a)', None))
    def test_bad_p_invarray_combos_in_functions(self, arrays):
        m_ss, m_bs, m_sb, mini = view_as(*arrays)
        # hy.assume(hn.tall(m_bs))

        with self.assertRaises(TypeError):
            la.solve(m_sb.pinv, mini)
        with self.assertRaises(TypeError):
            la.rsolve(mini, m_bs.pinv)
        with self.assertRaises(TypeError):
            la.solve(mini, m_bs.pinv)
        with self.assertRaises(TypeError):
            la.rsolve(m_sb.pinv, mini)
        with self.assertRaises(TypeError):
            la.solve(m_sb.pinv, m_bs.pinv)
        with self.assertRaises(TypeError):
            la.rsolve(m_sb.pinv, m_bs.pinv)
        with self.assertRaises(TypeError):
            la.matmul(m_ss.inv, m_bs.pinv)
        with self.assertRaises(TypeError):
            la.matmul(m_sb.pinv, mini.inv)
        with self.assertRaises(TypeError):
            la.solve(m_bs.pinv, mini.inv)
        with self.assertRaises(TypeError):
            la.rsolve(mini.inv, m_sb.pinv)

    @hy.given(hn.broadcastable('(a,a),(b,a),(a,b),(a,a)', None))
    def test_good_p_invarray_combos_in_lstsq(self, arrays):
        m_ss, m_bs, m_sb, mini = view_as(*arrays)
        # hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_ss, mini, m_bs, m_sb))

        self.assertArrayAllClose(la.lstsq(mini.inv, m_sb),
                                 la.matmul(mini, m_sb))
        self.assertArrayAllClose(la.rlstsq(m_bs, mini.inv),
                                 la.matmul(m_bs, mini))
        cond = np.linalg.cond(m_bs).max()
        self.assertArrayAllClose(la.lstsq(mini.inv, m_bs.pinv),
                                 la.rlstsq(mini, m_bs),
                                 cond=cond)
        cond = np.linalg.cond(mini).max()
        self.assertArrayAllClose(la.rlstsq(mini.inv, m_sb.pinv),
                                 la.solve(mini, m_sb),
                                 cond=cond)
        cond = np.linalg.cond(m_ss).max()
        self.assertArrayAllClose(la.lstsq(mini.inv, m_ss.inv),
                                 la.rsolve(mini, m_ss),
                                 cond=cond)
        cond = np.linalg.cond(mini).max()
        self.assertArrayAllClose(la.rlstsq(mini.inv, m_ss.inv),
                                 la.solve(mini, m_ss),
                                 cond=cond)
        cond = np.linalg.cond(m_ss).max()
        self.assertArrayAllClose(la.lstsq(m_bs.pinv, m_ss.inv),
                                 la.rsolve(m_bs, m_ss),
                                 cond=cond)
        cond = np.linalg.cond(m_sb).max()
        self.assertArrayAllClose(la.rlstsq(m_sb.pinv, m_ss.inv),
                                 la.lstsq(m_sb, m_ss),
                                 cond=cond)

    @hy.given(hn.broadcastable('(a,a),(b,a),(a,b),(a,a)', None))
    def test_good_p_invarray_combos_in_solve(self, arrays):
        m_ss, m_bs, m_sb, mini = view_as(*arrays)
        # hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_bs, m_sb))
        # hy.assume(hn.all_well_behaved(m_ss, mini))

        cond = np.linalg.cond(m_bs).max()
        self.assertArrayAllClose(la.solve(m_ss.inv, m_bs.pinv),
                                 la.rlstsq(m_ss, m_bs),
                                 cond=cond)
        cond = np.linalg.cond(m_sb).max()
        self.assertArrayAllClose(la.rsolve(m_sb.pinv, mini.inv),
                                 la.lstsq(m_sb, mini),
                                 cond=cond)

    @hy.given(hn.broadcastable('(a,b),(b,a),(b,a),()', None))
    def test_pinvarray_operators(self, arrays):
        m_sb, high, m_bs, scal = view_as(*arrays)
        scal[np.abs(scal) < 1e-5] += 1.
        scal = scal.s
        # hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_bs))

        cond = np.linalg.cond(m_bs).max()
        self.assertArrayAllClose(m_bs.pinv @ high,
                                 gf.lstsq(m_bs, high),
                                 cond=cond)
        self.assertArrayAllClose(m_bs.pinv() @ high,
                                 gf.lstsq(m_bs, high),
                                 cond=cond)
        self.assertArrayAllClose(m_sb @ m_bs.pinv.t,
                                 gf.rlstsq(m_sb, m_bs.t),
                                 cond=cond)
        with self.assertRaises(TypeError):
            m_bs.pinv @ m_sb.pinv  # pylint: disable=pointless-statement
        self.assertArrayAllClose((m_bs.pinv * 3.5).pinv, m_bs / 3.5)
        self.assertArrayAllClose((2.4 * m_bs.pinv).pinv, m_bs / 2.4)
        self.assertArrayAllClose((m_bs.pinv / 3.564).pinv, m_bs * 3.564)
        with self.assertRaises(TypeError):
            65 / m_bs.pinv  # pylint: disable=pointless-statement
        self.assertArrayAllClose((m_bs.pinv * scal).pinv, m_bs / scal)
        self.assertArrayAllClose((scal * m_bs.pinv).pinv, m_bs / scal)
        self.assertArrayAllClose((m_bs.pinv / scal).pinv, m_bs * scal)
        with self.assertRaises(TypeError):
            scal / m_bs.pinv  # pylint: disable=pointless-statement
        with self.assertRaises(TypeError):
            scal.pinv * m_bs.pinv  # pylint: disable=pointless-statement
        with self.assertRaises(TypeError):
            m_bs.pinv + m_sb  # pylint: disable=pointless-statement
        told = 1. * m_bs
        m_bs_p = m_bs.pinv
        m_bs_p *= 2
        self.assertArrayAllClose(m_bs, told / 2)

    @hy.given(hn.broadcastable('(a,a),(b,a),(a,b),(a,a),()', None))
    def test_invarray_operators(self, arrays):
        m_ss, m_bs, m_sb, mini, scal = view_as(*arrays)
        scal[np.abs(scal) < 1e-5] += 1.
        scal = scal.s
        # hy.assume(hn.tall(m_bs))
        hy.assume(hn.all_well_behaved(m_ss, mini))

        cond = np.linalg.cond(m_ss).max()
        self.assertArrayAllClose(m_ss.inv @ m_sb,
                                 gf.solve(m_ss, m_sb),
                                 cond=cond)
        self.assertArrayAllClose(m_ss.inv() @ m_sb,
                                 gf.solve(m_ss, m_sb),
                                 cond=cond)
        self.assertArrayAllClose(m_bs @ m_ss.inv,
                                 gf.rsolve(m_bs, m_ss),
                                 cond=cond)
        self.assertArrayAllClose((m_ss.inv @ mini.inv).inv, mini @ m_ss)
        self.assertArrayAllClose((m_ss.inv * 3.5).inv, m_ss / 3.5)
        self.assertArrayAllClose((2.4 * m_ss.inv).inv, m_ss / 2.4)
        self.assertArrayAllClose((m_ss.inv / 3.564).inv, m_ss * 3.564)
        with self.assertRaises(TypeError):
            45.564 / m_ss.inv  # pylint: disable=pointless-statement
        self.assertArrayAllClose((mini.inv * scal).inv, mini / scal)
        self.assertArrayAllClose((scal * mini.inv).inv, mini / scal)
        self.assertArrayAllClose((mini.inv / scal).inv, mini * scal)
        with self.assertRaises(TypeError):
            scal / mini.inv  # pylint: disable=pointless-statement
        with self.assertRaises(TypeError):
            scal.inv * mini.inv  # pylint: disable=pointless-statement
        with self.assertRaises(TypeError):
            m_ss + mini.inv  # pylint: disable=pointless-statement
        mini_ss = m_ss @ mini
        mini_i = mini.inv
        mini_i @= m_ss.inv
        self.assertArrayAllClose(mini, mini_ss)
예제 #17
0
class TestBlasVectors(TestCaseNumpy):
    """Testing matmul and rmatmul"""

    def setUp(self):
        super().setUp()
        self.gfm = gfb

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a),(a),(b)', 'd'))
    def test_matmul_flexible_signature_with_vectors(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays[:-2]
        v_s, v_b = hn.core_only(*arrays[-2:], dims=1)
        smol, wide, big, tall = [arr.shape for arr in arrays[:-2]]
        hy.assume(hn.nonsquare(m_sb))
        off_b, y_one = utn.make_off_by_one(m_sb, m_sb)

        # with self.subTest('matrix-vector'):
        self.assertArrayShape(self.gfm.matmul(m_sb, v_b), wide[:-1])
        self.assertArrayShape(self.gfm.matmul(m_bs, v_s), tall[:-1])
        with self.assertRaisesRegex(*utn.core_dim_err):
            self.gfm.matmul(m_sb, v_s)
        with self.assertRaisesRegex(*utn.core_dim_err):
            # This would succeed/broadcast error if interpreted as Mv:
            self.gfm.matmul(m_sb[off_b], m_sb[y_one])
        # with self.subTest('vector-matrix'):
        self.assertArrayShape(self.gfm.matmul(v_s, m_ss), smol[:-1])
        self.assertArrayShape(self.gfm.matmul(v_b, m_bb), big[:-1])
        with self.assertRaisesRegex(*utn.core_dim_err):
            self.gfm.matmul(v_b, m_sb)
        with self.assertRaisesRegex(*utn.core_dim_err):
            # This would succeed/broadcast error if interpreted as vM:
            self.gfm.matmul(m_sb[y_one], m_sb[off_b])
        # with self.subTest('vector-vector'):
        self.assertArrayShape(self.gfm.matmul(v_s, v_s), ())
        with self.assertRaisesRegex(*utn.core_dim_err):
            self.gfm.matmul(v_s, v_b)

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a),(a),(b)', 'd'))
    def test_rmatmul_flexible_signature_with_vectors(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays[:-2]
        v_s, v_b = hn.core_only(*arrays[-2:], dims=1)
        smol, wide, big, tall = [arr.shape for arr in arrays[:-2]]
        hy.assume(hn.nonsquare(m_sb))
        off_b, y_one = utn.make_off_by_one(m_sb, m_sb)

        # with self.subTest('matrix-vector'):
        self.assertArrayShape(self.gfm.rmatmul(v_s, m_bs), tall[:-1])
        self.assertArrayShape(self.gfm.rmatmul(v_b, m_sb), wide[:-1])
        with self.assertRaisesRegex(*utn.core_dim_err):
            self.gfm.rmatmul(v_b, m_bs)
        with self.assertRaisesRegex(*utn.core_dim_err):
            # This would succeed/broadcast error if interpreted as Mv:
            self.gfm.rmatmul(m_sb[y_one], m_sb[off_b])
        # w\ith self.subTest('vector-matrix'):
        self.assertArrayShape(self.gfm.rmatmul(m_ss, v_s), smol[:-1])
        self.assertArrayShape(self.gfm.rmatmul(m_bb, v_b), big[:-1])
        with self.assertRaisesRegex(*utn.core_dim_err):
            self.gfm.rmatmul(m_bs, v_s)
        with self.assertRaisesRegex(*utn.core_dim_err):
            # This would succeed/broadcast error if interpreted as vM:
            self.gfm.rmatmul(m_sb[off_b], m_sb[y_one])
        # with self.subTest('vector-vector'):
        self.assertArrayShape(self.gfm.rmatmul(v_b, v_b), ())
        with self.assertRaisesRegex(*utn.core_dim_err):
            self.gfm.rmatmul(v_b, v_s)
예제 #18
0
numerical_ranges = str_sample('arange linspace logspace geomspace')
# -----------------------------------------------------------------------------
# Random number generators
# -----------------------------------------------------------------------------
# Parameter types:
# (v)ector of (i)ntegers or (r)eals that are zer(o) and/or (p)ositive
# Or (m)ean and Cholesky deccomposition of (cov)ariance
params = {
    'i': st.integers(min_value=-100, max_value=100),
    'iop': st.integers(min_value=0, max_value=100),
    'ip': st.integers(min_value=1, max_value=100),
    'r': hyn.real_numbers(),
    'rop': hyn.real_numbers(min_value=0),
    'rp': hyn.real_numbers(min_value=1e-5),
    'p': hyn.real_numbers(min_value=1e-5, max_value=1),
    'mcov': hyn.broadcastable('(n),(n,n)', 'd', max_dims=0, max_side=20),
    'z': hyn.real_numbers(min_value=1.1, max_value=100),
    'none':  st.none(),
}
params['vrp'] = hn.arrays(float, params['ip'], elements=params['rp'])
params['vp'] = hn.arrays(float, params['ip'], elements=params['p'])
params['viop'] = hn.arrays(int, params['ip'], elements=params['iop'])
# -----------------------------------------------------------------------------
# Method names, grouped by paraneter signature
rnd_methods = {
    # ('_' -> 'standard_'):
    'r_rop': str_sample('gumbel laplace logistic lognormal normal vonmises'),
    'rp_rp': str_sample('beta f wald'),
    'rop': str_sample('exponential poisson rayleigh _gamma weibull'),
    'rp': str_sample('chisquare pareto _t'),
    'p': str_sample('geometric logseries'),
예제 #19
0
class TestLstsqVectors(TestCaseNumpy):
    """Testing (r)lstsq with vectors"""
    @hy.given(hn.broadcastable('(a,b),(b,a),(a),(b)', 'd'))
    def test_lstsq_flexible_signature_with_vectors_mv(self, arrays):
        m_sb, m_bs = arrays[:-2]
        v_s, v_b = hn.core_only(*arrays[-2:], dims=1)
        wide, tall = [arr.shape for arr in arrays[:-2]]
        hy.assume(hn.wide(m_sb))
        off_b, y_one = utn.make_off_by_one(m_sb, m_bs)

        self.assertArrayShape(gfl.lstsq(m_bs, v_b), utn.drop(tall))
        self.assertArrayShape(gfl.lstsq(m_sb, v_s), utn.drop(wide))
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.lstsq(m_sb, v_b)
        with self.assertRaisesRegex(*utn.core_dim_err):
            # This would succeed/broadcast error if interpreted as Mv:
            gfl.lstsq(m_sb[off_b], m_bs[y_one])

    @hy.given(hn.broadcastable('(a,b),(b,a),(a),(b)', 'd'))
    def test_lstsq_flexible_signature_with_vectors_vm(self, arrays):
        m_sb, m_bs = arrays[:-2]
        v_s, v_b = hn.core_only(*arrays[-2:], dims=1)
        wide, tall = [arr.shape for arr in arrays[:-2]]
        hy.assume(hn.nonsquare(m_sb))

        self.assertArrayShape(gfl.lstsq(v_s, m_sb), utn.drop(wide))
        self.assertArrayShape(gfl.lstsq(v_b, m_bs), utn.drop(tall))
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.lstsq(v_s, m_bs)

    @hy.given(hn.vectors, hn.vectors)
    def test_lstsq_flexible_signature_with_vectors_vv(self, v_s, v_b):
        hy.assume(len(v_s) != len(v_b))

        self.assertArrayShape(gfl.lstsq(v_s, v_s), ())
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.lstsq(v_s, v_b)

    @hy.given(hn.broadcastable('(a,b),(b,a),(a),(b)', 'd'))
    def test_rlstsq_flexible_signature_with_vectors_mv(self, arrays):
        m_sb, m_bs = arrays[:-2]
        v_s, v_b = hn.core_only(*arrays[-2:], dims=1)
        wide, tall = [arr.shape for arr in arrays[:-2]]
        hy.assume(hn.wide(m_sb))

        self.assertArrayShape(gfl.rlstsq(m_sb, v_b), wide[:-1])
        self.assertArrayShape(gfl.rlstsq(m_bs, v_s), tall[:-1])
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rlstsq(m_bs, v_b)

    @hy.given(hn.broadcastable('(a,b),(b,a),(a),(b)', 'd'))
    def test_rlstsq_flexible_signature_with_vectors_vm(self, arrays):
        m_sb, m_bs = arrays[:-2]
        v_s, v_b = hn.core_only(*arrays[-2:], dims=1)
        wide, tall = [arr.shape for arr in arrays[:-2]]
        hy.assume(hn.wide(m_sb))
        off_b, y_one = utn.make_off_by_one(m_sb, m_bs)

        self.assertArrayShape(gfl.rlstsq(v_b, m_sb), wide[:-1])
        self.assertArrayShape(gfl.rlstsq(v_s, m_bs), tall[:-1])
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rlstsq(v_b, m_bs)
        with self.assertRaisesRegex(*utn.core_dim_err):
            # This would succeed/broadcast error if interpreted as vM:
            gfl.rlstsq(m_bs[y_one], m_sb[off_b])

    @hy.given(hn.vectors, hn.vectors)
    def test_rlstsq_flexible_signature_with_vectors_vv(self, v_s, v_b):
        hy.assume(len(v_s) != len(v_b))

        self.assertArrayShape(gfl.rlstsq(v_s, v_s), ())
        with self.assertRaisesRegex(*utn.core_dim_err):
            gfl.rlstsq(v_s, v_b)
예제 #20
0
class TestShape(TestCaseNumpy):
    """Testing shapes returned by linalg functions"""
    @hy.given(hn.matrices_b)
    def test_functions_shape(self, array):
        shape = array.shape
        self.assertArrayShape(la.transpose(array), utn.trnsp(shape))
        self.assertArrayShape(la.row(array), shape[:-1] + (1, ) + shape[-1:])
        self.assertArrayShape(la.col(array), shape + (1, ))
        self.assertArrayShape(la.scalar(array), shape + (1, 1))

    @hy.given(hn.broadcastable('(a,b),(b,a),(a),(b)', 'd'))
    def test_functions_matmul(self, arrays):
        m_sb, m_bs = arrays[:-2]
        v_s, v_b = hn.core_only(*arrays[-2:], dims=1)
        wide, tall = [arr.shape for arr in arrays[:-2]]

        # with self.subTest('matmul'):
        expect = gf.return_shape('(a,b),(b,c)->(a,c)', tall, wide)
        self.assertArrayShape(la.matmul(m_bs, m_sb), expect)
        self.assertArrayShape(la.matmul(m_bs, v_s), tall[:-1])
        self.assertArrayShape(la.matmul(v_b, m_bs), utn.drop(tall))
        self.assertArrayShape(la.matmul(v_s, v_s), ())
        # with self.subTest('rmatmul'):
        expect = gf.return_shape('(a,b),(b,c)->(a,c)', wide, tall)
        self.assertArrayShape(gf.rmatmul(m_bs, m_sb), expect)
        self.assertArrayShape(gf.rmatmul(m_sb, v_s), utn.drop(wide))
        self.assertArrayShape(gf.rmatmul(v_b, m_sb), wide[:-1])
        self.assertArrayShape(gf.rmatmul(v_b, v_b), ())

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,a),(a)', 'd'))
    def test_functions_solve(self, arrays):
        m_ss, m_sb, m_bs = arrays[:-1]
        v_s = hn.core_only(arrays[-1], dims=1)
        smol, wide, tall = [arr.shape for arr in arrays[:-1]]
        hy.assume(hn.all_well_behaved(m_ss))

        # with self.subTest('solve'):
        expect = gf.return_shape('(a,b),(b,c)->(a,c)', smol, wide)
        self.assertArrayShape(la.solve(m_ss, m_sb), expect)
        self.assertArrayShape(la.solve(m_ss, v_s), smol[:-1])
        # with self.subTest('rsolve'):
        expect = gf.return_shape('(a,b),(b,c)->(a,c)', tall, smol)
        self.assertArrayShape(la.rsolve(m_bs, m_ss), expect)
        self.assertArrayShape(la.rsolve(v_s, m_ss), smol[:-1])

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a),(a),(b)', 'd'))
    def test_functions_lstsq(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays[:-2]
        v_s, v_b = hn.core_only(*arrays[-2:], dims=1)
        smol, wide, big, tall = [arr.shape for arr in arrays[:-2]]

        # with self.subTest('lstsq'):
        expect = gf.return_shape('(a,b),(a,c)->(b,c)', tall, big)
        self.assertArrayShape(la.lstsq(m_bs, m_bb), expect)
        expect = gf.return_shape('(a,b),(a,c)->(b,c)', wide, smol)
        self.assertArrayShape(la.lstsq(m_sb, m_ss), expect)
        self.assertArrayShape(la.lstsq(m_sb, v_s), utn.drop(wide))
        self.assertArrayShape(la.lstsq(v_s, m_ss), smol[:-1])
        # with self.subTest('rlstsq'):
        expect = gf.return_shape('(a,b),(c,b)->(a,c)', smol, tall)
        self.assertArrayShape(la.rlstsq(m_ss, m_bs), expect)
        expect = gf.return_shape('(a,b),(c,b)->(a,c)', big, wide)
        self.assertArrayShape(la.rlstsq(m_bb, m_sb), expect)
        self.assertArrayShape(la.rlstsq(v_b, m_sb), wide[:-1])
        self.assertArrayShape(la.rlstsq(m_ss, v_s), smol[:-1])
        self.assertArrayShape(la.rlstsq(v_s, m_bs), tall[:-1])

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,b),(b,a),(a)', 'd'))
    def test_functions_matldiv(self, arrays):
        m_ss, m_sb, m_bb, m_bs = arrays[:-1]
        v_s = hn.core_only(arrays[-1], dims=1)
        smol, wide, big, tall = [arr.shape for arr in arrays[:-1]]
        hy.assume(hn.all_well_behaved(m_ss))
        hy.assume(hn.wide(m_sb))

        # with self.subTest('solve'):
        expect = gf.return_shape('(a,b),(a,c)->(b,c)', smol, wide)
        self.assertArrayShape(la.matldiv(m_ss, m_sb), expect)
        self.assertArrayShape(la.matldiv(m_ss, v_s), smol[:-1])
        # with self.subTest('lstsq'):
        expect = gf.return_shape('(a,b),(a,c)->(b,c)', tall, big)
        self.assertArrayShape(la.matldiv(m_bs, m_bb), expect)
        expect = gf.return_shape('(a,b),(a,c)->(b,c)', wide, smol)
        self.assertArrayShape(la.matldiv(m_sb, m_ss), expect)
        self.assertArrayShape(la.matldiv(m_sb, v_s), utn.drop(wide))
        self.assertArrayShape(la.matldiv(v_s, m_ss), smol[:-1])

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,a),(a),(b)', 'd'))
    def test_functions_matrdiv(self, arrays):
        m_ss, m_sb, m_bs = arrays[:-2]
        v_s, v_b = hn.core_only(*arrays[-2:], dims=1)
        smol, wide, tall = [arr.shape for arr in arrays[:-2]]
        hy.assume(hn.all_well_behaved(m_ss))
        hy.assume(hn.wide(m_sb))

        # with self.subTest('rsolve'):
        expect = gf.return_shape('(a,b),(c,b)->(a,c)', tall, smol)
        self.assertArrayShape(la.matrdiv(m_bs, m_ss), expect)
        self.assertArrayShape(la.matrdiv(v_s, m_ss), smol[:-1])
        # with self.subTest('rlstsq'):
        expect = gf.return_shape('(a,b),(c,b)->(a,c)', smol, tall)
        self.assertArrayShape(la.matrdiv(m_ss, m_bs), expect)
        self.assertArrayShape(la.matrdiv(v_b, m_sb), wide[:-1])
        self.assertArrayShape(la.matrdiv(m_ss, v_s), smol[:-1])
        self.assertArrayShape(la.matrdiv(v_s, m_bs), tall[:-1])

    @hy.given(hn.broadcastable('(a,b),(b,a)', 'd'))
    def test_qr(self, arrays):
        m_sb, m_bs = arrays
        wide, tall = [arr.shape for arr in arrays]
        hy.assume(hn.wide(m_sb))

        # with self.subTest("reduced"):
        self.assertArrayShapesAre(la.qr(m_bs, 'reduced'),
                                  (tall, utn.chop(tall)))
        self.assertArrayShapesAre(la.qr(m_sb, 'reduced'),
                                  (utn.chop(wide), wide))
        # with self.subTest("complete"):
        self.assertArrayShapesAre(la.qr(m_bs, 'complete'),
                                  (utn.grow(tall), tall))
        self.assertArrayShapesAre(la.qr(m_sb, 'complete'),
                                  (utn.chop(wide), wide))
        # with self.subTest("r/raw"):
        self.assertArrayShape(la.qr(m_bs, 'r'), utn.chop(tall))
        self.assertArrayShape(la.qr(m_sb, 'r'), wide)
        self.assertArrayShapesAre(la.qr(m_bs, 'raw'),
                                  (utn.trnsp(tall), utn.drop(tall)))
        self.assertArrayShapesAre(la.qr(m_sb, 'raw'),
                                  (utn.trnsp(wide), wide[:-1]))

    @hy.given(hn.broadcastable('(a,b),(b,a)', 'd'))
    def test_lq(self, arrays):
        m_sb, m_bs = arrays
        wide, tall = [arr.shape for arr in arrays]
        hy.assume(hn.wide(m_sb))

        # with self.subTest("reduced"):
        self.assertArrayShapesAre(la.lq(m_bs, 'reduced'),
                                  (tall, utn.chop(tall)))
        self.assertArrayShapesAre(la.lq(m_sb, 'reduced'),
                                  (utn.chop(wide), wide))
        # with self.subTest("complete"):
        self.assertArrayShapesAre(la.lq(m_bs, 'complete'),
                                  (tall, utn.chop(tall)))
        self.assertArrayShapesAre(la.lq(m_sb, 'complete'),
                                  (wide, utn.grow(wide)))
        # with self.subTest("l/raw"):
        self.assertArrayShape(la.lq(m_bs, 'l'), tall)
        self.assertArrayShape(la.lq(m_sb, 'l'), utn.chop(wide))
        self.assertArrayShapesAre(la.lq(m_bs, 'raw'),
                                  (utn.trnsp(tall), utn.drop(tall)))
        self.assertArrayShapesAre(la.lq(m_sb, 'raw'),
                                  (utn.trnsp(wide), wide[:-1]))

    @hy.given(hn.broadcastable('(a,b),(b,a)', 'd'))
    def test_lqr(self, arrays):
        m_sb, m_bs = arrays
        wide, tall = [arr.shape for arr in arrays]
        hy.assume(hn.wide(m_sb))

        # with self.subTest("reduced"):
        self.assertArrayShapesAre(la.lqr(m_bs, 'reduced'),
                                  (tall, utn.chop(tall)))
        self.assertArrayShapesAre(la.lqr(m_sb, 'reduced'),
                                  (utn.chop(wide), wide))
        # with self.subTest("complete"):
        self.assertArrayShapesAre(la.lqr(m_bs, 'complete'),
                                  (utn.grow(tall), tall))
        self.assertArrayShapesAre(la.lqr(m_sb, 'complete'),
                                  (wide, utn.grow(wide)))
        # with self.subTest("r/l/raw"):
        self.assertArrayShape(la.lqr(m_bs, 'l'), utn.chop(tall))
        self.assertArrayShape(la.lqr(m_sb, 'l'), utn.chop(wide))
        self.assertArrayShape(la.lqr(m_bs, 'r'), utn.chop(tall))
        self.assertArrayShape(la.lqr(m_sb, 'r'), utn.chop(wide))
        self.assertArrayShapesAre(la.lqr(m_bs, 'raw'),
                                  (utn.trnsp(tall), utn.drop(tall)))
        self.assertArrayShapesAre(la.lqr(m_sb, 'raw'),
                                  (utn.trnsp(wide), wide[:-1]))

    @hy.given(hn.broadcastable('(a,a),(a,b),(b,a)', 'd'))
    def test_lu(self, arrays):
        m_ss, m_sb, m_bs = arrays
        smol, wide, tall = [arr.shape for arr in arrays]
        hy.assume(hn.wide(m_sb))

        # with self.subTest("separate"):
        self.assertArrayShapesAre(la.lu(m_ss, 'separate'),
                                  (smol, smol, smol[:-1]))
        self.assertArrayShapesAre(la.lu(m_bs, 'separate'),
                                  (tall, utn.chop(tall), utn.drop(tall)))
        self.assertArrayShapesAre(la.lu(m_sb, 'separate'),
                                  (utn.chop(wide), wide, wide[:-1]))
        # with self.subTest("raw"):
        self.assertArrayShapesAre(la.lu(m_ss, 'raw'), (smol, smol[:-1]))
        self.assertArrayShapesAre(la.lu(m_bs, 'raw'),
                                  (utn.trnsp(tall), utn.drop(tall)))
        self.assertArrayShapesAre(la.lu(m_sb, 'raw'),
                                  (utn.trnsp(wide), wide[:-1]))
예제 #21
0
class TestLstsqQRVectors(TestCaseNumpy):
    """Testing (r)lstsq_qr? with vectors"""
    @hy.given(hn.broadcastable('(a,b),(b,a),(a),(b)', 'd'), qr_funcs)
    def test_lstsq_qr_flexible_signature_with_vectors_mv(self, arrays, fun):
        m_sb, m_bs = arrays[:-2]
        wide, tall = [arr.shape for arr in arrays[:-2]]
        v_s, v_b = hn.core_only(*arrays[-2:], dims=1)
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_bs, m_sb))
        off_b, y_one = utn.make_off_by_one(m_sb, m_bs)

        tau = m_bs.shape[:-2] + tau_len(m_bs, fun)
        self.assertArrayShapesAre(fun(m_bs, v_b),
                                  (utn.drop(tall), utn.trnsp(tall), tau))
        tau = m_sb.shape[:-2] + tau_len(m_sb, fun)
        self.assertArrayShapesAre(fun(m_sb, v_s),
                                  (utn.drop(wide), utn.trnsp(wide), tau))
        with self.assertRaisesRegex(*utn.core_dim_err):
            fun(m_sb, v_b)
        with self.assertRaisesRegex(*utn.core_dim_err):
            # This would succeed/broadcast error if interpreted as Mv:
            fun(m_sb[off_b], m_bs[y_one])

    @hy.given(hn.broadcastable('(a,b),(b,a),(a)', 'd'), qr_funcs)
    def test_lstsq_qr_flexible_signature_with_vectors_vm(self, arrays, fun):
        m_sb, m_bs = arrays[:-1]
        wide = m_sb.shape
        v_s = hn.core_only(arrays[-1], dims=1)
        hy.assume(hn.wide(m_sb))
        hy.assume(la.norm(v_s) > 0.)

        tau = m_sb.shape[:-2] + tau_len_vec(v_s, fun)
        self.assertArrayShapesAre(fun(v_s, m_sb),
                                  (utn.drop(wide), wide[:-1], tau))
        with self.assertRaisesRegex(*utn.core_dim_err):
            fun(v_s, m_bs)

    @hy.given(hn.vectors, hn.vectors, qr_funcs)
    def test_lstsq_qr_flexible_signature_with_vectors_vv(self, v_s, v_b, fun):
        hy.assume(len(v_s) != len(v_b))
        hy.assume(la.norm(v_s) > 0.)

        tau = tau_len_vec(v_s, fun)
        self.assertArrayShapesAre(fun(v_s, v_s), ((), v_s.shape, tau))
        with self.assertRaisesRegex(*utn.core_dim_err):
            fun(v_s, v_b)

    @hy.given(hn.broadcastable('(a,b),(b,a),(b)', 'd'), rqr_funcs)
    def test_rlstsq_qr_flexible_signature_with_vectors_mv(self, arrays, fun):
        m_sb, m_bs = arrays[:-1]
        wide = m_sb.shape
        v_b = hn.core_only(arrays[-1], dims=1)
        hy.assume(hn.wide(m_sb))
        hy.assume(la.norm(v_b) > 0.)

        tau = m_sb.shape[:-2] + tau_len_vec(v_b, fun)
        self.assertArrayShapesAre(fun(m_sb, v_b),
                                  (wide[:-1], utn.drop(wide), tau))
        with self.assertRaisesRegex(*utn.core_dim_err):
            fun(m_bs, v_b)

    @hy.given(hn.broadcastable('(a,b),(b,a),(a),(b)', 'd'), rqr_funcs)
    def test_rlstsq_qr_flexible_signature_with_vectors_vm(self, arrays, fun):
        m_sb, m_bs = arrays[:-2]
        v_s, v_b = hn.core_only(*arrays[-2:], dims=1)
        wide, tall = [arr.shape for arr in arrays[:-2]]
        hy.assume(hn.wide(m_sb))
        hy.assume(hn.all_well_behaved(m_sb, m_bs))
        off_b, y_one = utn.make_off_by_one(m_sb, m_bs)

        tau = m_sb.shape[:-2] + tau_len(m_sb, fun)
        self.assertArrayShapesAre(fun(v_b, m_sb),
                                  (wide[:-1], utn.trnsp(wide), tau))
        tau = m_bs.shape[:-2] + tau_len(m_bs, fun)
        self.assertArrayShapesAre(fun(v_s, m_bs),
                                  (tall[:-1], utn.trnsp(tall), tau))
        with self.assertRaisesRegex(*utn.core_dim_err):
            fun(v_b, m_bs)
        with self.assertRaisesRegex(*utn.core_dim_err):
            # This would succeed/broadcast error if interpreted as vM:
            fun(m_bs[y_one], m_sb[off_b])

    @hy.given(hn.vectors, hn.vectors, rqr_funcs)
    def test_rlstsq_qr_flexible_signature_with_vectors_vv(self, v_s, v_b, fun):
        hy.assume(len(v_s) != len(v_b))
        hy.assume(la.norm(v_s) > 0.)

        tau = tau_len_vec(v_s, fun)
        self.assertArrayShapesAre(fun(v_s, v_s), ((), v_s.shape, tau))
        with self.assertRaisesRegex(*utn.core_dim_err):
            fun(v_s, v_b)