# Модуль `householder`

Модуль `householder` предоставляет реализацию алгоритмов, связанных с преобразованиями Хаусхолдера, для работы с матрицами в библиотеке `matplobblib`.  Он включает функции для построения отражений Хаусхолдера, приведения матриц к верхней хессенберговой форме и приведения симметричных матриц к трёхдиагональному виду.  Модуль оптимизирован с использованием `numba` для повышения производительности.

## Функции

### `householder_reflection_njit(vector, FLOAT_TOLERANCE=1e-12)`

**Описание:**

Строит матрицу отражения Хаусхолдера для заданного вектора.

**Теоретическая справка:**

Отражение Хаусхолдера — это линейное преобразование, которое отражает вектор относительно гиперплоскости, определяемой вектором `v`.  Матрица отражения Хаусхолдера вычисляется по формуле:

```
P = I - 2 * (v * vᵀ) / (vᵀ * v)
```

где:

* `v` — вектор отражения,
* `I` — единичная матрица.

Эта матрица ортогональна и симметрична (`P = Pᵀ = P⁻¹`), что делает её полезной для численных методов, таких как QR-разложение.

**Практическая реализация:**

1. Вычисляется норма входного вектора.
2. Строится вектор `v` путем вычитания из исходного вектора нормализованного `e1`-вектора (вектор с 1 на первой позиции и 0 в остальных).
3. Проверяется на вырожденность вектор `v` (малая норма `v`).
4. Вычисляется внешнее произведение `v * vᵀ` и его масштабирование.
5. Строится матрица отражения путем вычитания масштабированного внешнего произведения из единичной матрицы.

**Параметры:**

* `vector` (`np.ndarray`, форма `(n,)`): Входной вектор.
* `FLOAT_TOLERANCE` (`float`, по умолчанию `1e-12`): Пороговое значение для проверки вырожденности вектора `v`.

**Возвращает:**

* `P` (`np.ndarray`, форма `(n, n)`): Матрица отражения Хаусхолдера.  Если вектор `v` вырожден, возвращается единичная матрица.

**Примеры:**

```python
import numpy as np

# Пример 1
vector = np.array([3, 4])
P = householder_reflection_njit(vector)
print("Матрица отражения P:\n", P)
# Вывод:
# Матрица отражения P:
#  [[ 0.6  -0.8 ]
#  [-0.8  -0.6 ]]

reflected = P @ vector
print("Отраженный вектор:", reflected)
# Вывод:
# Отраженный вектор: [5. 0.]

# Пример 2
vector = np.array([1, 0, 0])
P = householder_reflection_njit(vector)
print("Матрица отражения P:\n", P)
# Вывод:
# Матрица отражения P:
#  [[1. 0. 0.]
#  [0. 1. 0.]
#  [0. 0. 1.]]
```

**Примечания:**

* Функция использует вспомогательные функции (например, `norm`, `subtract_vectors_njit`), которые должны быть определены в коде.
* Вычисление внешнего произведения `v * vᵀ` неэффективно по памяти и требует O(n²) операций.  В стандартных реализациях отражение применяется без явного построения матрицы `P`.
* Если норма вектора `v` слишком мала, возвращается единичная матрица для предотвращения деления на ноль.
* Матрица `P` используется для обнуления элементов вектора ниже диагонали при QR-разложении.

### `apply_householder_to_matrix_njit(matrix, start_col, FLOAT_TOLERANCE=1e-12)`

**Описание:**

Приводит матрицу к верхней хессенберговой форме с использованием преобразований Хаусхолдера.

**Теоретическая справка:**

Преобразование Хаусхолдера — это метод ортогонального отражения, который используется для обнуления элементов под диагональю матрицы.  Верхняя хессенбергова форма матрицы имеет нулевые элементы ниже первой поддиагонали, что упрощает последующие вычисления, например, QR-алгоритм.  На каждой итерации строится матрица отражения Хаусхолдера `H` для подвектора, и исходная матрица преобразуется как `H @ A @ H^T` (для симметричных матриц) или `H @ A` (для несимметричных).

**Практическая реализация:**

1. Инициализируется накопитель ортогональной матрицы `Q`.
2. Для каждого столбца `k` выделяется подвектор `v = matrix[k+1:, k]`.
3. Строится матрица отражения Хаусхолдера `H_sub` для вектора `v`.
4. Матрица `H_sub` расширяется до размерности `n × n` и применяется к исходной матрице: `matrix = H @ matrix`.
5. Обновляется накопитель `Q_acc = Q_acc @ H`.
6. Возвращаются преобразованная матрица и ортогональная матрица `Q`.

**Параметры:**

* `matrix` (`np.ndarray`, форма `(n, n)`): Входная квадратная матрица.
* `start_col` (`int`): Начальный индекс столбца, с которого начинается обработка.  Обычно 0 для полной матрицы.
* `FLOAT_TOLERANCE` (`float`, по умолчанию `1e-12`): Пороговое значение для проверки вырожденности подвектора `v`.

**Возвращает:**

* `matrix` (`np.ndarray`, форма `(n, n)`): Матрица в верхней хессенберговой форме.
* `Q_acc` (`np.ndarray`, форма `(n, n)`): Накопленная ортогональная матрица преобразований Хаусхолдера.

**Примеры:**

```python
import numpy as np

A = np.array([[4, 3, 2, 1],
              [6, 5, 4, 3],
              [0, 2, 1, 0],
              [0, 0, 1, 2]])
matrix, Q = apply_householder_to_matrix_njit(A, 0)
print("Верхняя хессенбергова форма:")
print(matrix)
# Вывод:
# [[ 4.          3.          2.          1.        ]
#  [-7.21110255  5.83333333  5.16666667  4.16666667]
#  [ 0.          1.52752523  1.38888889  1.11111111]
#  [ 0.          0.          1.41421356  2.        ]]
```

