@@ -870,302 +870,3 @@ cdef class Matrix_modn_sparse(Matrix_sparse):
870
870
return d
871
871
else :
872
872
raise ValueError (" no algorithm '%s '" % algorithm)
873
-
874
- def _solve_right_nonsingular_square (self , B , algorithm = None , check_rank = False ):
875
- r """
876
- If self is a matrix `A`, then this function returns a
877
- vector or matrix `X` such that `A X = B`. If
878
- `B` is a vector then `X` is a vector and if
879
- `B` is a matrix, then `X` is a matrix.
880
-
881
- .. NOTE::
882
-
883
- DEPRECATED. In Sage one can also write ``A \ B`` for
884
- ``A. solve_right( B) ``, i. e. , Sage implements the "the
885
- MATLAB/Octave backslash operator".
886
-
887
- INPUT:
888
-
889
-
890
- - ``B`` - a matrix or vector
891
-
892
- - ``algorithm`` - one of the following:
893
-
894
- - ``'linbox'`` or ``'linbox_default'`` - ( default) use LinBox
895
- and let it chooses the appropriate algorithm
896
-
897
- - ``linbox_dense_elimination'`` - use LinBox dense elimination
898
-
899
- - ``'linbox_sparse_elimination'`` - use LinBox sparse elimination
900
-
901
- - ``'linbox_ blackbox'`` - LinBox via a Blackbox algorithm
902
-
903
- - ``'linbox_wiedemann'`` - use LinBox implementation of
904
- Wiedemann's algorithm
905
-
906
- - ``'generic'`` - use the Sage generic implementation
907
- ( via inversion)
908
-
909
- - ``check_rank`` - whether to check that the rank is maximal
910
-
911
- OUTPUT: a matrix or vector
912
-
913
- EXAMPLES::
914
-
915
- sage: A = matrix( ZZ, 3, [1,2,3,-1,2,5,2,3,1 ], sparse=True)
916
- sage: b = vector( ZZ, [1,2,3 ])
917
- sage: x = A. solve_right( b)
918
- sage: x
919
- ( -13/12, 23/12, -7/12)
920
- sage: A * x
921
- ( 1, 2, 3)
922
-
923
- sage: u = matrix( ZZ, 3, 2, [0,1,1,1,0,2 ])
924
- sage: x = A. solve_right( u)
925
- sage: x
926
- [-7/12 -1/6 ]
927
- [ 5/12 5/6 ]
928
- [-1/12 -1/6 ]
929
- sage: A * x
930
- [0 1 ]
931
- [1 1 ]
932
- [0 2 ]
933
- """
934
- if check_rank and self .rank() < self .nrows():
935
- from sage.matrix.matrix2 import NotFullRankError
936
- raise NotFullRankError
937
-
938
- if self .base_ring() != B.base_ring():
939
- B = B.change_ring(self .base_ring())
940
- if self .nrows() != B.nrows():
941
- raise ValueError (" input matrices must have the same number of rows." )
942
-
943
- if algorithm == " generic" :
944
- return Matrix_sparse.solve_right(self , B)
945
- else :
946
- if isinstance (B, Matrix):
947
- from sage.matrix.special import diagonal_matrix
948
- m, d = self ._solve_matrix_linbox(B, algorithm)
949
- return m * diagonal_matrix([QQ((1 ,x)) for x in d])
950
- else :
951
- v, d = self ._solve_vector_linbox(B, algorithm)
952
- return v / d
953
-
954
- def _solve_vector_linbox (self , v , algorithm = None ):
955
- r """
956
- Return a pair ``( a, d) `` so that ``d * b = m * a``
957
-
958
- If there is no solution a ``ValueError`` is raised.
959
-
960
- INPUT:
961
-
962
- - ``b`` -- a dense integer vector
963
-
964
- - ``algorithm`` -- ( optional) either ``None``, ``'dense_elimination'``,
965
- ``'sparse_elimination'``, ``'wiedemann'`` or ``'blackbox'``.
966
-
967
- OUTPUT: a pair ``( a, d) `` consisting of
968
-
969
- - ``a`` -- a dense integer vector
970
-
971
- - ``d`` -- an integer
972
-
973
- EXAMPLES::
974
-
975
- sage: m = matrix( ZZ, 4, sparse=True)
976
- sage: m[0,0 ] = m[1,2 ] = m[2,0 ] = m[3,3 ] = 2
977
- sage: m[0,2 ] = m[1,1 ] = -1
978
- sage: m[2,3 ] = m[3,0 ] = -3
979
-
980
- sage: b0 = vector(( 1,1,1,1))
981
- sage: m. _solve_vector_linbox( b0)
982
- (( -1, -7, -3, -1) , 1)
983
- sage: m. _solve_vector_linbox( b0, 'dense_elimination')
984
- (( -1, -7, -3, -1) , 1)
985
- sage: m. _solve_vector_linbox( b0, 'sparse_elimination')
986
- (( -1, -7, -3, -1) , 1)
987
- sage: m. _solve_vector_linbox( b0, 'wiedemann')
988
- (( -1, -7, -3, -1) , 1)
989
- sage: m. _solve_vector_linbox( b0, 'blackbox')
990
- (( -1, -7, -3, -1) , 1)
991
-
992
- sage: b1 = vector(( 1,1,-1,1))
993
- sage: a1, d1 = m. _solve_vector_linbox( b1)
994
- sage: d1 * b1 == m * a1
995
- True
996
-
997
- TESTS::
998
-
999
- sage: algos = ["default", "dense_elimination", "sparse_elimination",
1000
- ....: "blackbox", "wiedemann" ]
1001
- sage: for i in range( 20) :
1002
- .... : dim = randint( 1, 30)
1003
- .... : M = MatrixSpace( ZZ, dim, sparse=True)
1004
- .... : density = min( 1, 4/dim)
1005
- .... : m = M. random_element( density=density)
1006
- .... : while m. rank( ) != dim:
1007
- .... : m = M. random_element( density=density)
1008
- .... : U = m. column_space( ) . dense_module( )
1009
- .... : for algo in algos:
1010
- .... : u, d = m. _solve_vector_linbox( U. zero( ) , algorithm=algo)
1011
- .... : assert u. is_zero( )
1012
- .... : b = U. random_element( )
1013
- .... : x, d = m. _solve_vector_linbox( b, algorithm=algo)
1014
- .... : assert m * x == d * b
1015
- """
1016
- Vin = self .column_ambient_module(base_ring = None , sparse = False )
1017
- v = Vin(v)
1018
-
1019
- if self ._nrows == 0 or self ._ncols == 0 :
1020
- raise ValueError (" not implemented for nrows=0 or ncols=0" )
1021
-
1022
- # LinBox "solve" is mostly broken for nonsquare or singular matrices.
1023
- # The conditions below could be removed once all LinBox issues has
1024
- # been solved.
1025
- if self ._nrows != self ._ncols or self .rank() != self ._nrows:
1026
- raise ValueError (" only available for full rank square matrices" )
1027
-
1028
- cdef givaro.ZRing givZZ
1029
- cdef linbox.SparseMatrix_integer * A = new_linbox_matrix_integer_sparse(givZZ, self )
1030
- cdef linbox.DenseVector_integer * b = new_linbox_vector_integer_dense(givZZ, v)
1031
- cdef linbox.DenseVector_integer * res = new linbox.DenseVector_integer(givZZ, < size_t> self ._ncols)
1032
- cdef givaro.Integer D
1033
-
1034
- method = get_method(algorithm)
1035
-
1036
- if method == METHOD_DEFAULT:
1037
- linbox.solve(res[0 ], D, A[0 ], b[0 ])
1038
- elif method == METHOD_WIEDEMANN:
1039
- linbox.solve(res[0 ], D, A[0 ], b[0 ], linbox.Method.Wiedemann())
1040
- elif method == METHOD_DENSE_ELIMINATION:
1041
- linbox.solve(res[0 ], D, A[0 ], b[0 ], linbox.Method.DenseElimination())
1042
- elif method == METHOD_SPARSE_ELIMINATION:
1043
- linbox.solve(res[0 ], D, A[0 ], b[0 ], linbox.Method.SparseElimination())
1044
- elif method == METHOD_BLACKBOX:
1045
- linbox.solve(res[0 ], D, A[0 ], b[0 ], linbox.Method.Blackbox())
1046
-
1047
- Vout = self .row_ambient_module(base_ring = None , sparse = False )
1048
- res_sage = new_sage_vector_integer_dense(Vout, res[0 ])
1049
- cdef Integer d = PY_NEW(Integer)
1050
- mpz_set(d.value, D.get_mpz_const())
1051
-
1052
- del A
1053
- del b
1054
- del res
1055
-
1056
- return (res_sage, d)
1057
-
1058
- def _solve_matrix_linbox (self , mat , algorithm = None ):
1059
- r """
1060
- Solve the equation ``A x = mat`` where ``A`` is this matrix.
1061
-
1062
- EXAMPLES::
1063
-
1064
- sage: m = matrix( ZZ, [[1,2 ],[1,0 ]], sparse=True)
1065
- sage: b = matrix( ZZ, 2, 4, [1,0,2,0,1,1,2,0 ], sparse=False)
1066
- sage: u, d = m. _solve_matrix_linbox( b)
1067
- sage: u
1068
- [ 1 2 2 0 ]
1069
- [ 0 -1 0 0 ]
1070
- sage: m * u == b * diagonal_matrix( d)
1071
- True
1072
-
1073
- sage: u, d = m. _solve_matrix_linbox( [[1,3,4 ],[0,1,0 ]])
1074
- sage: u
1075
- [0 1 0 ]
1076
- [1 1 2 ]
1077
- sage: d
1078
- ( 2, 1, 1)
1079
-
1080
- Test input::
1081
-
1082
- sage: m = matrix( ZZ, [[1,2 ],[1,0 ]], sparse=True)
1083
- sage: b = matrix( ZZ, 3, 3, range( 9))
1084
- sage: m. _solve_matrix_linbox( b)
1085
- Traceback ( most recent call last) :
1086
- ...
1087
- ValueError: wrong matrix dimension
1088
-
1089
- sage: m. _solve_matrix_linbox( [[1,1 ],[2,3 ]], algorithm='hop')
1090
- Traceback ( most recent call last) :
1091
- ...
1092
- ValueError: unknown algorithm
1093
-
1094
- TESTS::
1095
-
1096
- sage: algos = ["default", "dense_elimination", "sparse_elimination",
1097
- ....: "blackbox", "wiedemann" ]
1098
-
1099
- sage: for _ in range( 10) :
1100
- .... : dim = randint( 2, 10)
1101
- .... : M = MatrixSpace( ZZ, dim, sparse=True)
1102
- .... : m = M. random_element( density=min( 1,10/dim))
1103
- .... : while m. rank( ) != dim:
1104
- .... : m = M. random_element( density=min( 1,10/dim))
1105
- .... : b = random_matrix( ZZ, dim, 7)
1106
- .... : Mb = b. parent( )
1107
- .... : for algo in algos:
1108
- .... : u, d = m. _solve_matrix_linbox( b, algo)
1109
- .... : assert m * u == b * diagonal_matrix( d)
1110
- """
1111
- if self ._nrows == 0 or self ._ncols == 0 :
1112
- raise ValueError (" not implemented for nrows=0 or ncols=0" )
1113
-
1114
- from sage.matrix.constructor import matrix
1115
- from sage.modules.free_module_element import vector
1116
-
1117
- cdef Matrix_integer_dense B
1118
- if not isinstance (mat, Matrix2):
1119
- B = < Matrix_integer_dense?> matrix(ZZ, mat, sparse = False )
1120
- else :
1121
- B = < Matrix_integer_dense?> mat.change_ring(ZZ).dense_matrix()
1122
- if B._nrows != self ._nrows:
1123
- raise ValueError (" wrong matrix dimension" )
1124
-
1125
- # LinBox "solve" is mostly broken for singular matrices. The
1126
- # conditions below could be removed once all LinBox issues
1127
- # have been solved.
1128
- if self ._nrows != self ._ncols or self .rank() != self ._nrows:
1129
- raise ValueError (" only available for full rank square matrices" )
1130
-
1131
- cdef givaro.ZRing givZZ
1132
- cdef linbox.SparseMatrix_integer * A = new_linbox_matrix_integer_sparse(givZZ, self )
1133
- cdef linbox.DenseVector_integer * b = new linbox.DenseVector_integer(givZZ, < size_t> self ._nrows)
1134
- cdef linbox.DenseVector_integer * res = new linbox.DenseVector_integer(givZZ, < size_t> self ._ncols)
1135
- cdef givaro.Integer D
1136
-
1137
- cdef int algo = get_method(algorithm)
1138
-
1139
- cdef Matrix_integer_dense X = matrix(ZZ, A.coldim(), B.ncols(), sparse = False ) # solution
1140
- cdef Vector_integer_dense d = vector(ZZ, X.ncols(), sparse = False ) # multipliers
1141
-
1142
- cdef size_t i, j
1143
- for i in range (X.ncols()):
1144
- # set b to the i-th column of B
1145
- for j in range (A.coldim()):
1146
- fmpz_get_mpz(< mpz_t> b.getEntry(j).get_mpz(), fmpz_mat_entry(B._matrix, j, i))
1147
-
1148
- # solve the current row
1149
- if algo == METHOD_DEFAULT:
1150
- linbox.solve(res[0 ], D, A[0 ], b[0 ])
1151
- elif algo == METHOD_DENSE_ELIMINATION:
1152
- linbox.solve(res[0 ], D, A[0 ], b[0 ], linbox.Method.DenseElimination())
1153
- elif algo == METHOD_SPARSE_ELIMINATION:
1154
- linbox.solve(res[0 ], D, A[0 ], b[0 ], linbox.Method.SparseElimination())
1155
- elif algo == METHOD_BLACKBOX:
1156
- linbox.solve(res[0 ], D, A[0 ], b[0 ], linbox.Method.Blackbox())
1157
- elif algo == METHOD_WIEDEMANN:
1158
- linbox.solve(res[0 ], D, A[0 ], b[0 ], linbox.Method.Wiedemann())
1159
-
1160
- # set i-th column of X to be res
1161
- for j in range (A.coldim()):
1162
- fmpz_set_mpz(fmpz_mat_entry(X._matrix, j, i), res[0 ].getEntry(j).get_mpz())
1163
-
1164
- # compute common gcd
1165
- mpz_set(d._entries[i], D.get_mpz_const())
1166
-
1167
- del A
1168
- del b
1169
- del res
1170
-
1171
- return X, d
0 commit comments