示例#1
0
def main():
    # Матрица из задания
    matrix = Matrix([[-11, 7, -1, 6], [-11, -9, 2, -7], [9, -3, 1, -2],
                     [-5, 4, -1, -11]])
    # Столбец свободных членов
    free_column = [74, 60, -54, -66]

    # ============================================================
    # ВНИМАНИЕ! Пугливым ниже не смотреть! Дальше программный код!
    # ATTENTION!  Not for timid people! Below is the program code!
    # ============================================================

    print("Введенная матрица:")
    matrix.console_display()

    print(f'Определитель данной матрицы равен {matrix.det}\n')

    print("Матрица, обратная данной:")
    (matrix**(-1)).console_display()

    print('\n' + " Решение методом Гаусса для данной СЛАУ: ".center(75, '='))
    decision = gauss(matrix.copy(), free_column, level_of_details=2)
    for step in decision:
        for info in step:
            if 'Матрица' in info:
                step[info].console_display()
            else:
                print(f"{info}: {step[info]}")
示例#2
0
def main():
    # Матрица из задания
    matrix = Matrix([[19, 5, 8], [5, -1, -6], [8, -6, -3]])

    # Количество итераций
    number_of_iterations = 21

    # ============================================================
    # ВНИМАНИЕ! Пугливым ниже не смотреть! Дальше программный код!
    # ATTENTION!  Not for timid people! Below is the program code!
    # ============================================================

    print("Введенная матрица:\n")
    matrix.console_display()

    print("Нахождение спектрального радиуса степенным методом:\n")
    decision = power_method(matrix,
                            level_of_detail=2,
                            iterations=number_of_iterations)
    for step in decision:
        step_info = ''
        for info in step:
            if info not in ['Матрица']:
                if isinstance(step[info], (tuple, list)):
                    step_info += f'{info}: {list(map(lambda x: round(x, 8), step[info]))}\n'
                elif isinstance(step[info], float):
                    step_info += f'{info}: {round(step[info], 8)}\n'
                else:
                    step_info += f'{info}: {step[info]}\n'
        print(step_info)
示例#3
0
def main():
    # Матрица из задания
    matrix = Matrix([[7, -1, 0, 0, 0], [5, -11, -4, 0, 0], [0, 2, -8, 4, 0],
                     [0, 0, -4, 7, -4], [0, 0, 0, 4, -8]])
    # Столбец свободных членов
    free_column = [10, 54, 42, 28, -16]

    # ============================================================
    # ВНИМАНИЕ! Пугливым ниже не смотреть! Дальше программный код!
    # ATTENTION!  Not for timid people! Below is the program code!
    # ============================================================

    print(f"Столбец свободных членов: {free_column}\n")

    print("Введенная матрица:\n")
    matrix.console_display()

    print("Решение методом прогонки:\n")
    solution = triple(matrix, free_column, level_of_detail=2)
    for step in solution:
        step_info = ''
        for info in step:
            if info not in ['Матрица']:
                if isinstance(step[info], (tuple, list)):
                    step_info += f'{info}: {list(map(lambda x: round(x, 8), step[info]))}\n'
                elif isinstance(step[info], float):
                    step_info += f'{info}: {round(step[info], 8)}\n'
                else:
                    step_info += f'{info}: {step[info]}\n'
        print(step_info)
示例#4
0
def main():
    # Матрица из задания
    matrix = Matrix([
        [38, -10, -1],
        [2, -36, 9],
        [6, -1, -37],
    ])
    # Столбец свободных членов
    free_column = [-293, -23, -303]

    print("Введенная матрица:")
    matrix.console_display()

    # ============================================================
    # ВНИМАНИЕ! Пугливым ниже не смотреть! Дальше программный код!
    # ATTENTION!  Not for timid people! Below is the program code!
    # ============================================================

    print(f"Столбец свободных членов: {free_column}\n")

    if not matrix.is_dominant:
        print("Матрица не сходится")
        input('Нажмите "Enter" чтобы выйти...')
        exit()
    else:
        print(f"\n{' Решение методом простых итераций '.center(50, '=')}\n")
        solution = simple(matrix,
                          free_column,
                          iterations=10,
                          level_of_detail=2)
        for step in solution:
            step_info = ''
            for info in step:
                if info not in ['Матрица']:
                    if info in ['Нормы матрицы', 'Нормы вектора', 'Решение']:
                        step_info += f'{info}: {list(map(lambda x: round(x, 8), step[info]))}\n'
                    else:
                        step_info += f'{info}: ' \
                                     f'{step[info] if not isinstance(step[info], float) else round(step[info], 8)}\n'
            print(step_info)

        print(f"\n{' Решение методом Зейделя '.center(50, '=')}\n")
        solution = zeidel(matrix, free_column, iterations=5, level_of_detail=2)
        for step in solution:
            step_info = ''
            for info in step:
                if info not in ['Матрица']:
                    if info in ['Нормы матрицы', 'Нормы вектора', 'Решение']:
                        step_info += f'{info}: {list(map(lambda x: round(x, 8), step[info]))}\n'
                    else:
                        step_info += f'{info}: ' \
                                     f'{step[info] if not isinstance(step[info], float) else round(step[info], 8)}\n'
            print(step_info)
