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)))
 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)
    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)
    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)
    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)