def _compute_echelon(self): A = Matrix(self.solution_parent(), self.A.rows()) # we create a copy U = identity_matrix(self.solution_parent(), A.nrows()) ## Step 1: initialize r = 0; c = 0 # we are looking from (r,c) while(r < A.nrows() and c < A.ncols()): ir = self.__find_pivot(A, r,c) if(ir != None): # we found a pivot if(ir != r): # swapping rows A.swap_rows(r, ir); U.swap_rows(r,ir) # We reduce the next rows for m in range(r+1, A.nrows()): if(A[m][c] != 0): g, t, s = self.__xgcd(A[r][c], A[m][c]) p,_ = self.__euclidean(A[r][c],g); q,_ = self.__euclidean(A[m][c],g) Ar = A.row(r); Am = A.row(m) Ur = U.row(r); Um = U.row(m) A.set_row(r,t*Ar + s*Am); U.set_row(r,t*Ur + s*Um) A.set_row(m,p*Am - q*Ar); U.set_row(m,p*Um - q*Ur) # We reduce previous rows with the new gcd for m in range(r): if(A[m][c] != 0): q,_ = self.__euclidean(A[m][c], A[r][c]) Ar = A.row(r); Am = A.row(m) Ur = U.row(r); Um = U.row(m) A.set_row(m, Am - q*Ar); U.set_row(m, Um-q*Ur) r += 1 c+= 1 return A, U
def _compute_echelon(self): A = Matrix(self.parent(), self.A.rows()) # we create a copy of the matrix U = identity_matrix(self.parent(), A.nrows()) if (self.have_ideal): # we do simplifications A = self.simplify(A) ## Step 1: initialize r = 0 c = 0 # we look from the position (r,c) while (r < A.nrows() and c < A.ncols()): ir = self.__find_pivot(A, r, c) A = self.simplify(A) U = self.simplify(U) # we simplify in case relations pop up if (ir != None): # we found a pivot # We do the swapping (if needed) if (ir != r): A.swap_rows(r, ir) U.swap_rows(r, ir) # We do the bareiss step Arc = A[r][c] Arows = A.rows() Urows = U.rows() for i in range(r): # we create zeros on top of the pivot Aic = A[i][c] A.set_row(i, Arc * Arows[i] - Aic * Arows[r]) U.set_row(i, Arc * Urows[i] - Aic * Urows[r]) # We then leave the row r without change for i in range(r + 1, A.nrows()): # we create zeros below the pivot Aic = A[i][c] A.set_row(i, Aic * Arows[r] - Arc * Arows[i]) U.set_row(i, Aic * Urows[r] - Arc * Urows[i]) r += 1 c += 1 else: # no pivot then only advance in column c += 1 # We finish simplifying the gcds in each row gcds = [gcd(row) for row in A] T = diagonal_matrix([1 / el if el != 0 else 1 for el in gcds]) A = (T * A).change_ring(self.parent()) U = T * U return A, U