| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737 |
- from sympy import ZZ, QQ, ZZ_I, EX, Matrix, eye, zeros, symbols
- from sympy.polys.matrices import DM, DomainMatrix
- from sympy.polys.matrices.dense import ddm_irref_den, ddm_irref
- from sympy.polys.matrices.ddm import DDM
- from sympy.polys.matrices.sdm import SDM, sdm_irref, sdm_rref_den
- import pytest
- #
- # The dense and sparse implementations of rref_den are ddm_irref_den and
- # sdm_irref_den. These can give results that differ by some factor and also
- # give different results if the order of the rows is changed. The tests below
- # show all results on lowest terms as should be returned by cancel_denom.
- #
- # The EX domain is also a case where the dense and sparse implementations
- # can give results in different forms: the results should be equivalent but
- # are not canonical because EX does not have a canonical form.
- #
- a, b, c, d = symbols('a, b, c, d')
- qq_large_1 = DM([
- [ (1,2), (1,3), (1,5), (1,7), (1,11), (1,13), (1,17), (1,19), (1,23), (1,29), (1,31)],
- [ (1,37), (1,41), (1,43), (1,47), (1,53), (1,59), (1,61), (1,67), (1,71), (1,73), (1,79)],
- [ (1,83), (1,89), (1,97),(1,101),(1,103),(1,107),(1,109),(1,113),(1,127),(1,131),(1,137)],
- [(1,139),(1,149),(1,151),(1,157),(1,163),(1,167),(1,173),(1,179),(1,181),(1,191),(1,193)],
- [(1,197),(1,199),(1,211),(1,223),(1,227),(1,229),(1,233),(1,239),(1,241),(1,251),(1,257)],
- [(1,263),(1,269),(1,271),(1,277),(1,281),(1,283),(1,293),(1,307),(1,311),(1,313),(1,317)],
- [(1,331),(1,337),(1,347),(1,349),(1,353),(1,359),(1,367),(1,373),(1,379),(1,383),(1,389)],
- [(1,397),(1,401),(1,409),(1,419),(1,421),(1,431),(1,433),(1,439),(1,443),(1,449),(1,457)],
- [(1,461),(1,463),(1,467),(1,479),(1,487),(1,491),(1,499),(1,503),(1,509),(1,521),(1,523)],
- [(1,541),(1,547),(1,557),(1,563),(1,569),(1,571),(1,577),(1,587),(1,593),(1,599),(1,601)],
- [(1,607),(1,613),(1,617),(1,619),(1,631),(1,641),(1,643),(1,647),(1,653),(1,659),(1,661)]],
- QQ)
- qq_large_2 = qq_large_1 + 10**100 * DomainMatrix.eye(11, QQ)
- RREF_EXAMPLES = [
- (
- 'zz_1',
- DM([[1, 2, 3]], ZZ),
- DM([[1, 2, 3]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_2',
- DomainMatrix([], (0, 0), ZZ),
- DomainMatrix([], (0, 0), ZZ),
- ZZ(1),
- ),
- (
- 'zz_3',
- DM([[1, 2],
- [3, 4]], ZZ),
- DM([[1, 0],
- [0, 1]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_4',
- DM([[1, 0],
- [3, 4]], ZZ),
- DM([[1, 0],
- [0, 1]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_5',
- DM([[0, 2],
- [3, 4]], ZZ),
- DM([[1, 0],
- [0, 1]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_6',
- DM([[1, 2, 3],
- [4, 5, 6],
- [7, 8, 9]], ZZ),
- DM([[1, 0, -1],
- [0, 1, 2],
- [0, 0, 0]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_7',
- DM([[0, 0, 0],
- [0, 0, 0],
- [1, 0, 0]], ZZ),
- DM([[1, 0, 0],
- [0, 0, 0],
- [0, 0, 0]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_8',
- DM([[0, 0, 0],
- [0, 0, 0],
- [0, 0, 0]], ZZ),
- DM([[0, 0, 0],
- [0, 0, 0],
- [0, 0, 0]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_9',
- DM([[1, 1, 0],
- [0, 0, 2],
- [0, 0, 0]], ZZ),
- DM([[1, 1, 0],
- [0, 0, 1],
- [0, 0, 0]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_10',
- DM([[2, 2, 0],
- [0, 0, 2],
- [0, 0, 0]], ZZ),
- DM([[1, 1, 0],
- [0, 0, 1],
- [0, 0, 0]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_11',
- DM([[2, 2, 0],
- [0, 2, 2],
- [0, 0, 2]], ZZ),
- DM([[1, 0, 0],
- [0, 1, 0],
- [0, 0, 1]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_12',
- DM([[ 1, 2, 3],
- [ 4, 5, 6],
- [ 7, 8, 9],
- [10, 11, 12]], ZZ),
- DM([[1, 0, -1],
- [0, 1, 2],
- [0, 0, 0],
- [0, 0, 0]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_13',
- DM([[ 1, 2, 3],
- [ 4, 5, 6],
- [ 7, 8, 9],
- [10, 11, 13]], ZZ),
- DM([[ 1, 0, 0],
- [ 0, 1, 0],
- [ 0, 0, 1],
- [ 0, 0, 0]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_14',
- DM([[1, 2, 4, 3],
- [4, 5, 10, 6],
- [7, 8, 16, 9]], ZZ),
- DM([[1, 0, 0, -1],
- [0, 1, 2, 2],
- [0, 0, 0, 0]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_15',
- DM([[1, 2, 4, 3],
- [4, 5, 10, 6],
- [7, 8, 17, 9]], ZZ),
- DM([[1, 0, 0, -1],
- [0, 1, 0, 2],
- [0, 0, 1, 0]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_16',
- DM([[1, 2, 0, 1],
- [1, 1, 9, 0]], ZZ),
- DM([[1, 0, 18, -1],
- [0, 1, -9, 1]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_17',
- DM([[1, 1, 1],
- [1, 2, 2]], ZZ),
- DM([[1, 0, 0],
- [0, 1, 1]], ZZ),
- ZZ(1),
- ),
- (
- # Here the sparse implementation and dense implementation give very
- # different denominators: 4061232 and -1765176.
- 'zz_18',
- DM([[94, 24, 0, 27, 0],
- [79, 0, 0, 0, 0],
- [85, 16, 71, 81, 0],
- [ 0, 0, 72, 77, 0],
- [21, 0, 34, 0, 0]], ZZ),
- DM([[ 1, 0, 0, 0, 0],
- [ 0, 1, 0, 0, 0],
- [ 0, 0, 1, 0, 0],
- [ 0, 0, 0, 1, 0],
- [ 0, 0, 0, 0, 0]], ZZ),
- ZZ(1),
- ),
- (
- # Let's have a denominator that cannot be cancelled.
- 'zz_19',
- DM([[1, 2, 4],
- [4, 5, 6]], ZZ),
- DM([[3, 0, -8],
- [0, 3, 10]], ZZ),
- ZZ(3),
- ),
- (
- 'zz_20',
- DM([[0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0],
- [0, 0, 0, 0, 4]], ZZ),
- DM([[0, 0, 0, 0, 1],
- [0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_21',
- DM([[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
- [1, 0, 0, 0, 0, 0, 1, 0, 0, 0],
- [0, 1, 0, 0, 0, 0, 0, 1, 0, 0],
- [0, 0, 0, 1, 0, 0, 0, 0, 1, 0],
- [0, 0, 0, 0, 1, 0, 0, 0, 0, 1]], ZZ),
- DM([[1, 0, 0, 0, 0, 0, 1, 0, 0, 0],
- [0, 1, 0, 0, 0, 0, 0, 1, 0, 0],
- [0, 0, 0, 1, 0, 0, 0, 0, 1, 0],
- [0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
- [0, 0, 0, 0, 0, 1, 0, 0, 0, 0]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_22',
- DM([[1, 1, 1, 0, 1],
- [1, 1, 0, 1, 0],
- [1, 0, 1, 0, 1],
- [1, 1, 0, 1, 0],
- [1, 0, 0, 0, 0]], ZZ),
- DM([[1, 0, 0, 0, 0],
- [0, 1, 0, 0, 0],
- [0, 0, 1, 0, 1],
- [0, 0, 0, 1, 0],
- [0, 0, 0, 0, 0]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_large_1',
- DM([
- [ 0, 0, 0, 81, 0, 0, 75, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0],
- [ 0, 0, 0, 0, 0, 86, 0, 92, 79, 54, 0, 7, 0, 0, 0, 0, 79, 0, 0, 0],
- [89, 54, 81, 0, 0, 20, 0, 0, 0, 0, 0, 0, 51, 0, 94, 0, 0, 77, 0, 0],
- [ 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 48, 29, 0, 0, 5, 0, 32, 0],
- [ 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 11],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 43, 0, 0],
- [ 0, 0, 0, 0, 0, 38, 91, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 26, 0, 0],
- [69, 0, 0, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55],
- [ 0, 13, 18, 49, 49, 88, 0, 0, 35, 54, 0, 0, 51, 0, 0, 0, 0, 0, 0, 87],
- [ 0, 0, 0, 0, 31, 0, 40, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 0, 88, 0],
- [ 0, 0, 0, 0, 0, 0, 0, 0, 98, 0, 0, 0, 15, 53, 0, 92, 0, 0, 0, 0],
- [ 0, 0, 0, 95, 0, 0, 0, 36, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 73, 19],
- [ 0, 65, 14, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 34, 0, 0],
- [ 0, 0, 0, 16, 39, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0],
- [ 0, 17, 0, 0, 0, 99, 84, 13, 50, 84, 0, 0, 0, 0, 95, 0, 43, 33, 20, 0],
- [79, 0, 17, 52, 99, 12, 69, 0, 98, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [ 0, 0, 0, 82, 0, 44, 0, 0, 0, 97, 0, 0, 0, 0, 0, 10, 0, 0, 31, 0],
- [ 0, 0, 21, 0, 67, 0, 0, 0, 0, 0, 4, 0, 50, 0, 0, 0, 33, 0, 0, 0],
- [ 0, 0, 0, 0, 9, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8],
- [ 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, 34, 93, 0, 0, 0, 0, 47, 0, 0, 0]],
- ZZ),
- DM([[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]], ZZ),
- ZZ(1),
- ),
- (
- 'zz_large_2',
- DM([
- [ 0, 0, 0, 0, 50, 0, 6, 81, 0, 1, 86, 0, 0, 98, 82, 94, 4, 0, 0, 29],
- [ 0, 44, 43, 0, 62, 0, 0, 0, 60, 0, 0, 0, 0, 71, 9, 0, 57, 41, 0, 93],
- [ 0, 0, 28, 0, 74, 89, 42, 0, 28, 0, 6, 0, 0, 0, 44, 0, 0, 0, 77, 19],
- [ 0, 21, 82, 0, 30, 88, 0, 89, 68, 0, 0, 0, 79, 41, 0, 0, 99, 0, 0, 0],
- [31, 0, 0, 0, 19, 64, 0, 0, 79, 0, 5, 0, 72, 10, 60, 32, 64, 59, 0, 24],
- [ 0, 0, 0, 0, 0, 57, 0, 94, 0, 83, 20, 0, 0, 9, 31, 0, 49, 26, 58, 0],
- [ 0, 65, 56, 31, 64, 0, 0, 0, 0, 0, 0, 52, 85, 0, 0, 0, 0, 51, 0, 0],
- [ 0, 35, 0, 0, 0, 69, 0, 0, 64, 0, 0, 0, 0, 70, 0, 0, 90, 0, 75, 76],
- [69, 7, 0, 90, 0, 0, 84, 0, 47, 69, 19, 20, 42, 0, 0, 32, 71, 35, 0, 0],
- [39, 0, 90, 0, 0, 4, 85, 0, 0, 55, 0, 0, 0, 35, 67, 40, 0, 40, 0, 77],
- [98, 63, 0, 71, 0, 50, 0, 2, 61, 0, 38, 0, 0, 0, 0, 75, 0, 40, 33, 56],
- [ 0, 73, 0, 64, 0, 38, 0, 35, 61, 0, 0, 52, 0, 7, 0, 51, 0, 0, 0, 34],
- [ 0, 0, 28, 0, 34, 5, 63, 45, 14, 42, 60, 16, 76, 54, 99, 0, 28, 30, 0, 0],
- [58, 37, 14, 0, 0, 0, 94, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 8, 90, 53],
- [86, 74, 94, 0, 49, 10, 60, 0, 40, 18, 0, 0, 0, 31, 60, 24, 0, 1, 0, 29],
- [53, 0, 0, 97, 0, 0, 58, 0, 0, 39, 44, 47, 0, 0, 0, 12, 50, 0, 0, 11],
- [ 4, 0, 92, 10, 28, 0, 0, 89, 0, 0, 18, 54, 23, 39, 0, 2, 0, 48, 0, 92],
- [ 0, 0, 90, 77, 95, 33, 0, 0, 49, 22, 39, 0, 0, 0, 0, 0, 0, 40, 0, 0],
- [96, 0, 0, 0, 0, 38, 86, 0, 22, 76, 0, 0, 0, 0, 83, 88, 95, 65, 72, 0],
- [81, 65, 0, 4, 60, 0, 19, 0, 0, 68, 0, 0, 89, 0, 67, 22, 0, 0, 55, 33]],
- ZZ),
- DM([
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]],
- ZZ),
- ZZ(1),
- ),
- (
- 'zz_large_3',
- DM([
- [62,35,89,58,22,47,30,28,52,72,17,56,80,26,64,21,10,35,24,42,96,32,23,50,92,37,76,94,63,66],
- [20,47,96,34,10,98,19,6,29,2,19,92,61,94,38,41,32,9,5,94,31,58,27,41,72,85,61,62,40,46],
- [69,26,35,68,25,52,94,13,38,65,81,10,29,15,5,4,13,99,85,0,80,51,60,60,26,77,85,2,87,25],
- [99,58,69,15,52,12,18,7,27,56,12,54,21,92,38,95,33,83,28,1,44,8,29,84,92,12,2,25,46,46],
- [93,13,55,48,35,87,24,40,23,35,25,32,0,19,0,85,4,79,26,11,46,75,7,96,76,11,7,57,99,75],
- [128,85,26,51,161,173,77,78,85,103,123,58,91,147,38,91,161,36,123,81,102,25,75,59,17,150,112,65,77,143],
- [15,59,61,82,12,83,34,8,94,71,66,7,91,21,48,69,26,12,64,38,97,87,38,15,51,33,93,43,66,89],
- [74,74,53,39,69,90,41,80,32,66,40,83,87,87,61,38,12,80,24,49,37,90,19,33,56,0,46,57,56,60],
- [82,11,0,25,56,58,39,49,92,93,80,38,19,62,33,85,19,61,14,30,45,91,97,34,97,53,92,28,33,43],
- [83,79,41,16,95,35,53,45,26,4,71,76,61,69,69,72,87,92,59,72,54,11,22,83,8,57,77,55,19,22],
- [49,34,13,31,72,77,52,70,46,41,37,6,42,66,35,6,75,33,62,57,30,14,26,31,9,95,89,13,12,90],
- [29,3,49,30,51,32,77,41,38,50,16,1,87,81,93,88,58,91,83,0,38,67,29,64,60,84,5,60,23,28],
- [79,51,13,20,89,96,25,8,39,62,86,52,49,81,3,85,86,3,61,24,72,11,49,28,8,55,23,52,65,53],
- [96,86,73,20,41,20,37,18,10,61,85,24,40,83,69,41,4,92,23,99,64,33,18,36,32,56,60,98,39,24],
- [32,62,47,80,51,66,17,1,9,30,65,75,75,88,99,92,64,53,53,86,38,51,41,14,35,18,39,25,26,32],
- [39,21,8,16,33,6,35,85,75,62,43,34,18,68,71,28,32,18,12,0,81,53,1,99,3,5,45,99,35,33],
- [19,95,89,45,75,94,92,5,84,93,34,17,50,56,79,98,68,82,65,81,51,90,5,95,33,71,46,61,14,7],
- [53,92,8,49,67,84,21,79,49,95,66,48,36,14,62,97,26,45,58,31,83,48,11,89,67,72,91,34,56,89],
- [56,76,99,92,40,8,0,16,15,48,35,72,91,46,81,14,86,60,51,7,33,12,53,78,48,21,3,89,15,79],
- [81,43,33,49,6,49,36,32,57,74,87,91,17,37,31,17,67,1,40,38,69,8,3,48,59,37,64,97,11,3],
- [98,48,77,16,2,48,57,38,63,59,79,35,16,71,60,86,71,41,14,76,80,97,77,69,4,58,22,55,26,73],
- [80,47,78,44,31,48,47,29,29,62,19,21,17,24,19,3,53,93,97,57,13,54,12,10,77,66,60,75,32,21],
- [86,63,2,13,71,38,86,23,18,15,91,65,77,65,9,92,50,0,17,42,99,80,99,27,10,99,92,9,87,84],
- [66,27,72,13,13,15,72,75,39,3,14,71,15,68,10,19,49,54,11,29,47,20,63,13,97,47,24,62,16,96],
- [42,63,83,60,49,68,9,53,75,87,40,25,12,63,0,12,0,95,46,46,55,25,89,1,51,1,1,96,80,52],
- [35,9,97,13,86,39,66,48,41,57,23,38,11,9,35,72,88,13,41,60,10,64,71,23,1,5,23,57,6,19],
- [70,61,5,50,72,60,77,13,41,94,1,45,52,22,99,47,27,18,99,42,16,48,26,9,88,77,10,94,11,92],
- [55,68,58,2,72,56,81,52,79,37,1,40,21,46,27,60,37,13,97,42,85,98,69,60,76,44,42,46,29,73],
- [73,0,43,17,89,97,45,2,68,14,55,60,95,2,74,85,88,68,93,76,38,76,2,51,45,76,50,79,56,18],
- [72,58,41,39,24,80,23,79,44,7,98,75,30,6,85,60,20,58,77,71,90,51,38,80,30,15,33,10,82,8]],
- ZZ),
- Matrix([
- [eye(29) * 2028539767964472550625641331179545072876560857886207583101,
- Matrix([ 4260575808093245475167216057435155595594339172099000182569,
- 169148395880755256182802335904188369274227936894862744452,
- 4915975976683942569102447281579134986891620721539038348914,
- 6113916866367364958834844982578214901958429746875633283248,
- 5585689617819894460378537031623265659753379011388162534838,
- 359776822829880747716695359574308645968094838905181892423,
- -2800926112141776386671436511182421432449325232461665113305,
- 941642292388230001722444876624818265766384442910688463158,
- 3648811843256146649321864698600908938933015862008642023935,
- -4104526163246702252932955226754097174212129127510547462419,
- -704814955438106792441896903238080197619233342348191408078,
- 1640882266829725529929398131287244562048075707575030019335,
- -4068330845192910563212155694231438198040299927120544468520,
- 136589038308366497790495711534532612862715724187671166593,
- 2544937011460702462290799932536905731142196510605191645593,
- 755591839174293940486133926192300657264122907519174116472,
- -3683838489869297144348089243628436188645897133242795965021,
- -522207137101161299969706310062775465103537953077871128403,
- -2260451796032703984456606059649402832441331339246756656334,
- -6476809325293587953616004856993300606040336446656916663680,
- 3521944238996782387785653800944972787867472610035040989081,
- 2270762115788407950241944504104975551914297395787473242379,
- -3259947194628712441902262570532921252128444706733549251156,
- -5624569821491886970999097239695637132075823246850431083557,
- -3262698255682055804320585332902837076064075936601504555698,
- 5786719943788937667411185880136324396357603606944869545501,
- -955257841973865996077323863289453200904051299086000660036,
- -1294235552446355326174641248209752679127075717918392702116,
- -3718353510747301598130831152458342785269166356215331448279,
- ]),],
- [zeros(1, 29), zeros(1, 1)],
- ]).to_DM().to_dense(),
- ZZ(2028539767964472550625641331179545072876560857886207583101),
- ),
- (
- 'qq_1',
- DM([[(1,2), 0], [0, 2]], QQ),
- DM([[1, 0], [0, 1]], QQ),
- QQ(1),
- ),
- (
- # Standard square case
- 'qq_2',
- DM([[0, 1],
- [1, 1]], QQ),
- DM([[1, 0],
- [0, 1]], QQ),
- QQ(1),
- ),
- (
- # m < n case
- 'qq_3',
- DM([[1, 2, 1],
- [3, 4, 1]], QQ),
- DM([[1, 0, -1],
- [0, 1, 1]], QQ),
- QQ(1),
- ),
- (
- # same m < n but reversed
- 'qq_4',
- DM([[3, 4, 1],
- [1, 2, 1]], QQ),
- DM([[1, 0, -1],
- [0, 1, 1]], QQ),
- QQ(1),
- ),
- (
- # m > n case
- 'qq_5',
- DM([[1, 0],
- [1, 3],
- [0, 1]], QQ),
- DM([[1, 0],
- [0, 1],
- [0, 0]], QQ),
- QQ(1),
- ),
- (
- # Example with missing pivot
- 'qq_6',
- DM([[1, 0, 1],
- [3, 0, 1]], QQ),
- DM([[1, 0, 0],
- [0, 0, 1]], QQ),
- QQ(1),
- ),
- (
- # This is intended to trigger the threshold where we give up on
- # clearing denominators.
- 'qq_large_1',
- qq_large_1,
- DomainMatrix.eye(11, QQ).to_dense(),
- QQ(1),
- ),
- (
- # This is intended to trigger the threshold where we use rref_den over
- # QQ.
- 'qq_large_2',
- qq_large_2,
- DomainMatrix.eye(11, QQ).to_dense(),
- QQ(1),
- ),
- (
- # Example with missing pivot and no replacement
- # This example is just enough to show a different result from the dense
- # and sparse versions of the algorithm:
- #
- # >>> A = Matrix([[0, 1], [0, 2], [1, 0]])
- # >>> A.to_DM().to_sparse().rref_den()[0].to_Matrix()
- # Matrix([
- # [1, 0],
- # [0, 1],
- # [0, 0]])
- # >>> A.to_DM().to_dense().rref_den()[0].to_Matrix()
- # Matrix([
- # [2, 0],
- # [0, 2],
- # [0, 0]])
- #
- 'qq_7',
- DM([[0, 1],
- [0, 2],
- [1, 0]], QQ),
- DM([[1, 0],
- [0, 1],
- [0, 0]], QQ),
- QQ(1),
- ),
- (
- # Gaussian integers
- 'zz_i_1',
- DM([[(0,1), 1, 1],
- [ 1, 1, 1]], ZZ_I),
- DM([[1, 0, 0],
- [0, 1, 1]], ZZ_I),
- ZZ_I(1),
- ),
- (
- # EX: test_issue_23718
- 'EX_1',
- DM([
- [a, b, 1],
- [c, d, 1]], EX),
- DM([[a*d - b*c, 0, -b + d],
- [ 0, a*d - b*c, a - c]], EX),
- EX(a*d - b*c),
- ),
- ]
- def _to_DM(A, ans):
- """Convert the answer to DomainMatrix."""
- if isinstance(A, DomainMatrix):
- return A.to_dense()
- elif isinstance(A, Matrix):
- return A.to_DM(ans.domain).to_dense()
- if not (hasattr(A, 'shape') and hasattr(A, 'domain')):
- shape, domain = ans.shape, ans.domain
- else:
- shape, domain = A.shape, A.domain
- if isinstance(A, (DDM, list)):
- return DomainMatrix(list(A), shape, domain).to_dense()
- elif isinstance(A, (SDM, dict)):
- return DomainMatrix(dict(A), shape, domain).to_dense()
- else:
- assert False # pragma: no cover
- def _pivots(A_rref):
- """Return the pivots from the rref of A."""
- return tuple(sorted(map(min, A_rref.to_sdm().values())))
- def _check_cancel(result, rref_ans, den_ans):
- """Check the cancelled result."""
- rref, den, pivots = result
- if isinstance(rref, (DDM, SDM, list, dict)):
- assert type(pivots) is list
- pivots = tuple(pivots)
- rref = _to_DM(rref, rref_ans)
- rref2, den2 = rref.cancel_denom(den)
- assert rref2 == rref_ans
- assert den2 == den_ans
- assert pivots == _pivots(rref)
- def _check_divide(result, rref_ans, den_ans):
- """Check the divided result."""
- rref, pivots = result
- if isinstance(rref, (DDM, SDM, list, dict)):
- assert type(pivots) is list
- pivots = tuple(pivots)
- rref_ans = rref_ans.to_field() / den_ans
- rref = _to_DM(rref, rref_ans)
- assert rref == rref_ans
- assert _pivots(rref) == pivots
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_Matrix_rref(name, A, A_rref, den):
- K = A.domain
- A = A.to_Matrix()
- A_rref_found, pivots = A.rref()
- if K.is_EX:
- A_rref_found = A_rref_found.expand()
- _check_divide((A_rref_found, pivots), A_rref, den)
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_dm_dense_rref(name, A, A_rref, den):
- A = A.to_field()
- _check_divide(A.rref(), A_rref, den)
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_dm_dense_rref_den(name, A, A_rref, den):
- _check_cancel(A.rref_den(), A_rref, den)
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_dm_sparse_rref(name, A, A_rref, den):
- A = A.to_field().to_sparse()
- _check_divide(A.rref(), A_rref, den)
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_dm_sparse_rref_den(name, A, A_rref, den):
- A = A.to_sparse()
- _check_cancel(A.rref_den(), A_rref, den)
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_dm_sparse_rref_den_keep_domain(name, A, A_rref, den):
- A = A.to_sparse()
- A_rref_f, den_f, pivots_f = A.rref_den(keep_domain=False)
- A_rref_f = A_rref_f.to_field() / den_f
- _check_divide((A_rref_f, pivots_f), A_rref, den)
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_dm_sparse_rref_den_keep_domain_CD(name, A, A_rref, den):
- A = A.to_sparse()
- A_rref_f, den_f, pivots_f = A.rref_den(keep_domain=False, method='CD')
- A_rref_f = A_rref_f.to_field() / den_f
- _check_divide((A_rref_f, pivots_f), A_rref, den)
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_dm_sparse_rref_den_keep_domain_GJ(name, A, A_rref, den):
- A = A.to_sparse()
- A_rref_f, den_f, pivots_f = A.rref_den(keep_domain=False, method='GJ')
- A_rref_f = A_rref_f.to_field() / den_f
- _check_divide((A_rref_f, pivots_f), A_rref, den)
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_ddm_rref_den(name, A, A_rref, den):
- A = A.to_ddm()
- _check_cancel(A.rref_den(), A_rref, den)
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_sdm_rref_den(name, A, A_rref, den):
- A = A.to_sdm()
- _check_cancel(A.rref_den(), A_rref, den)
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_ddm_rref(name, A, A_rref, den):
- A = A.to_field().to_ddm()
- _check_divide(A.rref(), A_rref, den)
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_sdm_rref(name, A, A_rref, den):
- A = A.to_field().to_sdm()
- _check_divide(A.rref(), A_rref, den)
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_ddm_irref(name, A, A_rref, den):
- A = A.to_field().to_ddm().copy()
- pivots_found = ddm_irref(A)
- _check_divide((A, pivots_found), A_rref, den)
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_ddm_irref_den(name, A, A_rref, den):
- A = A.to_ddm().copy()
- (den_found, pivots_found) = ddm_irref_den(A, A.domain)
- result = (A, den_found, pivots_found)
- _check_cancel(result, A_rref, den)
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_sparse_sdm_rref(name, A, A_rref, den):
- A = A.to_field().to_sdm()
- _check_divide(sdm_irref(A)[:2], A_rref, den)
- @pytest.mark.parametrize('name, A, A_rref, den', RREF_EXAMPLES)
- def test_sparse_sdm_rref_den(name, A, A_rref, den):
- A = A.to_sdm().copy()
- K = A.domain
- _check_cancel(sdm_rref_den(A, K), A_rref, den)
|