Merge pull request 'lab2' (#1) from lab2 into main
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
2
lab2/.flake8
Normal file
2
lab2/.flake8
Normal file
@@ -0,0 +1,2 @@
|
||||
[flake8]
|
||||
max-line-length = 110
|
||||
34
lab2/AbsoluteMeasurementErrors.py
Normal file
34
lab2/AbsoluteMeasurementErrors.py
Normal file
@@ -0,0 +1,34 @@
|
||||
def get_accuracy(x):
|
||||
x_str = str(x)
|
||||
acc = 0
|
||||
|
||||
if "." in x_str:
|
||||
acc = len(x_str) - x_str.find(".") - 1
|
||||
|
||||
return acc
|
||||
|
||||
|
||||
def get_error(x):
|
||||
acc = get_accuracy(x)
|
||||
return 1 / 10**acc / 2
|
||||
|
||||
|
||||
def sum_error(*values):
|
||||
return sum([get_error(value) for value in values])
|
||||
|
||||
|
||||
def product_error(*values):
|
||||
p = 1
|
||||
s = 0
|
||||
for value in values:
|
||||
p *= value
|
||||
s += get_error(value) / abs(value)
|
||||
return p * s
|
||||
|
||||
|
||||
def frac_error(a, b):
|
||||
return abs(a / b) * (get_error(a) / abs(a) + get_error(b) / abs(b))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
get_error(1)
|
||||
236
lab2/HookJeeves.py
Normal file
236
lab2/HookJeeves.py
Normal file
@@ -0,0 +1,236 @@
|
||||
# HookJeeves.py
|
||||
|
||||
import numpy as np
|
||||
import AbsoluteMeasurementErrors as abserror
|
||||
from itertools import product
|
||||
|
||||
result_log = ""
|
||||
|
||||
|
||||
def log(*values, sep=" ", end="\n"):
|
||||
global result_log
|
||||
result_log += sep.join(list(map(str, values))) + end
|
||||
# print(*values, sep=sep, end=end)
|
||||
|
||||
|
||||
def get_errors_vector(x):
|
||||
return np.array(list(map(abserror.get_error, x)))
|
||||
|
||||
|
||||
def sum_errors_vector(a, b):
|
||||
return np.array([abserror.sum_error(a[i], b[i]) for i in range(len(a))])
|
||||
|
||||
|
||||
def frac_errors_vector(a, b):
|
||||
return np.array([abserror.frac_error(a[i], b) for i in range(len(a))])
|
||||
|
||||
|
||||
def point_info(x, f, x_err):
|
||||
return f"x = {x}, x_err = {x_err}, f(x) = {f(x)}"
|
||||
|
||||
|
||||
def hooke_jeeves(
|
||||
f,
|
||||
x0,
|
||||
delta0,
|
||||
epsilon,
|
||||
alpha,
|
||||
r=lambda x: True,
|
||||
fit=lambda a, b: a < b,
|
||||
x_err=None,
|
||||
delta_err=None,
|
||||
):
|
||||
x = np.array(x0)
|
||||
delta = np.array(delta0)
|
||||
|
||||
if x_err is None:
|
||||
x_err = get_errors_vector(x)
|
||||
|
||||
if delta_err is None:
|
||||
delta_err = get_errors_vector(delta)
|
||||
|
||||
iteration = 0
|
||||
|
||||
while np.linalg.norm(delta) > epsilon:
|
||||
iteration += 1
|
||||
|
||||
log()
|
||||
log("=" * 40)
|
||||
log("Итерация", iteration)
|
||||
|
||||
log("Текущая базовая точка", point_info(x, f, x_err))
|
||||
|
||||
sample_x, sample_x_err = exploratory_search(
|
||||
f, x, delta, r=r, fit=fit, x_err=x_err, delta_err=delta_err
|
||||
)
|
||||
|
||||
if fit(f(sample_x), f(x)):
|
||||
log("Исследующий поиск УДАЧНЫЙ")
|
||||
|
||||
x_p, x_p_err = sample_search(
|
||||
f, x, sample_x, r=r, fit=fit, x1_err=x_err, x2_err=sample_x_err
|
||||
)
|
||||
|
||||
if fit(f(x_p), f(x)):
|
||||
log("Поиск по образцу УДАЧНЫЙ")
|
||||
x, x_err = x_p, x_p_err
|
||||
else:
|
||||
log("Поиск по образцу ПРОВАЛЕН")
|
||||
x, x_err = sample_x, sample_x_err
|
||||
|
||||
log()
|
||||
log("Новая базовая точка", point_info(x, f, x_err))
|
||||
|
||||
else:
|
||||
log("Исследующий поиск ПРОВАЛЕН")
|
||||
|
||||
log("Уменьшаем шаг", delta, "->", delta / alpha)
|
||||
delta = delta / alpha
|
||||
delta_err = frac_errors_vector(delta, alpha)
|
||||
log("ε =", np.linalg.norm(delta))
|
||||
|
||||
return x, f(x), x_err
|
||||
|
||||
|
||||
def exploratory_search(
|
||||
f, x, delta, r=lambda x: True, fit=lambda a, b: a < b, x_err=None, delta_err=None
|
||||
):
|
||||
log()
|
||||
log("Выполняем исследующий поиск")
|
||||
|
||||
if x_err is None:
|
||||
x_err = get_errors_vector(x)
|
||||
|
||||
if delta_err is None:
|
||||
delta_err = get_errors_vector(delta)
|
||||
|
||||
dxs = product(*[[d, -d] for d in delta])
|
||||
|
||||
x = np.array(x)
|
||||
t_x_err = None
|
||||
t_f = f(x)
|
||||
t_x = None
|
||||
|
||||
for dx in dxs:
|
||||
if fit(f(x + dx), t_f) and r(x + dx):
|
||||
t_f = f(x + dx)
|
||||
t_x = x + dx
|
||||
t_x_err = x_err + delta_err
|
||||
|
||||
if t_x is not None:
|
||||
log("Найдена точка", t_x, t_f)
|
||||
return t_x, t_x_err
|
||||
|
||||
return x, x_err
|
||||
|
||||
|
||||
def sample_search(
|
||||
f, x1, x2, r=lambda x: True, fit=lambda a, b: a < b, x1_err=None, x2_err=None
|
||||
):
|
||||
log()
|
||||
log("Выполняем поиск по образцу")
|
||||
|
||||
if x1_err is None:
|
||||
x1_err = get_errors_vector(x1)
|
||||
|
||||
if x2_err is None:
|
||||
x2_err = get_errors_vector(x2)
|
||||
|
||||
x2_last = x2.copy()
|
||||
x2_last_err = x2_err.copy()
|
||||
|
||||
error_growth_coeff = 0.05 # КОЭФФИЦИЕНТ РОСТА ОШИБКИ
|
||||
|
||||
while fit(f(x2), f(x1)):
|
||||
x2_last = x2.copy()
|
||||
x2_last_err = x2_err.copy()
|
||||
|
||||
step = x2 - x1
|
||||
if not r(x2 + step):
|
||||
log("Ограничение ОДЗ")
|
||||
break
|
||||
|
||||
x2, x1 = x2 + step, x2
|
||||
|
||||
# Новая погрешность
|
||||
step_error = error_growth_coeff * np.abs(step)
|
||||
x2_err = x2_err + step_error
|
||||
x1_err = x2_err.copy()
|
||||
|
||||
log("Найдена точка", x2_last, f(x2_last))
|
||||
return x2_last, x2_last_err
|
||||
|
||||
|
||||
class TARGET:
|
||||
MIN = 0
|
||||
MAX = 1
|
||||
|
||||
|
||||
def example():
|
||||
# начальная базовая точка
|
||||
x0 = [100, 100]
|
||||
|
||||
# начальное значение приращения
|
||||
delta0 = [10, 10]
|
||||
|
||||
# коэффициент приращения
|
||||
alpha = 2
|
||||
|
||||
# условие окончания поиска
|
||||
epsilon = 0.0001
|
||||
|
||||
# коэффициенты при неизвестных (внутри списков порядок обратный)
|
||||
c = [[1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1]]
|
||||
|
||||
x1r = [-10000, 10000]
|
||||
x2r = [-10000, 10000]
|
||||
|
||||
target = TARGET.MIN
|
||||
|
||||
def fit(a, b):
|
||||
"""
|
||||
Функция сравнения значений оптимизируемой функции
|
||||
> - ищем максимум
|
||||
< - ищем минимум
|
||||
"""
|
||||
if target == TARGET.MIN:
|
||||
return a < b
|
||||
elif target == TARGET.MAX:
|
||||
return a > b
|
||||
|
||||
def r(x):
|
||||
"""
|
||||
Функция, описывающая область допустимых значений.
|
||||
Должна возвращать истину, если точка находится в ОДЗ.
|
||||
"""
|
||||
return x1r[0] <= x[0] <= x1r[1] and x2r[0] <= x[1] <= x2r[1]
|
||||
|
||||
def f(x):
|
||||
"""
|
||||
Функция, которую мы должны оптимизировать
|
||||
"""
|
||||
return sum(
|
||||
[
|
||||
sum([c[i][j] * x[i] ** j for j in range(len(c[i]))])
|
||||
for i in range(len(c))
|
||||
]
|
||||
)
|
||||
|
||||
x, val, x_err = hooke_jeeves(f, x0, delta0, epsilon, alpha, r=r, fit=fit)
|
||||
|
||||
log()
|
||||
log("=" * 40)
|
||||
log("Точка экстремумв:", x)
|
||||
log("Абсолютная погрешность:", x_err)
|
||||
log("Максимальное значение функции:", val)
|
||||
|
||||
with open("result.log", "w", encoding="utf-8") as file:
|
||||
file.write(result_log)
|
||||
|
||||
|
||||
def main():
|
||||
example()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
94
lab2/README.md
Normal file
94
lab2/README.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Лабораторная работа по вычислительной математике "Нелинейное программирование"
|
||||
|
||||
## Запуск
|
||||
|
||||
Склонировать проект и перейти в директорию проекта
|
||||
|
||||
> Для запуска проекта используется менеджер пакетов [poetry](https://python-poetry.org/docs/#installation)
|
||||
|
||||
```shell
|
||||
git clone ... project
|
||||
cd project
|
||||
poetry install
|
||||
poetry run flask run
|
||||
```
|
||||
|
||||
После запуска перейти по ссылке <http://127.0.0.1:5000>
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
Пример файла `example.json` с исходными данными
|
||||
|
||||
```json
|
||||
{
|
||||
"x0": [
|
||||
100,
|
||||
100
|
||||
],
|
||||
"delta0": [
|
||||
10,
|
||||
10
|
||||
],
|
||||
"epsilon": 0.0001,
|
||||
"alpha": 2,
|
||||
"target": "min",
|
||||
"x1r": [
|
||||
-10000,
|
||||
10000
|
||||
],
|
||||
"x2r": [
|
||||
-10000,
|
||||
10000
|
||||
],
|
||||
"x1c": [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"x2c": [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Организация работы
|
||||
|
||||
1. Лабораторная работа выполняется индивидуально.
|
||||
2. Лабораторная работа состоит из двух частей, основная часть и дополнительные задания в зависимости от качества выполнения работы.
|
||||
3. Выбрать можно любой из предложенных вариантов, которые отличаются уровнем сложности и, как следствием, максимальным числом баллов, которое можно получить за выполнение.
|
||||
4. Оценивается результат выполнения, а не качество написанного кода. Допускается реализация на любом языке программирования или среде разработки позволяющей решить задачу (1С, Excel, MatLAB, Maple и тд). Например, можно использовать макросы в Excel, но нельзя использовать готовый плагин для решения задач.
|
||||
5. Допускается использование математических библиотек и пакетов реализующих вспомогательные функции, такие как операции с векторами и матрицами, вычисление градиента и Гессиана, основные математические функции. Использование готовых методов оптимизации не допускается.
|
||||
|
||||
## Общее задание
|
||||
|
||||
1. Необходимо составить программную реализацию одного из изученных методов оптимизации полиномиальной функции с оценкой абсолютной погрешности работы данного метода.
|
||||
2. Программа должна позволять ввести произвольные значения в заранее подготовленный файл, с клавиатуры или другим общепринятым способом. Генерация случайных данных не допускается.
|
||||
3. Количество ненулевых коэффициентов в проверочных примерах должно быть не менее 10.
|
||||
4. Результатом работы программы должны быть:
|
||||
- Значения неизвестных (массив X) для минимума и максимума функции на заданном отрезке.
|
||||
- Результаты подстановки неизвестных целевую функцию
|
||||
- Оценки абсолютных погрешностей для найденных значений
|
||||
- Поощряется вывод промежуточных вычислений и графиков функции.
|
||||
5. Полученные абсолютные погрешности вычислений должны быть допустимыми, то есть не превышать половины единицы измерения искомых величин (не превышать 5%).
|
||||
|
||||
## Пояснения по расчету погрешностей
|
||||
|
||||
1. Для расчета погрешностей необходимо использовать формулы из соответствующей лекции со слайдов 7 и 8. Так как все алгоритмы подразумевают только выполнения базовых математических операций, то формулы со слайда 9, вам скорее всего не пригодятся.
|
||||
2. Погрешности исходных данных считаются по умолчанию и равны половине последнего введенного знака. То есть для числа 48 абсолютная погрешность равна 0.5, а для числа 48.01 абсолютная погрешность равна 0.005. Отдельно вводить погрешности для входных данных не требуется. Таким образом для достижения требуемого результата значения на входе должны иметь достаточно малые абсолютные погрешности.
|
||||
3. Для косвенной само-проверки расчета погрешностей разумно подсчитывать общее количество операций сложения, вычитания, умножения и деления. Это позволит понять где идет наибольшее накопление погрешностей и исправить ошибку.
|
||||
|
||||
## Вариант задания
|
||||
|
||||

|
||||
114
lab2/app.py
Normal file
114
lab2/app.py
Normal file
@@ -0,0 +1,114 @@
|
||||
from flask import Flask, render_template, request
|
||||
import HookJeeves
|
||||
import os
|
||||
import json
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config["UPLOAD_FOLDER"] = "uploads/"
|
||||
os.makedirs(app.config["UPLOAD_FOLDER"], exist_ok=True)
|
||||
|
||||
|
||||
def parse_uploaded_data(file):
|
||||
data = json.load(file)
|
||||
return data
|
||||
|
||||
|
||||
def to_str(arr):
|
||||
return ",".join(list(map(str, arr)))
|
||||
|
||||
|
||||
def to_normal_numb(numb):
|
||||
str_numb = str(numb)
|
||||
index_point = str_numb.find(".")
|
||||
end_num = ""
|
||||
|
||||
if index_point == -1:
|
||||
index_point = len(str_numb)
|
||||
else:
|
||||
end_num = str_numb[index_point:]
|
||||
|
||||
normal_numb = ""
|
||||
count = 0
|
||||
|
||||
for i in range(index_point - 1, -1, -1):
|
||||
normal_numb = str_numb[i] + normal_numb
|
||||
count += 1
|
||||
if count % 3 == 0:
|
||||
normal_numb = " " + normal_numb
|
||||
return normal_numb + end_num
|
||||
|
||||
|
||||
@app.route("/", methods=["GET", "POST"])
|
||||
def index():
|
||||
if request.method == "POST":
|
||||
if "datafile" in request.files and request.files["datafile"].filename != "":
|
||||
file = request.files["datafile"]
|
||||
data = parse_uploaded_data(file)
|
||||
else:
|
||||
try:
|
||||
data = {
|
||||
"x0": list(map(float, request.form["x0"].split(","))),
|
||||
"delta0": list(map(float, request.form["delta0"].split(","))),
|
||||
"epsilon": float(request.form["epsilon"]),
|
||||
"alpha": float(request.form["alpha"]),
|
||||
"target": request.form["target"],
|
||||
"x1c": list(map(float, request.form["x1c"].split(","))),
|
||||
"x2c": list(map(float, request.form["x2c"].split(","))),
|
||||
"x1r": list(map(float, request.form["x1r"].split(","))),
|
||||
"x2r": list(map(float, request.form["x2r"].split(","))),
|
||||
}
|
||||
except (KeyError, ValueError, json.JSONDecodeError):
|
||||
return render_template(
|
||||
"index.html",
|
||||
error="Ошибка в данных формы. Заполните все поля корректно.",
|
||||
)
|
||||
|
||||
# Инициализация функций
|
||||
c = [data["x1c"][::-1], data["x2c"][::-1]]
|
||||
x1r = data["x1r"]
|
||||
x2r = data["x2r"]
|
||||
target = data["target"]
|
||||
|
||||
def f(x):
|
||||
return sum(
|
||||
[
|
||||
sum([c[i][j] * x[i] ** j for j in range(len(c[i]))])
|
||||
for i in range(len(c))
|
||||
]
|
||||
)
|
||||
|
||||
def fit(a, b):
|
||||
return a < b if target == "min" else a > b
|
||||
|
||||
def r(x):
|
||||
return x1r[0] <= x[0] <= x1r[1] and x2r[0] <= x[1] <= x2r[1]
|
||||
|
||||
# Запуск метода
|
||||
x, val, x_err = HookJeeves.hooke_jeeves(
|
||||
f, data["x0"], data["delta0"], data["epsilon"], data["alpha"], r=r, fit=fit
|
||||
)
|
||||
|
||||
return render_template(
|
||||
"index.html",
|
||||
result=True,
|
||||
log=HookJeeves.result_log,
|
||||
extreme={
|
||||
"x": x,
|
||||
"val": to_normal_numb(val),
|
||||
"x_err": x_err,
|
||||
"type": target,
|
||||
},
|
||||
form_data={
|
||||
"x0": to_str(data["x0"]),
|
||||
"delta0": to_str(data["delta0"]),
|
||||
"epsilon": str(data["epsilon"]),
|
||||
"alpha": str(data["alpha"]),
|
||||
"target": data["target"],
|
||||
"x1c": to_str(data["x1c"]),
|
||||
"x2c": to_str(data["x2c"]),
|
||||
"x1r": to_str(data["x1r"]),
|
||||
"x2r": to_str(data["x2r"]),
|
||||
},
|
||||
)
|
||||
|
||||
return render_template("index.html")
|
||||
BIN
lab2/docs/mainform.png
Normal file
BIN
lab2/docs/mainform.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 104 KiB |
BIN
lab2/docs/results.png
Normal file
BIN
lab2/docs/results.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
BIN
lab2/docs/zadanie.png
Normal file
BIN
lab2/docs/zadanie.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
39
lab2/example.json
Normal file
39
lab2/example.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"x0": [
|
||||
100,
|
||||
100
|
||||
],
|
||||
"delta0": [
|
||||
10,
|
||||
10
|
||||
],
|
||||
"epsilon": 0.0001,
|
||||
"alpha": 2,
|
||||
"target": "min",
|
||||
"x1r": [
|
||||
-10000,
|
||||
10000
|
||||
],
|
||||
"x2r": [
|
||||
-10000,
|
||||
10000
|
||||
],
|
||||
"x1c": [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"x2c": [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
]
|
||||
}
|
||||
9
lab2/main.py
Normal file
9
lab2/main.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import HookJeeves
|
||||
|
||||
|
||||
def main():
|
||||
HookJeeves.main()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
253
lab2/poetry.lock
generated
Normal file
253
lab2/poetry.lock
generated
Normal file
@@ -0,0 +1,253 @@
|
||||
# This file is automatically @generated by Poetry 2.1.2 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "blinker"
|
||||
version = "1.9.0"
|
||||
description = "Fast, simple object-to-object and broadcast signaling"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc"},
|
||||
{file = "blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.1.8"
|
||||
description = "Composable command line interface toolkit"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"},
|
||||
{file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
description = "Cross-platform colored terminal text."
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||
groups = ["main"]
|
||||
markers = "platform_system == \"Windows\""
|
||||
files = [
|
||||
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flask"
|
||||
version = "3.1.0"
|
||||
description = "A simple framework for building complex web applications."
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "flask-3.1.0-py3-none-any.whl", hash = "sha256:d667207822eb83f1c4b50949b1623c8fc8d51f2341d65f72e1a1815397551136"},
|
||||
{file = "flask-3.1.0.tar.gz", hash = "sha256:5f873c5184c897c8d9d1b05df1e3d01b14910ce69607a117bd3277098a5836ac"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
blinker = ">=1.9"
|
||||
click = ">=8.1.3"
|
||||
itsdangerous = ">=2.2"
|
||||
Jinja2 = ">=3.1.2"
|
||||
Werkzeug = ">=3.1"
|
||||
|
||||
[package.extras]
|
||||
async = ["asgiref (>=3.2)"]
|
||||
dotenv = ["python-dotenv"]
|
||||
|
||||
[[package]]
|
||||
name = "itsdangerous"
|
||||
version = "2.2.0"
|
||||
description = "Safely pass data to untrusted environments and back."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef"},
|
||||
{file = "itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jinja2"
|
||||
version = "3.1.6"
|
||||
description = "A very fast and expressive template engine."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"},
|
||||
{file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
MarkupSafe = ">=2.0"
|
||||
|
||||
[package.extras]
|
||||
i18n = ["Babel (>=2.7)"]
|
||||
|
||||
[[package]]
|
||||
name = "markupsafe"
|
||||
version = "3.0.2"
|
||||
description = "Safely add untrusted strings to HTML/XML markup."
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"},
|
||||
{file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "2.2.5"
|
||||
description = "Fundamental package for array computing in Python"
|
||||
optional = false
|
||||
python-versions = ">=3.10"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "numpy-2.2.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1f4a922da1729f4c40932b2af4fe84909c7a6e167e6e99f71838ce3a29f3fe26"},
|
||||
{file = "numpy-2.2.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b6f91524d31b34f4a5fee24f5bc16dcd1491b668798b6d85585d836c1e633a6a"},
|
||||
{file = "numpy-2.2.5-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:19f4718c9012e3baea91a7dba661dcab2451cda2550678dc30d53acb91a7290f"},
|
||||
{file = "numpy-2.2.5-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:eb7fd5b184e5d277afa9ec0ad5e4eb562ecff541e7f60e69ee69c8d59e9aeaba"},
|
||||
{file = "numpy-2.2.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6413d48a9be53e183eb06495d8e3b006ef8f87c324af68241bbe7a39e8ff54c3"},
|
||||
{file = "numpy-2.2.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7451f92eddf8503c9b8aa4fe6aa7e87fd51a29c2cfc5f7dbd72efde6c65acf57"},
|
||||
{file = "numpy-2.2.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0bcb1d057b7571334139129b7f941588f69ce7c4ed15a9d6162b2ea54ded700c"},
|
||||
{file = "numpy-2.2.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:36ab5b23915887543441efd0417e6a3baa08634308894316f446027611b53bf1"},
|
||||
{file = "numpy-2.2.5-cp310-cp310-win32.whl", hash = "sha256:422cc684f17bc963da5f59a31530b3936f57c95a29743056ef7a7903a5dbdf88"},
|
||||
{file = "numpy-2.2.5-cp310-cp310-win_amd64.whl", hash = "sha256:e4f0b035d9d0ed519c813ee23e0a733db81ec37d2e9503afbb6e54ccfdee0fa7"},
|
||||
{file = "numpy-2.2.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c42365005c7a6c42436a54d28c43fe0e01ca11eb2ac3cefe796c25a5f98e5e9b"},
|
||||
{file = "numpy-2.2.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:498815b96f67dc347e03b719ef49c772589fb74b8ee9ea2c37feae915ad6ebda"},
|
||||
{file = "numpy-2.2.5-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:6411f744f7f20081b1b4e7112e0f4c9c5b08f94b9f086e6f0adf3645f85d3a4d"},
|
||||
{file = "numpy-2.2.5-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:9de6832228f617c9ef45d948ec1cd8949c482238d68b2477e6f642c33a7b0a54"},
|
||||
{file = "numpy-2.2.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:369e0d4647c17c9363244f3468f2227d557a74b6781cb62ce57cf3ef5cc7c610"},
|
||||
{file = "numpy-2.2.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:262d23f383170f99cd9191a7c85b9a50970fe9069b2f8ab5d786eca8a675d60b"},
|
||||
{file = "numpy-2.2.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:aa70fdbdc3b169d69e8c59e65c07a1c9351ceb438e627f0fdcd471015cd956be"},
|
||||
{file = "numpy-2.2.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37e32e985f03c06206582a7323ef926b4e78bdaa6915095ef08070471865b906"},
|
||||
{file = "numpy-2.2.5-cp311-cp311-win32.whl", hash = "sha256:f5045039100ed58fa817a6227a356240ea1b9a1bc141018864c306c1a16d4175"},
|
||||
{file = "numpy-2.2.5-cp311-cp311-win_amd64.whl", hash = "sha256:b13f04968b46ad705f7c8a80122a42ae8f620536ea38cf4bdd374302926424dd"},
|
||||
{file = "numpy-2.2.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ee461a4eaab4f165b68780a6a1af95fb23a29932be7569b9fab666c407969051"},
|
||||
{file = "numpy-2.2.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ec31367fd6a255dc8de4772bd1658c3e926d8e860a0b6e922b615e532d320ddc"},
|
||||
{file = "numpy-2.2.5-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:47834cde750d3c9f4e52c6ca28a7361859fcaf52695c7dc3cc1a720b8922683e"},
|
||||
{file = "numpy-2.2.5-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:2c1a1c6ccce4022383583a6ded7bbcda22fc635eb4eb1e0a053336425ed36dfa"},
|
||||
{file = "numpy-2.2.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d75f338f5f79ee23548b03d801d28a505198297534f62416391857ea0479571"},
|
||||
{file = "numpy-2.2.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a801fef99668f309b88640e28d261991bfad9617c27beda4a3aec4f217ea073"},
|
||||
{file = "numpy-2.2.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:abe38cd8381245a7f49967a6010e77dbf3680bd3627c0fe4362dd693b404c7f8"},
|
||||
{file = "numpy-2.2.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5a0ac90e46fdb5649ab6369d1ab6104bfe5854ab19b645bf5cda0127a13034ae"},
|
||||
{file = "numpy-2.2.5-cp312-cp312-win32.whl", hash = "sha256:0cd48122a6b7eab8f06404805b1bd5856200e3ed6f8a1b9a194f9d9054631beb"},
|
||||
{file = "numpy-2.2.5-cp312-cp312-win_amd64.whl", hash = "sha256:ced69262a8278547e63409b2653b372bf4baff0870c57efa76c5703fd6543282"},
|
||||
{file = "numpy-2.2.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:059b51b658f4414fff78c6d7b1b4e18283ab5fa56d270ff212d5ba0c561846f4"},
|
||||
{file = "numpy-2.2.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:47f9ed103af0bc63182609044b0490747e03bd20a67e391192dde119bf43d52f"},
|
||||
{file = "numpy-2.2.5-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:261a1ef047751bb02f29dfe337230b5882b54521ca121fc7f62668133cb119c9"},
|
||||
{file = "numpy-2.2.5-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4520caa3807c1ceb005d125a75e715567806fed67e315cea619d5ec6e75a4191"},
|
||||
{file = "numpy-2.2.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d14b17b9be5f9c9301f43d2e2a4886a33b53f4e6fdf9ca2f4cc60aeeee76372"},
|
||||
{file = "numpy-2.2.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ba321813a00e508d5421104464510cc962a6f791aa2fca1c97b1e65027da80d"},
|
||||
{file = "numpy-2.2.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4cbdef3ddf777423060c6f81b5694bad2dc9675f110c4b2a60dc0181543fac7"},
|
||||
{file = "numpy-2.2.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:54088a5a147ab71a8e7fdfd8c3601972751ded0739c6b696ad9cb0343e21ab73"},
|
||||
{file = "numpy-2.2.5-cp313-cp313-win32.whl", hash = "sha256:c8b82a55ef86a2d8e81b63da85e55f5537d2157165be1cb2ce7cfa57b6aef38b"},
|
||||
{file = "numpy-2.2.5-cp313-cp313-win_amd64.whl", hash = "sha256:d8882a829fd779f0f43998e931c466802a77ca1ee0fe25a3abe50278616b1471"},
|
||||
{file = "numpy-2.2.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:e8b025c351b9f0e8b5436cf28a07fa4ac0204d67b38f01433ac7f9b870fa38c6"},
|
||||
{file = "numpy-2.2.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8dfa94b6a4374e7851bbb6f35e6ded2120b752b063e6acdd3157e4d2bb922eba"},
|
||||
{file = "numpy-2.2.5-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:97c8425d4e26437e65e1d189d22dff4a079b747ff9c2788057bfb8114ce1e133"},
|
||||
{file = "numpy-2.2.5-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:352d330048c055ea6db701130abc48a21bec690a8d38f8284e00fab256dc1376"},
|
||||
{file = "numpy-2.2.5-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b4c0773b6ada798f51f0f8e30c054d32304ccc6e9c5d93d46cb26f3d385ab19"},
|
||||
{file = "numpy-2.2.5-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55f09e00d4dccd76b179c0f18a44f041e5332fd0e022886ba1c0bbf3ea4a18d0"},
|
||||
{file = "numpy-2.2.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:02f226baeefa68f7d579e213d0f3493496397d8f1cff5e2b222af274c86a552a"},
|
||||
{file = "numpy-2.2.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c26843fd58f65da9491165072da2cccc372530681de481ef670dcc8e27cfb066"},
|
||||
{file = "numpy-2.2.5-cp313-cp313t-win32.whl", hash = "sha256:1a161c2c79ab30fe4501d5a2bbfe8b162490757cf90b7f05be8b80bc02f7bb8e"},
|
||||
{file = "numpy-2.2.5-cp313-cp313t-win_amd64.whl", hash = "sha256:d403c84991b5ad291d3809bace5e85f4bbf44a04bdc9a88ed2bb1807b3360bb8"},
|
||||
{file = "numpy-2.2.5-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b4ea7e1cff6784e58fe281ce7e7f05036b3e1c89c6f922a6bfbc0a7e8768adbe"},
|
||||
{file = "numpy-2.2.5-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:d7543263084a85fbc09c704b515395398d31d6395518446237eac219eab9e55e"},
|
||||
{file = "numpy-2.2.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0255732338c4fdd00996c0421884ea8a3651eea555c3a56b84892b66f696eb70"},
|
||||
{file = "numpy-2.2.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d2e3bdadaba0e040d1e7ab39db73e0afe2c74ae277f5614dad53eadbecbbb169"},
|
||||
{file = "numpy-2.2.5.tar.gz", hash = "sha256:a9c0d994680cd991b1cb772e8b297340085466a6fe964bc9d4e80f5e2f43c291"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "werkzeug"
|
||||
version = "3.1.3"
|
||||
description = "The comprehensive WSGI web application library."
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e"},
|
||||
{file = "werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
MarkupSafe = ">=2.1.1"
|
||||
|
||||
[package.extras]
|
||||
watchdog = ["watchdog (>=2.3)"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.1"
|
||||
python-versions = ">=3.13"
|
||||
content-hash = "e79fa5194de439ac19f30a7b4183d2c032849069c480531d402389348b2a8162"
|
||||
21
lab2/pyproject.toml
Normal file
21
lab2/pyproject.toml
Normal file
@@ -0,0 +1,21 @@
|
||||
[project]
|
||||
name = "lab2"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = [
|
||||
{name = "Никита Потапов",email = "ns.potapov@yandex.ru"}
|
||||
]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = [
|
||||
"numpy (>=2.2.5,<3.0.0)",
|
||||
"flask (>=3.1.0,<4.0.0)"
|
||||
]
|
||||
|
||||
[tool.poetry]
|
||||
package-mode = false
|
||||
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
1
lab2/requirements.txt
Normal file
1
lab2/requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
numpy==2.2.5
|
||||
0
lab2/static/style.css
Normal file
0
lab2/static/style.css
Normal file
109
lab2/templates/index.html
Normal file
109
lab2/templates/index.html
Normal file
@@ -0,0 +1,109 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Метод Хука-Дживса</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body class="bg-light">
|
||||
<div class="container mt-5">
|
||||
<h1 class="mb-4">Метод Хука-Дживса</h1>
|
||||
|
||||
{% if error %}
|
||||
<div class="alert alert-danger">{{ error }}</div>
|
||||
{% endif %}
|
||||
|
||||
<form method="post" enctype="multipart/form-data" class="mb-4">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Координаты начальной базовой точки x0</label>
|
||||
<input type="text" name="x0" class="form-control" placeholder="100,100"
|
||||
value='{{form_data["x0"] if form_data else ""}}'>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Начальные приращения Δx</label>
|
||||
<input type="text" name="delta0" class="form-control" placeholder="100,100"
|
||||
value='{{form_data["delta0"] if form_data else ""}}'>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Требуемая точность ε</label>
|
||||
<input type="text" name="epsilon" class="form-control" placeholder="0.0001"
|
||||
value='{{form_data["epsilon"] if form_data else ""}}'>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Коэффициент α</label>
|
||||
<input type="text" name="alpha" class="form-control" placeholder="2"
|
||||
value='{{form_data["alpha"] if form_data else ""}}'>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Цель:</label>
|
||||
<select name="target" class="form-select">
|
||||
{% for k, v in {"min": "Минимум", "max": "Максимум"}.items() %}
|
||||
{% if form_data and form_data["target"] == k %}
|
||||
<option selected value="{{k}}">{{v}}</option>
|
||||
{% else %}
|
||||
<option value="{{k}}">{{v}}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Ограничения x1:</label>
|
||||
<input type="text" name="x1r" class="form-control" placeholder="-1000,100000"
|
||||
value='{{form_data["x1r"] if form_data else ""}}'>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Ограничения x2:</label>
|
||||
<input type="text" name="x2r" class="form-control" placeholder="-1000,100000"
|
||||
value='{{form_data["x2r"] if form_data else ""}}'>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<label class="form-label">Коэффициенты при x1 (через запятую)</label>
|
||||
<textarea name="x1c" class="form-control" rows="3"
|
||||
placeholder='1,1,1,1,1,1,1'>{{form_data["x1c"] if form_data else ""}}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<label class="form-label">Коэффициенты при x2 (через запятую)</label>
|
||||
<textarea name="x2c" class="form-control" rows="3"
|
||||
placeholder='1,1,1,1,1,1,1'>{{form_data["x2c"] if form_data else ""}}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<label class="form-label">ИЛИ загрузите JSON-файл с данными:</label>
|
||||
<input type="file" name="datafile" class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="col-12 mt-3">
|
||||
<button type="submit" class="btn btn-primary">Рассчитать</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{% if result %}
|
||||
<h4>Найденный экстремум ({{extreme.type}}):</h4>
|
||||
<ul>
|
||||
<li><strong>x:</strong> {{ extreme.x }}</li>
|
||||
<li><strong>f(x):</strong> {{ extreme.val }}</li>
|
||||
<li><strong>Погрешности:</strong> {{ extreme.x_err }}</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2>Промежуточные вычисления</h2>
|
||||
<pre class="bg-white p-3 border">{{ log }}</pre>
|
||||
|
||||
<h4>Найденный экстремум ({{extreme.type}}):</h4>
|
||||
<ul>
|
||||
<li><strong>x:</strong> {{ extreme.x }}</li>
|
||||
<li><strong>f(x):</strong> {{ extreme.val }}</li>
|
||||
<li><strong>Погрешности:</strong> {{ extreme.x_err }}</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user