def test_reverse_matrix():
    matrix = Matrix([
        [2, 3, 6],
        [3, 6, 2],
        [6, 2, 8],
    ])
    true_solution = Matrix([[-11 / 32, 3 / 32, 15 / 64],
                            [3 / 32, 5 / 32, -7 / 64],
                            [15 / 64, -7 / 64, -3 / 128]])

    solution = matrix**-1

    assert solution.map(lambda value: round(float(
        value), 8)) == true_solution.map(lambda value: round(float(value), 8))
def test_gauss():
    matrix = Matrix([[2, 5, 1], [-1, 2, -2], [6, 2, 1]])
    free = [1, 2, 3]
    true_solution = [12 / 9, 10 / 57, -65 / 57]

    solution = get_solution(gauss(matrix, free))

    assert list_round(solution) == list_round(true_solution)
def runge_refinement(results, steps, level_of_details=3):
    if len(results) != len(steps):
        raise IndexError('Количество результатов рассчетов должно совпадать с количеством значений шагов')

    if level_of_details < 3:
        yield {
            'Этап': 'Получены значения',
            'Результаты': results,
            'Величины шагов': steps
        }

    matrix_first = Matrix(len(results))
    matrix_second = Matrix(len(results))

    for row_no in matrix_first.r_rows:
        matrix_first[row_no][0] = results[row_no]
        matrix_second[row_no][0] = 1

    for row_no in matrix_first.r_rows:
        for col_no in range(1, matrix_first.columns):
            value = steps[row_no] ** (col_no + 1)
            matrix_first[row_no][col_no] = value
            matrix_second[row_no][col_no] = value

    if level_of_details < 3:
        yield {
            'Этап': 'Сформированы матрицы',
            'Первая матрица': matrix_first,
            'Вторая матрица': matrix_second
        }

    first_determinant = matrix_first.det
    second_determinant = matrix_second.det

    if level_of_details < 3:
        yield {
            'Этап': 'Рассчитаны определители',
            'Первый определитель': float(first_determinant),
            'Второй определитель': float(second_determinant)
        }

    if level_of_details < 4:
        yield {
            'Решение': first_determinant / second_determinant
        }
def test_triple_solve():
    matrix = Matrix([[-34, -26, 0, 0, 0], [64, -124, -56, 0, 0],
                     [0, 94, -274, -86, 0], [0, 0, 124, -484, -116],
                     [0, 0, 0, 154, -754]])
    free = [34, 38, 42, 46, 50]
    true_solution = [-.6181818, -.4993007, -.2794706, -.1437131, -.0956655]

    solution = get_solution(triple(matrix, free))

    assert list_round(solution, 7) == list_round(true_solution, 7)
def test_second_problem_power_method():
    matrix = Matrix([
        [-12, 4, 8],
        [4, 11, -6],
        [8, -6, 2],
    ])
    true_solution = -17

    solution = get_solution(second_problem.power_method(matrix))

    assert round(float(solution)) == true_solution
def test_second_problem_yakobi_rotation():
    matrix = Matrix([
        [17, 1, 1],
        [1, 17, 2],
        [1, 2, 4],
    ])
    true_solution = [16.0349, 18.31907, 3.646025]

    solution = get_solution(
        second_problem.yakobi_rotation(matrix))['Собственные числа']

    assert list_round(solution, 4) == list_round(true_solution, 4)
def test_first_problem_iteration_simple():
    matrix = Matrix([
        [20, 4, -8],
        [-3, 15, 5],
        [6, 3, -18],
    ])
    free = [1, -2, 3]
    true_solution = [-.0077608, -.0743338, -.1816226]

    solution = get_solution(
        first_problem_iteration.simple(matrix, free, iterations=7))

    assert list_round(solution, 7) == list_round(true_solution, 7)
def test_first_problem_iteration_zeidel():
    matrix = Matrix([
        [20, 4, -8],
        [-3, 15, 5],
        [6, 3, -18],
    ])
    free = [1, -2, 3]
    true_solution = [-.0077778, -.0743447, -.18165]

    solution = get_solution(
        first_problem_iteration.zeidel(matrix, free, iterations=5))

    assert list_round(solution, 7) == list_round(true_solution, 7)