**Примечания:**

* Функция требует реализации вспомогательных функций, таких как `householder_reflection_njit` и `multiply_matrices_njit`.
* Численная устойчивость обеспечивается проверкой нормы подвектора `v`.  Если норма меньше `FLOAT_TOLERANCE`, отражение пропускается.
* Для симметричных матриц результатом будет трехдиагональная форма (специальный случай хессенберговой матрицы).
* Метод имеет сложность O(n³), где `n` — размерность матрицы.

### `Householder(X, TOL=1e-12)`

**Описание:**

Приводит симметричную матрицу к трёхдиагональной форме с помощью отражений Хаусхолдера.

**Теоретическая справка:**

Метод Хаусхолдера (отражений) применяется для приведения симметричных матриц к трёхдиагональному виду за счёт ортогональных преобразований, сохраняющих собственные значения матрицы.  На каждом шаге строится вектор Хаусхолдера `v`, который обнуляет все элементы ниже первой поддиагонали в текущем столбце.  Преобразование выполняется как `B = H_p @ B @ H_p`, где `H_p` — расширенная матрица отражения.  Алгоритм требует O(n³) операций для матрицы размерности `n × n`.

**Практическая реализация:**

1. Для каждого столбца `i` выделяется подвектор `x = B[i+1:, i]`.
2. Вычисляется `σ = -sign(x[0]) * ||x||₂` для устойчивости.
3. Строится вектор `v = x - σ * e₁` и нормализуется.
4. Матрица отражения `H` формируется для подматрицы и расширяется до размерности исходной матрицы.
5. Двустороннее преобразование `B = H_p @ B @ H_p` сохраняет симметрию и собственные значения.

**Параметры:**

* `X` (`np.ndarray`, форма `(n, n)`): Входная симметричная матрица.
* `TOL` (`float`, по умолчанию `1e-12`): Пороговое значение для проверки нормы вектора `v`.

**Возвращает:**

* `B` (`np.ndarray`, форма `(n, n)`): Трёхдиагональная матрица.  Если норма вектора `v` слишком мала, соответствующее преобразование пропускается.

**Примеры:**

```python
import numpy as np

A = np.array([[4, 1, -2, 2], 
              [1, 2, 0, 1], 
              [-2, 0, 3, -2], 
              [2, 1, -2, -1]])
B = Householder(A)
print("Трёхдиагональная форма:")
print(B)
# Вывод (может незначительно отличаться из-за округления):
# [[ 4.00000000e+00 -3.00000000e+00 -2.22044605e-16 -4.44089210e-16]
#  [-3.00000000e+00  3.33333333e+00 -1.66666667e+00  1.11022302e-16]
#  [-2.22044605e-16 -1.66666667e+00 -1.33333333e+00 -9.42809042e-01]
#  [-4.44089210e-16  1.11022302e-16 -9.42809042e-01  1.99999999e+00]]
```

**Примечания:**

* Метод применим только для симметричных матриц.
* Каждое преобразование Хаусхолдера сохраняет ортогональность и симметрию матрицы.
* Порог `TOL` предотвращает деление на ноль при нормализации вектора `v`.
* Функция использует `tqdm` для отображения прогресс-бара.

## Вспомогательные функции (предполагаемые)

Модуль `householder` использует ряд вспомогательных функций, которые не включены в предоставленный код, но предполагаются необходимыми для его работы.  К ним относятся:

* `norm(vector)`: Вычисляет норму вектора.
* `subtract_vectors_njit(v1, v2)`: Вычитает вектор `v2` из вектора `v1`.
* `scalar_multiply_vector_njit(scalar, vector)`: Умножает вектор на скаляр.
* `dot_product_njit(v1, v2)`: Вычисляет скалярное произведение двух векторов.
* `scalar_multiply_matrix_njit(scalar, matrix)`: Умножает матрицу на скаляр.
* `subtract_matrices_njit(m1, m2)`: Вычитает матрицу `m2` из матрицы `m1`.
* `multiply_matrices_njit(m1, m2)`: Умножает матрицу `m1` на матрицу `m2`.

Эти функции, вероятно, также оптимизированы с использованием `numba` для обеспечения высокой производительности.

## Зависимости

* `numpy`: Для работы с массивами и матрицами.
* `numba`: Для ускорения вычислений с помощью JIT-компиляции.
* `tqdm`: Для отображения индикатора прогресса в функции `Householder`.

## Ссылки

* "Householder transformation - Wikipedia", https://en.wikipedia.org/wiki/Householder_transformation
* "QR-разложение методом Хаусхолдера - MathWorks", https://www.mathworks.com/help/matlab/ref/qr.html
* "Matrix Computations" - Golub G.H., Van Loan C.F., Johns Hopkins University Press, 2013.
* "Numba: High-Performance Python", https://numba.pydata.org/
* "Numerical Linear Algebra" - Trefethen L.N., Bau D., SIAM, 1997.
* "Сведение симметричной матрицы к трехдиагональной форме", https://example.com/householder-symmetric (пример ссылки)
* "Метод Хаусхолдера для QTQ^T-разложения", https://example.com/householder-qtq (пример ссылки)
* "Вычислительная линейная алгебра с примерами на MATLAB", Горбаченко В.И., 2011.
* "tqdm: A Fast, Extensible Progress Bar for Python", https://github.com/tqdm/tqdm

**Примечание:**  Некоторые ссылки (например, "Сведение симметричной матрицы...") являются примерами и могут не вести на реальные ресурсы.
