def calc_linear_least_squares( points: list[Point]) -> Optional[ApproximationResult]: sx = sxx = sy = sxy = 0 number_of_points = len(points) for point in points: sx += point.x sxx += point.x**2 sy += point.y sxy += point.x * point.y determinant = sxx * number_of_points - sx * sx if determinant == 0: return None a = (sxy * number_of_points - sx * sy) / determinant b = (sxx * sy - sx * sxy) / determinant def func(x): return a * x + b func_text = '{:.3f} * x + {:.3f}'.format(a, b) measure = calc_deviation_measure(func, points) standard_deviation = calc_standard_deviation(func, points) return ApproximationResult(func, [a, b], points, measure, standard_deviation, func_text=func_text, description='Линейная аппроксимация')
def calc_logarithmic_least_squares( points: list[Point]) -> Optional[ApproximationResult]: sx = sxx = sy = sxy = 0 number_of_points = len(points) for point in points: if point.x <= 0 or point.y <= 0: return None sx += log(point.x) sxx += log(point.x)**2 sy += point.y sxy += log(point.x) * point.y determinant = sxx * number_of_points - sx * sx if determinant == 0: return None a = (sxy * number_of_points - sx * sy) / determinant b = (sxx * sy - sx * sxy) / determinant def func(x): return a * log(x) + b func_text = '{:.3f} * log(x) + {:.3f}'.format(a, b) measure = calc_deviation_measure(func, points) standard_deviation = calc_standard_deviation(func, points) return ApproximationResult(func, [a, b], points, measure, standard_deviation, func_text=func_text, description='Логарифмическая аппроксимация')
def calc_power_least_squares( points: list[Point]) -> Optional[ApproximationResult]: sx = sxx = sy = sxy = 0 number_of_points = len(points) # X = ln(x) # Y = ln(y) for point in points: if point.x <= 0: return None sx += log(point.x) sxx += log(point.x)**2 sy += log(point.y) sxy += log(point.x) * log(point.y) determinant = sxx * number_of_points - sx * sx if determinant == 0: return None b = (sxy * number_of_points - sx * sy) / determinant a = (sxx * sy - sx * sxy) / determinant a1 = exp(a) # a = ln(a1) b1 = b def func(x): return a1 * x**b1 func_text = '{:.3f} * x^{:.3f}'.format(a1, b1) measure = calc_deviation_measure(func, points) standard_deviation = calc_standard_deviation(func, points) return ApproximationResult(func, [a1, b1], points, measure, standard_deviation, func_text=func_text, description='Степенная аппроксимация')
def calc_exponential_least_squares( points: list[Point]) -> Optional[ApproximationResult]: sx = sxx = sy = sxy = 0 number_of_points = len(points) for point in points: sx += point.x sxx += point.x**2 if point.y <= 0: return None sy += log(point.y) sxy += point.x * log(point.y) determinant = sxx * number_of_points - sx * sx if determinant == 0: return None b = (sxy * number_of_points - sx * sy) / determinant a = (sxx * sy - sx * sxy) / determinant a1 = exp(a) # a = ln(a1) b1 = b def func(x): return a1 * exp(b1 * x) func_text = '{:.3f} * e^({:.3f} * x)'.format(a1, b1) measure = calc_deviation_measure(func, points) standard_deviation = calc_standard_deviation(func, points) return ApproximationResult(func, [a1, b1], points, measure, standard_deviation, func_text=func_text, description='Экспоненциальная аппроксимация')
def calc_quadratic_least_squares( points: list[Point]) -> Optional[ApproximationResult]: sx = sy = sx2 = sx3 = sx4 = sxy = sx2y = 0 number_of_points = len(points) for x, y in points: sx += x sx2 += x**2 sx3 += x**3 sx4 += x**4 sy += y sxy += x * y sx2y += x**2 * y matrix = [[number_of_points, sx, sx2, sy], [sx, sx2, sx3, sxy], [sx2, sx3, sx4, sx2y]] decision_count, decisions, _ = solve_sle(matrix) if decision_count != Decision.SINGLE: return None a0, a1, a2 = decisions def func(arg): return a0 + a1 * arg + a2 * arg**2 func_text = '{:3f} + {:.3f} * x + {:.3f} * x^2'.format(a0, a1, a2) measure = calc_deviation_measure(func, points) standard_deviation = calc_standard_deviation(func, points) return ApproximationResult(func, [a0, a1, a2], points, measure, standard_deviation, func_text=func_text, description='Квадратичная аппроксимация')