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 = 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 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 __init__(self, dimension=None, normal_vector=None, constant_term=None): if not dimension and not normal_vector: raise Exception(self.EITHER_DIM_OR_NORMAL_VEC_MUST_BE_PROVIDED_MSG) elif not normal_vector: self.dimension = dimension all_zeros = ["0"] * self.dimension normal_vector = Vector(all_zeros) else: self.dimension = normal_vector.dimension self.normal_vector = normal_vector if not constant_term: constant_term = Decimal("0") self.constant_term = Decimal(constant_term) self.set_basepoint()
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 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
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
output += ' = {}'.format(constant) return output @staticmethod def first_nonzero_index(iterable): for k, item in enumerate(iterable): if not MyDecimal(item).is_near_zero(): return k raise Exception(Plane.NO_NONZERO_ELTS_FOUND_MSG) class MyDecimal(Decimal): def is_near_zero(self, eps=1e-10): return abs(self) < eps if __name__ == "__main__": plane1 = Plane(Vector(["-0.412", "3.806", "0.728"]), "-3.46") plane2 = Plane(Vector(["1.03", "-9.515", "-1.82"]), "8.65") print(plane1.is_parallel_to(plane2)) print(plane1 == plane2) plane1 = Plane(Vector(["2.611", "5.528", "0.283"]), "4.6") plane2 = Plane(Vector(["7.715", "8.306", "5.342"]), "3.76") print(plane1.is_parallel_to(plane2)) print(plane1 == plane2) plane1 = Plane(Vector(["-7.926", "8.625", "-7.212"]), "-7.952") plane2 = Plane(Vector(["-2.642", "2.875", "-2.404"]), "2.443") print(plane1.is_parallel_to(plane2)) print(plane1 == plane2)
constant = round(self.constant_term, num_decimal_places) if constant % 1 == 0: constant = int(constant) output += ' = {}'.format(constant) return output @staticmethod def first_nonzero_index(iterable): for k, item in enumerate(iterable): if not MyDecimal(item).is_near_zero(): return k raise Exception(Line.NO_NONZERO_ELTS_FOUND_MSG) class MyDecimal(Decimal): def is_near_zero(self, eps=1e-10): return abs(self) < eps if __name__ == "__main__": line1 = Line(Vector(["4.046", "2.836"]), "1.21") line2 = Line(Vector(["10.115", "7.09"]), "3.025") print(line1.intersection_with(line2)) line1 = Line(Vector(["7.204", "3.182"]), "8.68") line2 = Line(Vector(["8.172", "4.114"]), "9.883") print(line1.intersection_with(line2)) line1 = Line(Vector(["1.182", "5.562"]), "6.744") line2 = Line(Vector(["1.773", "8.343"]), "9.525") print(line1.intersection_with(line2))
temp = [] for i in range(self.dimension): s = "x{} = ".format(i + 1) s += str(round(self.basepoint[i], num_decimal_places)) for j, direction in enumerate(self.direction_vectors): c = round(direction[i], num_decimal_places) if c == 0: continue s += " + {}t{}".format(c, j + 1) temp.append(s) ret = "\n".join(temp) return ret if __name__ == "__main__": p1 = Hyperplane(normal_vector=Vector(['0.786', '0.786']), constant_term='-0.714') p2 = Hyperplane(normal_vector=Vector(['-0.138', '-0.138']), constant_term='0.319') print(p1.is_parallel_to(p2)) s = LinearSystem([p1, p2]) r = s.compute_solution() print(r) p1 = Hyperplane(normal_vector=Vector(['8.631', '5.112', '-1.816']), constant_term='-5.113') p2 = Hyperplane(normal_vector=Vector(['4.315', '11.132', '-5.27']), constant_term='-6.775') p3 = Hyperplane(normal_vector=Vector(['-2.158', '3.01', '-1.727']), constant_term='-0.831') s = LinearSystem([p1, p2, p3])
@staticmethod def first_nonzero_index(iterable): for k, item in enumerate(iterable): if not MyDecimal(item).is_near_zero(): return k raise Exception(Hyperplane.NO_NONZERO_ELTS_FOUND_MSG) class MyDecimal(Decimal): def is_near_zero(self, eps=1e-10): return abs(self) < eps if __name__ == "__main__": plane1 = Hyperplane(normal_vector=Vector( ["-0.412", "3.806", "0.728", "5.23"]), constant_term="-3.46") plane2 = Hyperplane(normal_vector=Vector( ["1.03", "-9.515", "-1.82", "1.2"]), constant_term="8.65") print(plane1.is_parallel_to(plane2)) # plane1 = Hyperplane(Vector(["2.611", "5.528", "0.283"]), "4.6") # plane2 = Hyperplane(Vector(["7.715", "8.306", "5.342"]), "3.76") # print(plane1.is_parallel_to(plane2)) # print(plane1 == plane2) # plane1 = Hyperplane(Vector(["-7.926", "8.625", "-7.212"]), "-7.952") # plane2 = Hyperplane(Vector(["-2.642", "2.875", "-2.404"]), "2.443") # print(plane1.is_parallel_to(plane2)) # print(plane1 == plane2)