def test_DomainMatrix_add(): A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) B = DomainMatrix([[ZZ(2), ZZ(4)], [ZZ(6), ZZ(8)]], (2, 2), ZZ) assert A + A == A.add(A) == B A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) L = [[2, 3], [3, 4]] raises(TypeError, lambda: A + L) raises(TypeError, lambda: L + A) A1 = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) A2 = DomainMatrix([[ZZ(1), ZZ(2)]], (1, 2), ZZ) raises(DMShapeError, lambda: A1 + A2) raises(DMShapeError, lambda: A2 + A1) raises(DMShapeError, lambda: A1.add(A2)) raises(DMShapeError, lambda: A2.add(A1)) Az = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) Aq = DomainMatrix([[QQ(1), QQ(2)], [QQ(3), QQ(4)]], (2, 2), QQ) Asum = DomainMatrix([[QQ(2), QQ(4)], [QQ(6), QQ(8)]], (2, 2), QQ) assert Az + Aq == Asum assert Aq + Az == Asum raises(DMDomainError, lambda: Az.add(Aq)) raises(DMDomainError, lambda: Aq.add(Az)) As = DomainMatrix({0: {1: ZZ(1)}, 1: {0: ZZ(2)}}, (2, 2), ZZ) Ad = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) Asd = As + Ad Ads = Ad + As assert Asd == DomainMatrix([[1, 3], [5, 4]], (2, 2), ZZ) assert Asd.rep == DDM([[1, 3], [5, 4]], (2, 2), ZZ) assert Ads == DomainMatrix([[1, 3], [5, 4]], (2, 2), ZZ) assert Ads.rep == DDM([[1, 3], [5, 4]], (2, 2), ZZ) raises(DMFormatError, lambda: As.add(Ad))
def test_DDM_mul(): A = DDM([[ZZ(1)]], (1, 1), ZZ) A2 = DDM([[ZZ(2)]], (1, 1), ZZ) assert A * ZZ(2) == A2 assert ZZ(2) * A == A2 raises(TypeError, lambda: [[1]] * A) raises(TypeError, lambda: A * [[1]])
def test_DDM_copy(): ddm1 = DDM([[QQ(1)], [QQ(2)]], (2, 1), QQ) ddm2 = ddm1.copy() assert (ddm1 == ddm2) is True ddm1[0][0] = QQ(-1) assert (ddm1 == ddm2) is False ddm2[0][0] = QQ(-1) assert (ddm1 == ddm2) is True
def test_DDM_setitem(): dm = DDM.zeros((3, 3), ZZ) dm.setitem(0, 0, 1) dm.setitem(1, -2, 1) dm.setitem(-1, -1, 1) assert dm == DDM.eye(3, ZZ) raises(IndexError, lambda: dm.setitem(3, 3, 0))
def test_DDM_vstack(): A = DDM([[ZZ(1)], [ZZ(2)], [ZZ(3)]], (3, 1), ZZ) B = DDM([[ZZ(4)], [ZZ(5)]], (2, 1), ZZ) Ah = A.vstack(B) assert Ah.shape == (5, 1) assert Ah.domain == ZZ assert Ah == DDM([[ZZ(1)], [ZZ(2)], [ZZ(3)], [ZZ(4)], [ZZ(5)]], (5, 1), ZZ)
def test_DDM_hstack(): A = DDM([[ZZ(1), ZZ(2), ZZ(3)]], (1, 3), ZZ) B = DDM([[ZZ(4), ZZ(5)]], (1, 2), ZZ) Ah = A.hstack(B) assert Ah.shape == (1, 5) assert Ah.domain == ZZ assert Ah == DDM([[ZZ(1), ZZ(2), ZZ(3), ZZ(4), ZZ(5)]], (1, 5), ZZ)
def test_DDM_init(): items = [[ZZ(0), ZZ(1), ZZ(2)], [ZZ(3), ZZ(4), ZZ(5)]] shape = (2, 3) ddm = DDM(items, shape, ZZ) assert ddm.shape == shape assert ddm.rows == 2 assert ddm.cols == 3 assert ddm.domain == ZZ raises(DDMBadInputError, lambda: DDM([[ZZ(2), ZZ(3)]], (2, 2), ZZ)) raises(DDMBadInputError, lambda: DDM([[ZZ(1)], [ZZ(2), ZZ(3)]], (2, 2), ZZ))
def test_DDM_charpoly(): A = DDM([], (0, 0), ZZ) assert A.charpoly() == [ZZ(1)] A = DDM([[ZZ(1), ZZ(2), ZZ(3)], [ZZ(4), ZZ(5), ZZ(6)], [ZZ(7), ZZ(8), ZZ(9)]], (3, 3), ZZ) Avec = [ZZ(1), ZZ(-15), ZZ(-18), ZZ(0)] assert A.charpoly() == Avec A = DDM([[ZZ(1), ZZ(2)]], (1, 2), ZZ) raises(DDMShapeError, lambda: A.charpoly())
def test_DomainMatrix_sub(): A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) B = DomainMatrix([[ZZ(0), ZZ(0)], [ZZ(0), ZZ(0)]], (2, 2), ZZ) assert A - A == A.sub(A) == B A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) L = [[2, 3], [3, 4]] raises(TypeError, lambda: A - L) raises(TypeError, lambda: L - A) A1 = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) A2 = DomainMatrix([[ZZ(1), ZZ(2)]], (1, 2), ZZ) raises(DMShapeError, lambda: A1 - A2) raises(DMShapeError, lambda: A2 - A1) raises(DMShapeError, lambda: A1.sub(A2)) raises(DMShapeError, lambda: A2.sub(A1)) Az = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) Aq = DomainMatrix([[QQ(1), QQ(2)], [QQ(3), QQ(4)]], (2, 2), QQ) Adiff = DomainMatrix([[QQ(0), QQ(0)], [QQ(0), QQ(0)]], (2, 2), QQ) assert Az - Aq == Adiff assert Aq - Az == Adiff raises(DMDomainError, lambda: Az.sub(Aq)) raises(DMDomainError, lambda: Aq.sub(Az)) As = DomainMatrix({0: {1: ZZ(1)}, 1: {0: ZZ(2)}}, (2, 2), ZZ) Ad = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) Asd = As - Ad Ads = Ad - As assert Asd == DomainMatrix([[-1, -1], [-1, -4]], (2, 2), ZZ) assert Asd.rep == DDM([[-1, -1], [-1, -4]], (2, 2), ZZ) assert Asd == -Ads assert Asd.rep == -Ads.rep
def test_DomainMatrix_init(): lol = [[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]] dod = {0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}} ddm = DDM(lol, (2, 2), ZZ) sdm = SDM(dod, (2, 2), ZZ) A = DomainMatrix(lol, (2, 2), ZZ) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == ZZ A = DomainMatrix(dod, (2, 2), ZZ) assert A.rep == sdm assert A.shape == (2, 2) assert A.domain == ZZ raises(TypeError, lambda: DomainMatrix(ddm, (2, 2), ZZ)) raises(TypeError, lambda: DomainMatrix(sdm, (2, 2), ZZ)) raises(TypeError, lambda: DomainMatrix(Matrix([[1]]), (1, 1), ZZ)) for fmt, rep in [('sparse', sdm), ('dense', ddm)]: A = DomainMatrix(lol, (2, 2), ZZ, fmt=fmt) assert A.rep == rep A = DomainMatrix(dod, (2, 2), ZZ, fmt=fmt) assert A.rep == rep raises(ValueError, lambda: DomainMatrix(lol, (2, 2), ZZ, fmt='invalid')) raises(DMBadInputError, lambda: DomainMatrix([[ZZ(1), ZZ(2)]], (2, 2), ZZ))
def test_DomainMatrix_from_Matrix(): sdm = SDM({0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}}, (2, 2), ZZ) A = DomainMatrix.from_Matrix(Matrix([[1, 2], [3, 4]])) assert A.rep == sdm assert A.shape == (2, 2) assert A.domain == ZZ K = QQ.algebraic_field(sqrt(2)) sdm = SDM( { 0: { 0: K.convert(1 + sqrt(2)), 1: K.convert(2 + sqrt(2)) }, 1: { 0: K.convert(3 + sqrt(2)), 1: K.convert(4 + sqrt(2)) } }, (2, 2), K) A = DomainMatrix.from_Matrix(Matrix([[1 + sqrt(2), 2 + sqrt(2)], [3 + sqrt(2), 4 + sqrt(2)]]), extension=True) assert A.rep == sdm assert A.shape == (2, 2) assert A.domain == K A = DomainMatrix.from_Matrix(Matrix([[QQ(1, 2), QQ(3, 4)], [QQ(0, 1), QQ(0, 1)]]), fmt='dense') ddm = DDM([[QQ(1, 2), QQ(3, 4)], [QQ(0, 1), QQ(0, 1)]], (2, 2), QQ) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == QQ
def test_DDM_str(): ddm = DDM([[ZZ(0), ZZ(1)], [ZZ(2), ZZ(3)]], (2, 2), ZZ) if HAS_GMPY: # pragma: no cover assert str( ddm) == 'DDM([[mpz(0), mpz(1)], [mpz(2), mpz(3)]], (2, 2), ZZ)' else: # pragma: no cover assert str(ddm) == 'DDM([[0, 1], [2, 3]], (2, 2), ZZ)'
def test_DomainMatrix_init(): A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) assert A.rep == DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) assert A.shape == (2, 2) assert A.domain == ZZ raises(DDMBadInputError, lambda: DomainMatrix([[ZZ(1), ZZ(2)]], (2, 2), ZZ))
def test_DomainMatrix_from_Matrix(): ddm = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) A = DomainMatrix.from_Matrix(Matrix([[1, 2], [3, 4]])) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == ZZ K = QQ.algebraic_field(sqrt(2)) ddm = DDM([[ K.convert(1 + sqrt(2)), K.convert(2 + sqrt(2)) ], [K.convert(3 + sqrt(2)), K.convert(4 + sqrt(2))]], (2, 2), K) A = DomainMatrix.from_Matrix(Matrix([[1 + sqrt(2), 2 + sqrt(2)], [3 + sqrt(2), 4 + sqrt(2)]]), extension=True) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == K
def test_DDM_lu(): A = DDM([[QQ(1), QQ(2)], [QQ(3), QQ(4)]], (2, 2), QQ) L, U, swaps = A.lu() assert L == DDM([[QQ(1), QQ(0)], [QQ(3), QQ(1)]], (2, 2), QQ) assert U == DDM([[QQ(1), QQ(2)], [QQ(0), QQ(-2)]], (2, 2), QQ) assert swaps == [] A = [[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 1, 1], [0, 0, 1, 2]] Lexp = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 1, 1]] Uexp = [[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 1, 1], [0, 0, 0, 1]] to_dom = lambda rows, dom: [[dom(e) for e in row] for row in rows] A = DDM(to_dom(A, QQ), (4, 4), QQ) Lexp = DDM(to_dom(Lexp, QQ), (4, 4), QQ) Uexp = DDM(to_dom(Uexp, QQ), (4, 4), QQ) L, U, swaps = A.lu() assert L == Lexp assert U == Uexp assert swaps == []
def test_ddm_charpoly(): A = [] assert ddm_berk(A, ZZ) == [[ZZ(1)]] A = [[ZZ(1), ZZ(2), ZZ(3)], [ZZ(4), ZZ(5), ZZ(6)], [ZZ(7), ZZ(8), ZZ(9)]] Avec = [[ZZ(1)], [ZZ(-15)], [ZZ(-18)], [ZZ(0)]] assert ddm_berk(A, ZZ) == Avec A = DDM([[ZZ(1), ZZ(2)]], (1, 2), ZZ) raises(DMShapeError, lambda: ddm_berk(A, ZZ))
def test_DomainMatrix_from_list(): ddm = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) A = DomainMatrix.from_list([[1, 2], [3, 4]], ZZ) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == ZZ dom = FF(7) ddm = DDM([[dom(1), dom(2)], [dom(3), dom(4)]], (2, 2), dom) A = DomainMatrix.from_list([[1, 2], [3, 4]], dom) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == dom ddm = DDM([[QQ(1, 2), QQ(3, 1)], [QQ(1, 4), QQ(5, 1)]], (2, 2), QQ) A = DomainMatrix.from_list([[(1, 2), (3, 1)], [(1, 4), (5, 1)]], QQ) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == QQ
def test_DDM_getsetitem(): ddm = DDM([[ZZ(2), ZZ(3)], [ZZ(4), ZZ(5)]], (2, 2), ZZ) assert ddm[0][0] == ZZ(2) assert ddm[0][1] == ZZ(3) assert ddm[1][0] == ZZ(4) assert ddm[1][1] == ZZ(5) raises(IndexError, lambda: ddm[2][0]) raises(IndexError, lambda: ddm[0][2]) ddm[0][0] = ZZ(-1) assert ddm[0][0] == ZZ(-1)
def test_DDM_add(): A = DDM([[ZZ(1)], [ZZ(2)]], (2, 1), ZZ) B = DDM([[ZZ(3)], [ZZ(4)]], (2, 1), ZZ) C = DDM([[ZZ(4)], [ZZ(6)]], (2, 1), ZZ) AQ = DDM([[QQ(1)], [QQ(2)]], (2, 1), QQ) assert A + B == A.add(B) == C raises(DDMShapeError, lambda: A + DDM([[ZZ(5)]], (1, 1), ZZ)) raises(TypeError, lambda: A + ZZ(1)) raises(TypeError, lambda: ZZ(1) + A) raises(DDMDomainError, lambda: A + AQ) raises(DDMDomainError, lambda: AQ + A)
def test_DomainMatrix_unify(): Az = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) Aq = DomainMatrix([[QQ(1), QQ(2)], [QQ(3), QQ(4)]], (2, 2), QQ) assert Az.unify(Az) == (Az, Az) assert Az.unify(Aq) == (Aq, Aq) assert Aq.unify(Az) == (Aq, Aq) assert Aq.unify(Aq) == (Aq, Aq) As = DomainMatrix({0: {1: ZZ(1)}, 1: {0: ZZ(2)}}, (2, 2), ZZ) Ad = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) assert As.unify(As) == (As, As) assert Ad.unify(Ad) == (Ad, Ad) Bs, Bd = As.unify(Ad, fmt='dense') assert Bs.rep == DDM([[0, 1], [2, 0]], (2, 2), ZZ) assert Bd.rep == DDM([[1, 2], [3, 4]], (2, 2), ZZ) Bs, Bd = As.unify(Ad, fmt='sparse') assert Bs.rep == SDM({0: {1: 1}, 1: {0: 2}}, (2, 2), ZZ) assert Bd.rep == SDM({0: {0: 1, 1: 2}, 1: {0: 3, 1: 4}}, (2, 2), ZZ) raises(ValueError, lambda: As.unify(Ad, fmt='invalid'))
def test_DDM_getitem(): dm = DDM([[ZZ(1), ZZ(2), ZZ(3)], [ZZ(4), ZZ(5), ZZ(6)], [ZZ(7), ZZ(8), ZZ(9)]], (3, 3), ZZ) assert dm.getitem(1, 1) == ZZ(5) assert dm.getitem(1, -2) == ZZ(5) assert dm.getitem(-1, -3) == ZZ(7) raises(IndexError, lambda: dm.getitem(3, 3))
def test_DomainMatrix_mul(): A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) A2 = DomainMatrix([[ZZ(7), ZZ(10)], [ZZ(15), ZZ(22)]], (2, 2), ZZ) assert A * A == A.matmul(A) == A2 A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) L = [[1, 2], [3, 4]] raises(TypeError, lambda: A * L) raises(TypeError, lambda: L * A) Az = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) Aq = DomainMatrix([[QQ(1), QQ(2)], [QQ(3), QQ(4)]], (2, 2), QQ) Aprod = DomainMatrix([[QQ(7), QQ(10)], [QQ(15), QQ(22)]], (2, 2), QQ) assert Az * Aq == Aprod assert Aq * Az == Aprod raises(DMDomainError, lambda: Az.matmul(Aq)) raises(DMDomainError, lambda: Aq.matmul(Az)) A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) AA = DomainMatrix([[ZZ(2), ZZ(4)], [ZZ(6), ZZ(8)]], (2, 2), ZZ) x = ZZ(2) assert A * x == x * A == A.mul(x) == AA A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) AA = DomainMatrix.zeros((2, 2), ZZ) x = ZZ(0) assert A * x == x * A == A.mul(x).to_sparse() == AA As = DomainMatrix({0: {1: ZZ(1)}, 1: {0: ZZ(2)}}, (2, 2), ZZ) Ad = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) Asd = As * Ad Ads = Ad * As assert Asd == DomainMatrix([[3, 4], [2, 4]], (2, 2), ZZ) assert Asd.rep == DDM([[3, 4], [2, 4]], (2, 2), ZZ) assert Ads == DomainMatrix([[4, 1], [8, 3]], (2, 2), ZZ) assert Ads.rep == DDM([[4, 1], [8, 3]], (2, 2), ZZ)
def test_DDM_eq(): items = [[ZZ(0), ZZ(1)], [ZZ(2), ZZ(3)]] ddm1 = DDM(items, (2, 2), ZZ) ddm2 = DDM(items, (2, 2), ZZ) assert (ddm1 == ddm1) is True assert (ddm1 == items) is False assert (items == ddm1) is False assert (ddm1 == ddm2) is True assert (ddm2 == ddm1) is True assert (ddm1 != ddm1) is False assert (ddm1 != items) is True assert (items != ddm1) is True assert (ddm1 != ddm2) is False assert (ddm2 != ddm1) is False ddm3 = DDM([[ZZ(0), ZZ(1)], [ZZ(3), ZZ(3)]], (2, 2), ZZ) ddm3 = DDM(items, (2, 2), QQ) assert (ddm1 == ddm3) is False assert (ddm3 == ddm1) is False assert (ddm1 != ddm3) is True assert (ddm3 != ddm1) is True
def test_DomainMatrix_from_rep(): ddm = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) A = DomainMatrix.from_rep(ddm) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == ZZ sdm = SDM({0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}}, (2, 2), ZZ) A = DomainMatrix.from_rep(sdm) assert A.rep == sdm assert A.shape == (2, 2) assert A.domain == ZZ A = DomainMatrix([[ZZ(1)]], (1, 1), ZZ) raises(TypeError, lambda: DomainMatrix.from_rep(A))
def test_DomainMatrix_from_list_sympy(): # ddm = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) ddm = SDM({0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}}, (2, 2), ZZ) A = DomainMatrix.from_list_sympy(2, 2, [[1, 2], [3, 4]]) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == ZZ K = QQ.algebraic_field(sqrt(2)) ddm = DDM([[ K.convert(1 + sqrt(2)), K.convert(2 + sqrt(2)) ], [K.convert(3 + sqrt(2)), K.convert(4 + sqrt(2))]], (2, 2), K) ddm = SDM.from_ddm(ddm) A = DomainMatrix.from_list_sympy( 2, 2, [[1 + sqrt(2), 2 + sqrt(2)], [3 + sqrt(2), 4 + sqrt(2)]], extension=True) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == K
def test_DDM_eye(): ddmz = DDM.eye(3, QQ) f = lambda i, j: QQ(1) if i == j else QQ(0) assert list(ddmz) == [[f(i, j) for i in range(3)] for j in range(3)] assert ddmz.shape == (3, 3) assert ddmz.domain == QQ
def test_DDM_ones(): ddmone = DDM.ones((2, 3), QQ) assert list(ddmone) == [[QQ(1)] * 3] * 2 assert ddmone.shape == (2, 3) assert ddmone.domain == QQ
def test_DDM_zeros(): ddmz = DDM.zeros((3, 4), QQ) assert list(ddmz) == [[QQ(0)] * 4] * 3 assert ddmz.shape == (3, 4) assert ddmz.domain == QQ
def test_DDM_convert_to(): ddm = DDM([[ZZ(1), ZZ(2)]], (1, 2), ZZ) assert ddm.convert_to(ZZ) == ddm ddmq = ddm.convert_to(QQ) assert ddmq.domain == QQ
def test_DDM_extract(): dm1 = DDM([[ZZ(1), ZZ(2), ZZ(3)], [ZZ(4), ZZ(5), ZZ(6)], [ZZ(7), ZZ(8), ZZ(9)]], (3, 3), ZZ) dm2 = DDM([[ZZ(6), ZZ(4)], [ZZ(3), ZZ(1)]], (2, 2), ZZ) assert dm1.extract([1, 0], [2, 0]) == dm2 assert dm1.extract([-2, 0], [-1, 0]) == dm2 assert dm1.extract([], []) == DDM.zeros((0, 0), ZZ) assert dm1.extract([1], []) == DDM.zeros((1, 0), ZZ) assert dm1.extract([], [1]) == DDM.zeros((0, 1), ZZ) raises(IndexError, lambda: dm2.extract([2], [0])) raises(IndexError, lambda: dm2.extract([0], [2])) raises(IndexError, lambda: dm2.extract([-3], [0])) raises(IndexError, lambda: dm2.extract([0], [-3]))