957 | | def solve_left(self,vec): |
| 957 | def solve_right(self, b): |
| 958 | r""" |
| 959 | Solve the vector equation ``A*x = b`` for a nonsingular ``A``. |
| 960 | |
| 961 | INPUT: |
| 962 | |
| 963 | - ``self`` - a square matrix that is nonsigular (of full rank). |
| 964 | - ``b`` - a vector of the correct size. Elements of the vector |
| 965 | must coerce into the base ring of the coefficient matrix. In |
| 966 | particular, if ``b`` has entries from ``CDF`` then ``self`` |
| 967 | must have ``CDF`` as its base ring. |
| 968 | |
| 969 | OUTPUT: |
| 970 | |
| 971 | The unique solution ``x`` to the matrix equation ``A*x = b``, |
| 972 | as a vector over the same base ring as ``self``. |
| 973 | |
| 974 | ALGORITHM: |
| 975 | |
| 976 | Uses the ``solve()`` routine from the SciPy ``scipy.linalg`` module. |
| 977 | |
| 978 | EXAMPLES: |
| 979 | |
| 980 | Over the reals. :: |
| 981 | |
| 982 | sage: A = matrix(RDF, 3,3, [1,2,5,7.6,2.3,1,1,2,-1]); A |
| 983 | [ 1.0 2.0 5.0] |
| 984 | [ 7.6 2.3 1.0] |
| 985 | [ 1.0 2.0 -1.0] |
| 986 | sage: b = vector(RDF,[1,2,3]) |
| 987 | sage: x = A.solve_right(b); x |
| 988 | (-0.113695090439, 1.39018087855, -0.333333333333) |
| 989 | sage: x.parent() |
| 990 | Vector space of dimension 3 over Real Double Field |
| 991 | sage: A*x |
| 992 | (1.0, 2.0, 3.0) |
| 993 | |
| 994 | Over the complex numbers. :: |
| 995 | |
| 996 | sage: A = matrix(CDF, [[ 0, -1 + 2*I, 1 - 3*I, I], |
| 997 | ... [2 + 4*I, -2 + 3*I, -1 + 2*I, -1 - I], |
| 998 | ... [ 2 + I, 1 - I, -1, 5], |
| 999 | ... [ 3*I, -1 - I, -1 + I, -3 + I]]) |
| 1000 | sage: b = vector(CDF, [2 -3*I, 3, -2 + 3*I, 8]) |
| 1001 | sage: x = A.solve_right(b); x |
| 1002 | (1.96841637... - 1.07606761...*I, -0.614323843... + 1.68416370...*I, 0.0733985765... + 1.73487544...*I, -1.6018683... + 0.524021352...*I) |
| 1003 | sage: x.parent() |
| 1004 | Vector space of dimension 4 over Complex Double Field |
| 1005 | sage: abs(A*x - b) < 1e-14 |
| 1006 | True |
| 1007 | |
| 1008 | The vector of constants, ``b``, can be given in a |
| 1009 | variety of forms, so long as it coerces to a vector |
| 1010 | over the same base ring as the coefficient matrix. :: |
| 1011 | |
| 1012 | sage: A=matrix(CDF, 5, [1/(i+j+1) for i in range(5) for j in range(5)]) |
| 1013 | sage: A.solve_right([1]*5) |
| 1014 | (5.0..., -120.0..., 630.0..., -1120.0..., 630.0...) |
| 1015 | |
| 1016 | TESTS: |
| 1017 | |
| 1018 | A degenerate case. :: |
| 1019 | |
| 1020 | sage: A = matrix(RDF, 0, 0, []) |
| 1021 | sage: A.solve_right(vector(RDF,[])) |
| 1022 | () |
| 1023 | |
| 1024 | The coefficent matrix must be square. :: |
| 1025 | |
| 1026 | sage: A = matrix(RDF, 2, 3, range(6)) |
| 1027 | sage: b = vector(RDF, [1,2,3]) |
| 1028 | sage: A.solve_right(b) |
| 1029 | Traceback (most recent call last): |
| 1030 | ... |
| 1031 | ValueError: coefficient matrix of a system over RDF/CDF must be square, not 2 x 3 |
| 1032 | |
| 1033 | The coefficient matrix must be nonsingular. :: |
| 1034 | |
| 1035 | sage: A = matrix(RDF, 5, range(25)) |
| 1036 | sage: b = vector(RDF, [1,2,3,4,5]) |
| 1037 | sage: A.solve_right(b) |
| 1038 | Traceback (most recent call last): |
| 1039 | ... |
| 1040 | LinAlgError: singular matrix |
| 1041 | |
| 1042 | The vector of constants needs the correct degree. :: |
| 1043 | |
| 1044 | sage: A = matrix(RDF, 5, range(25)) |
| 1045 | sage: b = vector(RDF, [1,2,3,4]) |
| 1046 | sage: A.solve_right(b) |
| 1047 | Traceback (most recent call last): |
| 1048 | ... |
| 1049 | TypeError: vector of constants over Real Double Field incompatible with matrix over Real Double Field |
| 1050 | |
| 1051 | The vector of constants needs to be compatible with |
| 1052 | the base ring of the coefficient matrix. :: |
| 1053 | |
| 1054 | sage: F.<a> = FiniteField(27) |
| 1055 | sage: b = vector(F, [a,a,a,a,a]) |
| 1056 | sage: A.solve_right(b) |
| 1057 | Traceback (most recent call last): |
| 1058 | ... |
| 1059 | TypeError: vector of constants over Finite Field in a of size 3^3 incompatible with matrix over Real Double Field |
| 1060 | |
| 1061 | With a coefficient matrix over ``RDF``, a vector of constants |
| 1062 | over ``CDF`` can be accomodated by converting the base ring |
| 1063 | of the coefficient matrix. :: |
| 1064 | |
| 1065 | sage: A = matrix(RDF, 2, range(4)) |
| 1066 | sage: b = vector(CDF, [1+I,2]) |
| 1067 | sage: A.solve_right(b) |
| 1068 | Traceback (most recent call last): |
| 1069 | ... |
| 1070 | TypeError: vector of constants over Complex Double Field incompatible with matrix over Real Double Field |
| 1071 | |
| 1072 | sage: B = A.change_ring(CDF) |
| 1073 | sage: B.solve_right(b) |
| 1074 | (-0.5 - 1.5*I, 1.0 + 1.0*I) |
959 | | Solve the equation A*x = b, where |
960 | | |
| 1076 | if not self.is_square(): |
| 1077 | raise ValueError("coefficient matrix of a system over RDF/CDF must be square, not %s x %s " % (self.nrows(), self.ncols())) |
| 1078 | M = self._column_ambient_module() |
| 1079 | try: |
| 1080 | vec = M(b) |
| 1081 | except TypeError: |
| 1082 | raise TypeError("vector of constants over %s incompatible with matrix over %s" % (b.base_ring(), self.base_ring())) |
| 1083 | if vec.degree() != self.ncols(): |
| 1084 | raise ValueError("vector of constants in linear system over RDF/CDF must have degree equal to the number of columns for the coefficient matrix, not %s" % vec.degree() ) |
| 1085 | |
| 1086 | if self._ncols == 0: |
| 1087 | return M.zero_vector() |
| 1088 | |
| 1089 | global scipy |
| 1090 | if scipy is None: |
| 1091 | import scipy |
| 1092 | import scipy.linalg |
| 1093 | # may raise a LinAlgError for a singular matrix |
| 1094 | return M(scipy.linalg.solve(self._matrix_numpy, vec.numpy())) |
| 1095 | |
| 1096 | def solve_left(self, b): |
| 1097 | r""" |
| 1098 | Solve the vector equation ``x*A = b`` for a nonsingular ``A``. |
| 1099 | |
| 1100 | INPUT: |
| 1101 | |
| 1102 | - ``self`` - a square matrix that is nonsigular (of full rank). |
| 1103 | - ``b`` - a vector of the correct size. Elements of the vector |
| 1104 | must coerce into the base ring of the coefficient matrix. In |
| 1105 | particular, if ``b`` has entries from ``CDF`` then ``self`` |
| 1106 | must have ``CDF`` as its base ring. |
| 1107 | |
| 1108 | OUTPUT: |
| 1109 | |
| 1110 | The unique solution ``x`` to the matrix equation ``x*A = b``, |
| 1111 | as a vector over the same base ring as ``self``. |
| 1112 | |
| 1113 | ALGORITHM: |
| 1114 | |
| 1115 | Uses the ``solve()`` routine from the SciPy ``scipy.linalg`` module, |
| 1116 | after taking the tranpose of the coefficient matrix. |
| 1117 | |
| 1134 | Over the complex numbers. :: |
| 1135 | |
| 1136 | sage: A = matrix(CDF, [[ 0, -1 + 2*I, 1 - 3*I, I], |
| 1137 | ... [2 + 4*I, -2 + 3*I, -1 + 2*I, -1 - I], |
| 1138 | ... [ 2 + I, 1 - I, -1, 5], |
| 1139 | ... [ 3*I, -1 - I, -1 + I, -3 + I]]) |
| 1140 | sage: b = vector(CDF, [2 -3*I, 3, -2 + 3*I, 8]) |
| 1141 | sage: x = A.solve_left(b); x |
| 1142 | (-1.55765124... - 0.644483985...*I, 0.183274021... + 0.286476868...*I, 0.270818505... + 0.246619217...*I, -1.69003558... - 0.828113879...*I) |
| 1143 | sage: x.parent() |
| 1144 | Vector space of dimension 4 over Complex Double Field |
| 1145 | sage: abs(x*A - b) < 1e-14 |
| 1146 | True |
| 1147 | |
| 1148 | The vector of constants, ``b``, can be given in a |
| 1149 | variety of forms, so long as it coerces to a vector |
| 1150 | over the same base ring as the coefficient matrix. :: |
| 1151 | |
| 1152 | sage: A=matrix(CDF, 5, [1/(i+j+1) for i in range(5) for j in range(5)]) |
| 1153 | sage: A.solve_left([1]*5) |
| 1154 | (5.0..., -120.0..., 630.0..., -1120.0..., 630.0...) |
| 1155 | |
977 | | sage: A = matrix(RDF, 3, 0, []) |
978 | | sage: A.solve_left(vector(RDF,3, [1,2,3])) |
979 | | (0.0, 0.0, 0.0) |
| 1163 | |
| 1164 | The coefficent matrix must be square. :: |
| 1165 | |
| 1166 | sage: A = matrix(RDF, 2, 3, range(6)) |
| 1167 | sage: b = vector(RDF, [1,2,3]) |
| 1168 | sage: A.solve_left(b) |
| 1169 | Traceback (most recent call last): |
| 1170 | ... |
| 1171 | ValueError: coefficient matrix of a system over RDF/CDF must be square, not 2 x 3 |
| 1172 | |
| 1173 | The coefficient matrix must be nonsingular. :: |
| 1174 | |
| 1175 | sage: A = matrix(RDF, 5, range(25)) |
| 1176 | sage: b = vector(RDF, [1,2,3,4,5]) |
| 1177 | sage: A.solve_left(b) |
| 1178 | Traceback (most recent call last): |
| 1179 | ... |
| 1180 | LinAlgError: singular matrix |
| 1181 | |
| 1182 | The vector of constants needs the correct degree. :: |
| 1183 | |
| 1184 | sage: A = matrix(RDF, 5, range(25)) |
| 1185 | sage: b = vector(RDF, [1,2,3,4]) |
| 1186 | sage: A.solve_left(b) |
| 1187 | Traceback (most recent call last): |
| 1188 | ... |
| 1189 | TypeError: vector of constants over Real Double Field incompatible with matrix over Real Double Field |
| 1190 | |
| 1191 | The vector of constants needs to be compatible with |
| 1192 | the base ring of the coefficient matrix. :: |
| 1193 | |
| 1194 | sage: F.<a> = FiniteField(27) |
| 1195 | sage: b = vector(F, [a,a,a,a,a]) |
| 1196 | sage: A.solve_left(b) |
| 1197 | Traceback (most recent call last): |
| 1198 | ... |
| 1199 | TypeError: vector of constants over Finite Field in a of size 3^3 incompatible with matrix over Real Double Field |
| 1200 | |
| 1201 | With a coefficient matrix over ``RDF``, a vector of constants |
| 1202 | over ``CDF`` can be accomodated by converting the base ring |
| 1203 | of the coefficient matrix. :: |
| 1204 | |
| 1205 | sage: A = matrix(RDF, 2, range(4)) |
| 1206 | sage: b = vector(CDF, [1+I,2]) |
| 1207 | sage: A.solve_left(b) |
| 1208 | Traceback (most recent call last): |
| 1209 | ... |
| 1210 | TypeError: vector of constants over Complex Double Field incompatible with matrix over Real Double Field |
| 1211 | |
| 1212 | sage: B = A.change_ring(CDF) |
| 1213 | sage: B.solve_left(b) |
| 1214 | (0.5 - 1.5*I, 0.5 + 0.5*I) |