def find_idx_with_nonzero(self, coeficient_idx, start_idx=0): """Find the first equation index where coeficient "coeficient_idx" is not zero. Args: coeficient_idx(int): The index of the coefficient to check. start_idx(int): Start the search in this row of the system. Returns: bool: Returns False if there is not an equation in this system with coefficient "coeficient_idx" different than zero. int: Returns the index of the equation with the first non-zero coefficient in variable "coeficient_idx". Default value is zero. Raises: IndexError: If start_idx is out of the bounds of self.planes array. """ for i in range(start_idx, len(self.planes)): row_var_value = self.planes[i].normal_vector[coeficient_idx] row_var_value = MyDecimal(row_var_value) if(not row_var_value.is_near_zero()): return i return False
def compute_triangular_form(self): """This function will return a different copy of this system in triangular form. Returns: LinearSystem: A new system equals to this one in triangular form. """ system = deepcopy(self) n = system.dimension j= 0 for i,_ in enumerate(system.planes): while j < n: c = MyDecimal(system.planes[i].normal_vector[j]) if c.is_near_zero(): row_with_nonzero = system.find_idx_with_nonzero(j, i) if row_with_nonzero: system.swap_rows(i, row_with_nonzero) else: j += 1 continue; system.clear_var(i,j) j += 1 break; return system
def get_first_col_where_one_coefficient_is_zero_and_other_no(self,row,row2): for col in range(0,self.dimension): coefficient_row = 0 if MyDecimal(self.planes[row].normal_vector[col]).is_near_zero() else self.planes[row].normal_vector[col] coefficient_row2 = 0 if MyDecimal(self.planes[row].normal_vector[col]).is_near_zero() else self.planes[row2].normal_vector[col] one_is_zero_but_not_both = coefficient_row * coefficient_row2 == 0 and (coefficient_row + coefficient_row2 != 0) if(one_is_zero_but_not_both): return col return None
def var_count(self): """Returns a count of the number of variables present in the equation. Returns: int: Count of variables in this plane's equation. """ var_count = 0; for _, coefficient in enumerate(self.normal_vector): var_coefficient = MyDecimal(coefficient) if(not var_coefficient.is_near_zero()): var_count += 1 return var_count
def is_same_as(self, l2): """Check if self and l2 are the same. Args: l2(line.Line): We will check if self and this line are the same. Returns: bool: True if self and l2 are the same line. False otherwise. Raises: ValueError: If self and l2 normal vectors doesn't have the same dimensions. """ if (self.normal_vector.is_zero() and l2.normal_vector.is_zero()): diff = self.constant_term - l2.constant_term return MyDecimal(diff).is_near_zero() atLeastOneZero = self.normal_vector.is_zero( ) or l2.normal_vector.is_zero() if (atLeastOneZero): return False areParallel = self.is_parallel_to(l2) if (not areParallel): return False vectorBetweenLines = self.basepoint - l2.basepoint return vectorBetweenLines.is_orthogonal_to( self.normal_vector) and vectorBetweenLines.is_orthogonal_to( l2.normal_vector)
def is_same_as(self,p2): """Check if self and p2 are the same plane. Args: p2(plane.Plane): The plane to check against. Returns: bool: True if self and p2 are the same plane, false otherwise. Raises: ValueError: If self and p2 normal vectors doesn't have the same dimensions. """ if(self.normal_vector.is_zero() and p2.normal_vector.is_zero()): diff = self.constant_term - p2.constant_term return MyDecimal(diff).is_near_zero() atLeastOneZero = self.normal_vector.is_zero() or p2.normal_vector.is_zero() if(atLeastOneZero): return False areParallel = self.is_parallel_to(p2) if(not areParallel): return False vectorBetweenLines = self.basepoint - p2.basepoint return vectorBetweenLines.is_orthogonal_to(self.normal_vector) and vectorBetweenLines.is_orthogonal_to(p2.normal_vector)
def solve(self): """Returns the solution of this system of equation. Returns: vector.Vector: If there is an unique solution, will return a vector representing the x,y,z points of the solution. bool: False if there is no solution and True if there are many solutions. """ rref = self.compute_rref() unique_solution = ['0','0','0'] first_nonzeros = rref.indices_of_first_nonzero_terms_in_each_row() response = None one_variable_alone = False single_solution = True for i,plane in enumerate(rref.planes): pivot_var_idx = first_nonzeros[i] constant_term = MyDecimal(plane.constant_term) if(pivot_var_idx < 0 and not constant_term.is_near_zero() ): return False number_of_vars = rref[i].var_count() if(number_of_vars == 1): one_variable_alone = True unique_solution[pivot_var_idx] = plane.constant_term/plane.normal_vector[pivot_var_idx] elif(number_of_vars > 1): single_solution = False if(one_variable_alone and not single_solution): response = False elif(not one_variable_alone and not single_solution): response = True else: response = unique_solution return response
def first_nonzero_index(iterable): """Returns the index of the first non-zero value for the iterable. Returns: int: The index first nonzero value of the iterable. Raises: Exception: If all values in the iterable are zero. """ for k, item in enumerate(iterable): if not MyDecimal(item).is_near_zero(): return k raise Exception(Line.NO_NONZERO_ELTS_FOUND_MSG)
def first_nonzero_index(iterable): """Returns the index of the first non-zero value in iterable. Args: iterable(iterable): The iterable to search in. Returns: int: The index of the first non-zero value of iterable. Raises: Exception: If all items are zero. """ for k, item in enumerate(iterable): if not MyDecimal(item).is_near_zero(): return k raise Exception(Plane.NO_NONZERO_ELTS_FOUND_MSG)