示例#13
0
def main():
    # Матрица из задания
    matrix = Matrix([
                     [-4, 4, -4],
                     [4, 2, -8],
                     [-4, -8, 15]
    ])

    # Количество итераций
    number_of_iterations = 8

    # ============================================================
    # ВНИМАНИЕ! Пугливым ниже не смотреть! Дальше программный код!
    # ATTENTION!  Not for timid people! Below is the program code!
    # ============================================================

    print("Введенная матрица:\n")
    matrix.console_display()

    print("Нахождение собственных чисел и векторов методом вращения Якоби:\n")
    decision = yakobi_rotation(matrix, level_of_detail=2, iterations=number_of_iterations)
    for step in decision:
        for info in step:
            if 'матрица' in info.lower():
                print(info, end=':\n\n')
                step[info].console_display()
            elif info == 'Решение':
                print('\n', ' Решение '.center(75, '='), '\n')
                solution = step['Решение']
                for own_num_no in range(len(solution['Собственные числа'])):
                    print(f'{own_num_no + 1} собственное число: {round(solution["Собственные числа"][own_num_no], 8)}')
                    print(f'{own_num_no + 1} собственный вектор: '
                          f'{[round(_, 8) for _ in solution["Собственные векторы"][own_num_no]]}\n')
            elif info == 'Угол поворота фи':
                print(f'\n{info}: {step[info]}\n')
            else:
                print(f' {info}: {step[info]} '.center(75, '='))
示例#14
0
def canonical_polynomial(x_list_of_values, y_list_of_values):
    if len(x_list_of_values) != len(y_list_of_values):
        raise IndexError(
            "Количество занчений X не совпадает с количеством значений Y")
    matrix = []
    for row_no in range(len(x_list_of_values)):
        row = []
        for i in range(len(x_list_of_values) - 1, 0, -1):
            row.append(x_list_of_values[row_no]**i)
        row.append(1)
        matrix.append(row)
    matrix = Matrix(matrix)
    # решение СЛАУ относительно сгененрированной матрицы и столбца свободных членов
    koefs = matrix.slau_solve(y_list_of_values)
    polynomial = 0
    for koef_no in range(len(koefs)):
        polynomial += koefs[::-1][koef_no] * x**koef_no
    return {
        'Матрица': matrix,
        'Столбец свободных членов': y_list_of_values,
        'Решение СЛАУ': koefs,
        'Полином': polynomial,
        'Функция python': lambdify(x, polynomial)
    }
示例#15
0
def linearization(system,
                  variables,
                  approximation,
                  accuracy_order=8,
                  level_of_details=3,
                  iterations=None):
    """
    Решение СНЛАУ методом линеаризации (Ньютона)

    Args:
        system (list): список строк СНЛАУ
        variables (list): используемые пременные
        approximation (tuple): начальное приближение
        accuracy_order (int): необходимая точность
        level_of_details (int): необходимый уровень детализации
        iterations (int): неоюходимое количество итераций

    Yields:
        dict: информация о текущем шаге решения
    """
    def get_subs(vars_, approx):
        out = {}
        approx = approx.vector_to_list
        for var_no in range(len(vars_)):
            out.update({vars_[var_no]: approx[var_no]})
        return out

    def stop_iteration():
        return all([
            delta < 10**(-accuracy_order), (iteration_counter >= iterations)
            if iterations is not None else True,
            system_calc.vector_norma_1 < 10**(-accuracy_order)
        ])

    system = parse_list(system)
    variables = parse_list(variables)
    if level_of_details < 3:
        yield {
            'Этап': 'Получены значения',
            'Система уравнений': Matrix(system).T,
            'Использованные переменные': variables,
            'Начальное приближение': approximation
        }
    approximation = Matrix(list(approximation)).T
    matrix_j_n = Matrix(len(system), len(variables))
    for row_no, col_no in matrix_j_n:
        matrix_j_n[row_no][col_no] = diff(system[row_no], variables[col_no])
    if level_of_details < 2:
        yield {"Этап": "Получена матрица Якоби", 'J_n': matrix_j_n}
    system = Matrix(system)
    matrix_j_n_rev = (matrix_j_n**(-1)).map(simplify)
    if level_of_details < 2:
        yield {
            "Этап": "Получена обратная матрица для матрицы Якоби",
            'J_n ** (-1)': matrix_j_n_rev
        }
    iteration_matrix = (matrix_j_n_rev * system).map(simplify)
    if level_of_details < 3:
        yield {
            "Этап": "Вычислена матрица для совершения итераций",
            'J_n ** (-1) * f(n)': iteration_matrix
        }
    evalfed_matrix = Matrix(iteration_matrix.rows, iteration_matrix.columns)
    iteration_counter = 0
    while True:
        system_calc = system.T
        functions = []
        for row_no in iteration_matrix.r_rows:
            evalfed_matrix[row_no][0] = iteration_matrix[row_no][0].evalf(
                subs=get_subs(variables, approximation))
            system_calc[row_no][0] = system_calc[row_no][0].evalf(
                subs=get_subs(variables, approximation))
            functions.append(system_calc[row_no][0])
        old_approx = approximation
        if level_of_details < 3:
            yield {
                "Номер итерации": iteration_counter,
                'Решение': get_subs(variables, approximation),
                '||F||_1': system_calc.vector_norma_1,
                'F_1': functions[0],
                'F_2': functions[1]
            }
        approximation -= evalfed_matrix
        delta = (old_approx - approximation).vector_norma_1
        if stop_iteration():
            if level_of_details < 4:
                yield {'Решение': get_subs(variables, approximation)}
            break
        iteration_counter += 1
