def LDL(A): if not isinstance(A, Dense): raise Exception("Matrix A must be dense") A = copy.deepcopy(A) L = Dense(A.rows, A.columns) D = Vector(A.rows) for i in range(A.rows): L.data[i][i] = 1 a = A.data[i][i] for j in range(i): a = a - D.data[j] * L.data[i][j] * L.data[i][j] D.data[i] = a if D.data[i] == 0: raise Exception("A is no LDL decomposition") for j in range(i + 1, A.rows): a = A.data[j][i] for k in range(j): a = a - D.data[k] * L.data[j][k] * L.data[i][k] L.data[j][i] = a / D.data[i] return [L, D]
def test_vector_setup(): from matrix import Vector v_1 = Vector(3) v_1[0] = 5 v_1[2] = -3 assert str(v_1) == '[5, 0, -3]' v_2 = Vector(3, value=[2, 1, 3]) assert v_2[0] == 2 and v_2[1] == 1 and v_2[2] == 3 with pytest.raises(Exception) as _: _ = Vector(4, value=[2, 1, 3])
def test_vector_add(): from matrix import Vector v_1 = Vector(3) v_1[0] = 5 v_1[2] = -3 v_bad = Vector(4, value=[2, 1, 3, 4]) with pytest.raises(Exception) as _: _ = Vector.add(v_1, v_bad) v_2 = Vector(3, value=[-5, 0, 3]) v_add = Vector.add(v_1, v_2) assert v_add[0] == 0 and v_add[1] == 0 and v_add[2] == 0
def test_vector_dot(): from matrix import Vector v_1 = Vector(3) v_1[0] = 5 v_1[2] = -3 v_bad = Vector(4, value=[2, 1, 3, 4]) with pytest.raises(Exception) as _: _ = Vector.dot(v_1, v_bad) v_2 = Vector(3, value=[-5, 0, 3]) v_dot = Vector.dot(v_1, v_2) assert v_dot == -34
def fromAdjacencyToEdge(A, rand): duplicates = set() entries = [] w = [] for i in range(A.rows): for k in range(A.rowPtr[i], A.rowPtr[i + 1]): j = A.colInd[k] entry = (i, j) #BUG something breaks when [1] -> entry[1] if entry not in duplicates and entry[:: -1] not in duplicates and entry[ 0] != entry[1]: duplicates.add(entry) entries.append(sorted(entry)) if rand: w.append(random.random()) else: w.append(A.data[k]) entries = sorted(entries, key=itemgetter(0)) return [ _processEntries(len(entries), A.columns, entries), Vector(len(w), w) ]
def factorization(a: Matrix) -> (Matrix, Matrix): """Get Q and R from QR factorization""" size, size = a.size() q = Matrix.identity(size) r = a.copy() for i in range(size - 1): a_i = Vector(size) col = r.column(i) for j in range(i, r.num_columns()): a_i[j] = col[j] delta = a_i[i] / abs(a_i[i]) v_i = a_i + delta * a_i.norm() * canonical_base(size, i) h_v = householder(v_i) q = q * h_v r = h_v * r return q, r
def constructComponent(A, components=[]): if len(components) == 0: components = [l1Solver(A)] b = Vector(A.columns) xInit = Vector(A.columns) x = Vector.fromRandomn(A.columns) compositor = composite(A, xInit, components) for i in range(10): x = x + compositor(b) w = x.scale(1 / x.norm()) component = _formComponent(A, w) return component, w
def delta_x(x): mat = Matrix.from_list(jacobi(x)) B = Vector.from_list([-f1(x), -f2(x)]) LU, P = lu.LU_decomposition(mat) new_B = lu.get_new_B(B, P) delta = lu.LU_solve(LU, new_B) return delta.get_data()
def l1Smoother(A): if not isinstance(A, Sparse): raise Exception("Matrix A must be sparse") if A.rows != A.columns: raise Exception("Matrix A must be square and SPD") b = Vector(A.rows) for i in range(A.rows): sum = 0 for k in range(A.rowPtr[i], A.rowPtr[i + 1]): sum += abs(A.data[k]) b.data[i] = sum return b
def diagonal(A): if not isinstance(A, Sparse): raise Exception("Matrix A must be sparse") if A.rows != A.columns: raise Exception("Matrix A must be square and SPD") D = Vector(A.rows) for i in range(A.rows): for k in range(A.rowPtr[i], A.rowPtr[i + 1]): j = A.colInd[k] if i == j: D.data[i] = A.data[k] return D
def tc_Series_Vector(source_object, item='data'): ''' Function to convert from dataframe.Series object to a matrix.Vector object. @param source_object: object to be type casted / converted. @type source_object: dataframe.Series object @param item: item type to be converted into a list. Allowable items are 'data' and 'label'. Default = data. @type item: string @return: matrix.Vector object. ''' if item == 'data': return Vector(source_object.data) if item == 'label': return Vector(source_object.label)
def gradient(self): t = [] for i in range(self.weights.size[0]): t += [ self.weights[i] - (self.learning_rate * 1 / self.m * self.gradient_error(i)) ] self.weights = Vector(t)
def __init__(self, x, y, cost=1, learning_rate=0.2): self.x = Matrix([[1, *sample] for sample in x.raw]) self.y = y self.m = self.x.size[0] self.n = self.x.size[1] self.weights = Vector.gen(self.n, fill=0) self.learning_rate = learning_rate self.stop_cost = cost
def LU_solve(LU, B): sz = len(LU) z = Vector(sz) x = Vector(sz) z[0] = B[0] for i in range(1, sz): s = sum([LU[i][j] * z[j] for j in range(i)]) z[i] = B[i] - s x[-1] = z[-1] / LU[-1][-1] for i in reversed(range(sz - 1)): s = sum([LU[i][j] * x[j] for j in range(i + 1, sz)]) x[i] = (z[i] - s) / LU[i][i] return x
def iterative_method(alpha, beta, eps): x = Vector.copy(beta) norm_alpha = alpha.norm() while True: x_i = beta + alpha.multiply(x) if finish_iter_process(x_i, x, norm_alpha, norm_alpha, eps): break x = x_i return x_i
def _solveCoarse(A, r): converted = csr_matrix((A.data, A.colInd, A.rowPtr), (A.rows, A.columns)).asfptype() B = splu(converted.tocsc()) y = B.solve(np.array(r.data)) y = Vector(y.shape[0], list(y)) return y
def hw5(filename, O, maxIter, tolerance, preconditioner, M, display, displayResidual): with open(util.getMatrixFile(filename)) as file: A = Sparse.fromFile(file, O) if preconditioner.lower() == "d": method = "Diagonal" preconditioner = diagonalPreconditioner(A) elif preconditioner.lower() == "sgs": method = "Symmetric Gauss Seidel" preconditioner = sgsPreconditioner(A) elif preconditioner.lower() == "2l": method = "Symmetric Two Level" if M == "l1": M = l1Solver(A) method += " (L1 Smoother)" elif M == "fgs": M = fgsSolver(A) method += " (Forward Gauss Seidel)" preconditioner = twolevelPreconditioner(A, M) else: raise Exception("No valid preconditioner selected") # Generate random solution vector x = Vector.fromRandom(A.columns, 0, 5) b = A.multVec(x) # Generate first iteration xInit = Vector(A.columns) start = time.time() xResult, iterations, residual = pcg(A, b, xInit, maxIter, tolerance, preconditioner, displayResidual) end = time.time() convergence = "(Convergence)" if maxIter != iterations else "" if display: util.compareVectors(x, xResult) print(f"\nPreconditioner = {method}") print(f"Iterations = {iterations} {convergence}") print(f"Residual = {residual}") print(f"Time to solve was {end - start}\n")
def getVertexAggregate(X, clusters): data = [] colInd = [] rowPtr = [0] nnz = 0 X = [Vector(len(x), list(x)) for x in X] for i in range(len(clusters)): clusters[i] = [Vector(len(c), list(c)) for c in clusters[i]] for x in X: aggregate = _findAggregate(x, clusters) data.append(1) colInd.append(aggregate) nnz += 1 rowPtr.append(nnz) return Sparse(nnz, len(clusters), data, colInd, rowPtr)
def predict(self, sample, poly=False): if sample.size[1] == self.weights.size[0]: if poly == True: prediction = (Vector([f**i for i, f in enumerate(sample.raw)], transpose=True) * self.weights)[0][0] else: prediction = (sample * self.weights)[0][0] return prediction else: print('Wrong Sample', sample)
def hw2(fileName, O, maxIter, tolerance, iterMatrix, display, displayResidual): with open(util.getMatrixFile(fileName)) as file: A = Sparse.fromFile(file, O) # Generate random solution vector x = Vector.fromRandom(A.columns, 0, 5) b = A.multVec(x) # Generate first iteration xInit = Vector(A.columns) # Get proper iteration matrix if iterMatrix.lower() == "l1": method = "l1 Smoother" iterSolver = l1Solver(A) elif iterMatrix.lower() == "fgs": method = "Forward Gauss Seidel" iterSolver = fgsSolver(A) elif iterMatrix.lower() == "bgs": method = "Backward Gauss Seidel" iterSolver = bgsSolver(A) elif iterMatrix.lower() == "sgs": method = "Symmetric Gauss Seidel" iterSolver = sgsSolver(A) else: raise Exception("No valid iteration matrix selected") # Solve system using stationary iterative method start = time.time() xResult, iterations, residual, accuracy = stationaryIterative( A, b, xInit, maxIter, tolerance, iterSolver, displayResidual) end = time.time() convergence = "(Convergence)" if maxIter != iterations else "" if display: util.compareVectors(x, xResult) print(f"\nB Matrix = {method}") print(f"Iterations = {iterations} {convergence}") print(f"Residual = {residual}") print(f"Accuracy = {accuracy}") print(f"Time to solve was {end - start}\n")
def get_c(x, f, h): n = len(f) a = [0] + [h[i - 1] for i in range(3, n)] b = [2 * (h[i - 1] + h[i]) for i in range(2, n)] c = [h[i] for i in range(2, n - 1)] + [0] d = [ 3 * ((f[i] - f[i - 1]) / h[i] - ((f[i - 1] - f[i - 2]) / h[i - 1])) for i in range(2, n) ] x = tma(TridiagonalMatrix.from_lists(a, b, c), Vector.from_list(d)) res = [0, 0] + x.get_data() return res
def learn(self, iters=10000, s_cost=0.1, d_cost=0.01, polynomial=False): cost = [] for i in range(iters + 1): # calculating iteration predictions self.predictions = Vector( [self.predict(self.x[i], polynomial) for i in range(self.m)]) # applying gradient descent self.gradient() # calculating new cost cost += [self.error()] print("\rIteration : {}, Cost: {}".format(i, cost[len(cost) - 1]), end="") if cost[len(cost) - 1] < s_cost: break if len(cost) > 50 and (cost[len(cost) - 50] - cost[len(cost) - 1]) < d_cost: break print('\n') self.predictions = Vector( [self.predict(self.x[i], polynomial) for i in range(self.m)]) self.cost = Vector(cost)
def vectorSolver(a, b): if a.dim != b.dim: raise Exception(f"Dimension mismatch, {a.dim} != {b.dim}") data = [0] * a.dim for i in range(a.dim): if a.data[i] == 0 or b.data[i] == 0: data[i] = 0 else: data[i] = b.data[i] / a.data[i] return Vector(a.dim, data)
def finite_difference_method(f, p, q, a, b, alpha, beta, delta, gamma, y0, y1, h): n = int((b - a) / h) x = [i for i in np.arange(a, b + h, h)] A = [0] + [1 - p(x[i]) * h / 2 for i in range(0, n - 1)] + [-gamma] B = [alpha * h - beta] + [q(x[i]) * h**2 - 2 for i in range(0, n - 1)] + [delta * h + gamma] C = [beta] + [1 + p(x[i]) * h / 2 for i in range(0, n - 1)] + [0] D = [y0 * h] + [f(x[i]) * h**2 for i in range(0, n - 1)] + [y1 * h] y = tma(TridiagonalMatrix.from_lists(A, B, C), Vector.from_list(D)) return x, y.get_data()
def equivalent_form(A, B): sz = len(A) alpha = Matrix.zero(sz) beta = Vector(sz) # чтобы не делить на 0, добавим небольшую константу for i in range(sz): beta[i] = B[i] / (A[i][i] + 1e-3) for j in range(sz): if i != j: alpha[i][j] = -A[i][j] / (A[i][i] + 1e-3) return alpha, beta
def mls(n, x, y): N = len(x) mat = [[sum([x_j**(i + j) for x_j in x]) for i in range(n + 1)] for j in range(n + 1)] mat[0][0] = N + 1 b = [sum([x_j**i * y_j for x_j, y_j in zip(x, y)]) for i in range(n + 1)] mat = Matrix.from_list(mat) B = Vector.from_list(b) LU, P = lu.LU_decomposition(mat) new_B = lu.get_new_B(B, P) coefs = lu.LU_solve(LU, new_B) return coefs.get_data()
def seidel_method(alpha, beta, eps): sz = len(alpha) np_alpha = np.array(alpha.get_data()) np_beta = np.array(beta.get_data()) B = np.tril(np_alpha, -1) C = np_alpha - B tmp1 = inv(np.eye(sz, sz) - B) @ C tmp2 = inv(np.eye(sz, sz) - B) @ np_beta x = tmp2 while True: x_i = tmp2 + tmp1 @ x if finish_iter_process(x_i, x, norm(tmp1), norm(C), eps, zeidel=True): break x = x_i return Vector.from_list(x_i.tolist())
def normalize(self, data): if type(data).__name__ == 'Matrix': data_norm = [] for c in range(data.size[1]): column = data(c) min_ = min(column.raw) max_ = max(column.raw) data_norm += [[(data[l][c] - min_) / (max_ - min_) for l in range(data.size[0])]] return Matrix(data_norm).transpose() elif type(data).__name__ == 'Vector': min_ = min(data.raw) max_ = max(data.raw) return Vector([(data[l] - min_) / (max_ - min_) for l in range(data.size[0])])
def hw1(fileName, O, display): with open(util.getMatrixFile(fileName)) as file: A = Dense.fromFile(file, O) # Convert matrix to np array so I can use scipy factorization A = np.array(A.data) # Get LDLt factorization start = time.time() L, D, P = linalg.ldl(A) U = np.transpose(L) end = time.time() print(f"\nTime to factor input matrix was {end - start} seconds") # Convert to CSR format used in my library L = Sparse.fromDense(Dense(L.shape[0], L.shape[1], L.tolist())) U = Sparse.fromDense(Dense(U.shape[0], U.shape[1], U.tolist())) # Generate random solution vector x = Vector.fromRandom(L.columns, 0, 5) # Resulting b matrix times x vector bL = L.multVec(x) bU = U.multVec(x) # Solve lower triangular system start = time.time() r1 = forwardSparse(L, bL) end = time.time() print(f"Time to solve lower system was {end - start} seconds") # Solve upper triangular system start = time.time() r2 = backwardSparse(U, bU) end = time.time() print(f"Time to solve upper system was {end - start} seconds\n") if display: print("Solution to lower triangular") util.compareVectors(x, r1) print("\nSolution to upper triangular") util.compareVectors(x, r2)
def tma(mat, D): sz = len(mat) x = Vector(sz) p, q = [], [] p.append(-mat.c[0] / mat.b[0]) q.append(D[0] / mat.b[0]) for i in range(1, sz): p_i = 0 if i == sz - 1 else (-mat.c[i] / (mat.b[i] + mat.a[i] * p[i - 1])) q_i = (D[i] - mat.a[i] * q[i - 1]) / (mat.b[i] + mat.a[i] * p[i - 1]) p.append(p_i) q.append(q_i) x[sz - 1] = q[sz - 1] for i in range(sz - 2, -1, -1): x[i] = p[i] * x[i + 1] + q[i] return x