def do_gaussian_elimination_and_extract_solution(self): # 计算方程组的最简化的梯阵形式,然后看看是否有矛盾的等式 rref = self.compute_rref() # 0=k的形式,或者太多主变量,如果有则抛出异常 rref.raise_exception_if_contradictory_equation() rref.raise_exception_if_too_few_pivots() # 如果未有异常,则返回一个向量,向量坐标是方程的常量项 num_variables = rref.dimension solution_coordinates = [ rref.planes[i].constant_term for i in xrange(num_variables) ] return Vector(solution_coordinates)
def __init__(self, normal_vector=None, constant_term=None): self.dimension = 3 if not normal_vector: all_zeros = ['0'] * self.dimension normal_vector = Vector(all_zeros) self.normal_vector = normal_vector if not constant_term: constant_term = Decimal('0') self.constant_term = Decimal(constant_term) self.set_basepoint()
def extract_basepoint_for_parametrization(self): num_variables = self.dimension pivot_indices = self.indices_of_first_nonzero_terms_in_each_row() basepoint_coords = [0] * num_variables for i, p in enumerate(self.planes): pivot_var = pivot_indices[i] if pivot_var < 0: break basepoint_coords[pivot_var] = p.constant_term return Vector(basepoint_coords)
def __init__(self, normal_vector=None, constant_term=None): self.dimension = 2 # 直线等式的常量 if not normal_vector: all_zeros = ['0'] * self.dimension normal_vector = Vector(all_zeros) self.normal_vector = normal_vector # 直线法向量 if not constant_term: constant_term = Decimal('0') self.constant_term = Decimal(constant_term) # 在二维空间里,通过法向量,可以快速获得直线的方向向量,法向量更容易类推到多维空间 # 选择一个系数不为零的变量,并将另一个变量设为零,快速算出基准点 self.set_basepoint()
def set_basepoint(self): try: n = self.normal_vector c = self.constant_term basepoint_coords = ['0'] * self.dimension initial_index = Plane.first_nonzero_index(n) initial_coefficient = n[initial_index] basepoint_coords[initial_index] = c / initial_coefficient self.basepoint = Vector(basepoint_coords) except Exception as e: if str(e) == Plane.NO_NONZERO_ELTS_FOUND_MSG: self.basepoint = None else: raise e
def intersection_with(self, ell): try: A, B = self.normal_vector.coordinates C, D = ell.normal_vector.coordinates k1 = self.constant_term k2 = ell.constant_term x_numerator = D * k1 - B * k2 y_numerator = -C * k1 + A * k2 one_over_denom = Decimal('1') / (A * D - B * C) return Vector([x_numerator, y_numerator]).times_scalar(one_over_denom) except ZeroDivisionError: # 除数为零的错误 if self == ell: return self else: return None
def extract_direction_vectors_for_parametrization(self): # 通过不是主变量确定自由变量,然后对每个自由变量构建一个方向向量 num_variables = self.dimension pivot_indices = self.indices_of_first_nonzero_terms_in_each_row() free_variable_indices = set(range(num_variables)) - set(pivot_indices) direction_vectors = [] for free_var in free_variable_indices: vector_coords = [0] * num_variables # 自由变量对应的坐标为1,表示将该变量设为等于它自己 vector_coords[free_var] = 1 # 对方程组中的每个等式确定主变量 for i, p in enumerate(self.planes): pivot_var = pivot_indices[i] if pivot_var < 0: break # 找到等式中自由变量的系数,然后将主变量对应的坐标设为该系数的倒数 # 因为在参数形式化时,需要从等式两边消去自由变量 vector_coords[pivot_var] = -p.normal_vector[free_var] direction_vectors.append(Vector(vector_coords)) return direction_vectors
# -*- coding: utf-8 -*- from line import Line from my_vector import Vector ell1 = Line(normal_vector=Vector(['4.046', '2.836']), constant_term='1.21') ell2 = Line(normal_vector=Vector(['10.115', '7.09']), constant_term='3.025') # print 'intersection 1:', ell1.intersection_with(ell2) print('intersection 1:', ell1.intersection_with(ell2)) ell3 = Line(normal_vector=Vector(['7.204', '3.182']), constant_term='8.68') ell4 = Line(normal_vector=Vector(['8.172', '4.114']), constant_term='9.883') # print 'intersection 2:', ell3.intersection_with(ell4) print('intersection 2:', ell3.intersection_with(ell4)) ell5 = Line(normal_vector=Vector(['1.182', '5.562']), constant_term='6.744') ell6 = Line(normal_vector=Vector(['1.773', '8.343']), constant_term='9.525') # print 'intersection 3:', ell5.intersection_with(ell6) print('intersection 3:', ell5.intersection_with(ell6))
# -*- coding: utf-8 -*- from my_vector import Vector from plane import Plane from linsys import LinearSystem from decimal import Decimal p0 = Plane(normal_vector=Vector(['1', '1', '1']), constant_term='1') p1 = Plane(normal_vector=Vector(['0', '1', '0']), constant_term='2') p2 = Plane(normal_vector=Vector(['1', '1', '-1']), constant_term='3') p3 = Plane(normal_vector=Vector(['1', '0', '-2']), constant_term='2') s = LinearSystem([p0, p1, p2, p3]) s.swap_rows(0, 1) if not (s[0] == p1 and s[1] == p0 and s[2] == p2 and s[3] == p3): print 'test case 1 failed' s.swap_rows(1, 3) if not (s[0] == p1 and s[1] == p3 and s[2] == p2 and s[3] == p0): print 'test case 2 failed' s.swap_rows(3, 1) if not (s[0] == p1 and s[1] == p0 and s[2] == p2 and s[3] == p3): print 'test case 3 failed' s.multiply_coefficient_and_row(1, 0) if not (s[0] == p1 and s[1] == p0 and s[2] == p2 and s[3] == p3): print 'test case 4 failed' s.multiply_coefficient_and_row(-1, 2) if not (s[0] == p1 and s[1] == p0 and s[2] == Plane(normal_vector=Vector(['-1', '-1', '1']),
# -*- coding: utf-8 -*- from plane import Plane from my_vector import Vector p1 = Plane(normal_vector=Vector(['-0.412','3.806','0.728']), constant_term='-3.46') p2 = Plane(normal_vector=Vector(['1.03','-9.515','-1.82']), constant_term='8.65') print 'first pair of planes are parallel?: {}'.format(p1.is_parallel_to(p2)) print 'first pair of planes are equal?: {}'.format(p1 == p2) p3 = Plane(normal_vector=Vector(['2.611','5.528','0.283']), constant_term='4.6') p4 = Plane(normal_vector=Vector(['7.715','8.306','5.342']), constant_term='3.76') print 'second pair of planes are parallel?: {}'.format(p3.is_parallel_to(p4)) print 'second pair of planes are equal?: {}'.format(p3 == p4) p5 = Plane(normal_vector=Vector(['-7.926','8.625','-7.212']), constant_term='-7.95') p6 = Plane(normal_vector=Vector(['-2.642','2.875','-2.404']), constant_term='-2.44') print 'third pair of planes are parallel?: {}'.format(p5.is_parallel_to(p6)) print 'third pair of planes are equal?: {}'.format(p5 == p6)
# -*- coding: utf-8 -*- from my_vector import Vector v1 = Vector([8.218, -9.341]) w1 = Vector([-1.129, 2.111]) print(v1.plus(w1)) v2 = Vector([7.119, 8.215]) w2 = Vector([-8.223, 0.878]) print(v2.minus(w2)) v3 = Vector([1.671, -1.012, -0.318]) c = 7.41 print(v3.times_scalar(c)) v4 = Vector([-0.221, 7.437]) print(v4.magnitude()) v5 = Vector([8.813, -1.331, -6.247]) print(v5.magnitude()) v6 = Vector([5.581, -2.136]) print(v6.normalized()) v7 = Vector([1.996, 3.108, -4.554]) print(v7.normalized()) v8 = Vector([7.887, 4.138]) w8 = Vector([-8.802, 6.776]) print(v8.dot(w8))
self.direction_vectors = direction_vectors self.dimension = self.basepoint.dimension try: for v in direction_vectors: assert v.dimension == self.dimension except AssertionError: raise Exception(BASEPT_AND_DIR_VECTORS_MUST_BE_IN_SAME_DIM_MSG) class MyDecimal(Decimal): def is_near_zero(self, eps=1e-10): return abs(self) < eps p0 = Plane(normal_vector=Vector(['1', '1', '1']), constant_term='1') p1 = Plane(normal_vector=Vector(['0', '1', '0']), constant_term='2') p2 = Plane(normal_vector=Vector(['1', '1', '-1']), constant_term='3') p3 = Plane(normal_vector=Vector(['1', '0', '-2']), constant_term='2') s = LinearSystem([p0, p1, p2, p3]) print s.indices_of_first_nonzero_terms_in_each_row() print '{},{},{},{}'.format(s[0], s[1], s[2], s[3]) print len(s) print s s[0] = p1 print s print MyDecimal('1e-9').is_near_zero()
from my_vector import Vector if __name__ == "__main__": my_v = Vector([0.221, 7.437]) print(my_v.magnitude()) my_v = Vector([8.813, -1.331, -6.247]) print(my_v.magnitude()) #-------------------------- my_v = Vector([5.581, -2.136]) print(my_v.normalized()) my_v = Vector([1.996, 3.108, -4.554]) print(my_v.normalized())