def zeidel_method(system, variables, approximation, transformed_system=None,
                  accuracy_order=8, level_of_details=3, iterations=None):
    raise Exception("Этот метод временно недоступен")
    # TODO: узнать откуда комплексные числа
    def transform(solutions):
        solutions = list(map(simplify, solutions))
        min_sol = solutions[0]
        min_len = len(str(min_sol))
        for solution in solutions:
            if len(str(solution)) < min_len:
                min_sol = solution
                min_len = len(str(min_sol))
        return min_sol

    def calc_delta(old_subs, nw_subs):
        return sum(((elem1 - elem2) ** 2 for elem1, elem2 in zip(old_subs.values(), nw_subs.values()))) ** .5

    def stop_iteration():
        return all([
            delta < 10 ** (-accuracy_order),
            (iteration_counter >= iterations) if iterations is not None else True
        ])

    system = parse_list(system)
    variables = parse_list(variables)
    if transformed_system is None:
        transformed_system = {}
        for var_no in reversed(range(len(variables))):
            transformed_system.update({variables[::-1][var_no]: transform(solve(system[var_no],
                                                                                variables[::-1][var_no]))})
    else:
        new_transformed = {}
        for key in transformed_system:
            new_transformed.update({parse_expr(key): simplify(parse_expr(transformed_system[key]))})
        transformed_system = new_transformed.copy()
    if level_of_details < 3:
        yield {
            'Этап': 'Получены значения',
            'Система': Matrix(system).T,
            'Начальное приближение': approximation,
            'Преобразованная система': transformed_system,
        }
    for_subs = {}
    for var_no in range(len(variables)):
        for_subs.update({variables[var_no]: approximation[var_no]})
    old_subs = for_subs.copy()
    iteration_counter = 1
    while True:
        for key in transformed_system:
            for_subs.update({key: transformed_system[key].evalf(subs=for_subs)})
        delta = calc_delta(old_subs, for_subs)
        old_subs = for_subs.copy()
        if level_of_details < 3:
            answer = {
                'Номер итерации': iteration_counter,
                'd': delta
            }
            answer.update(for_subs)
            yield answer
        if stop_iteration():
            if level_of_details < 4:
                yield {'Решение': for_subs}
            break
        iteration_counter += 1
def minimal_sqr(table, level_of_details=3):
    """
    Аппроксимация методом наименьших квадратов (квадратичная)

    Args:
        table (list): таблица значений (список из двух списков - x и y)
        level_of_details (int): необходимый уровень детализации

    Yields:
        dict: информация о текущем шаге решения
    """
    def sum_xny(target_list, _power, second_list=None):
        if second_list is None:
            return sum((elem**_power for elem in target_list))
        else:
            return sum((elem**_power * elem2
                        for elem, elem2 in zip(target_list, second_list)))

    def check_len(target_matrix):
        pr_len = len(target_matrix[0])
        for line in target_matrix:
            if pr_len != len(line):
                return False
        return True

    def function(x_):
        return polynomial.evalf(subs={x: x_})

    if not check_len(table):
        raise IndexError("Количество элементов в строках не совпадает")

    s = 3
    system = []
    for j in range(s):
        new_row = []
        for koef_power in range(s):
            power = s - j - koef_power + 1
            if power > 0:
                new_row.append(sum_xny(table[0], power))
            else:
                new_row.append(len(table[0]))
        system.append(new_row)
    free_column = []
    for koef_power in reversed(range(len(system))):
        free_column.append(sum_xny(table[0], koef_power, table[1]))
    if level_of_details < 3:
        yield {
            'Матрица': Matrix(system),
            'Столбец свободных членов': free_column
        }
    koefs = Matrix(system).slau_solve(free_column)
    polynomial = 0
    for koef_power in range(len(koefs)):
        polynomial += x**koef_power * koefs[::-1][koef_power]
    sqr_nev = 0
    for i in range(len(table[0])):
        sqr_nev += (function(table[0][i]) - table[1][i])**2
    if level_of_details < 4:
        yield {'Многочлен': polynomial}
    if level_of_details < 3:
        yield {
            'Коэффициенты': koefs,
            'Функция python': function,
            'Квадратическая невязка': sqr_nev
        }