# Сингулярное разложение (SVD) и малоранговая аппроксимация

Этот модуль предоставляет реализацию сингулярного разложения (SVD) матрицы и функции для построения малоранговой аппроксимации на основе SVD.

## Сингулярное разложение (SVD)

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

Сингулярное разложение (SVD) — это разложение матрицы $F^*$ размерности $m \times n$ на три матрицы:

$F^* = U \Sigma V^T$,

где:

- $U$ — ортогональная матрица левых сингулярных векторов размерности $m \times m$.
- $\Sigma$ — диагональная матрица сингулярных значений размерности $m \times n$. Сингулярные значения — это неотрицательные числа, расположенные по убыванию на главной диагонали.
- $V^T$ — транспонированная ортогональная матрица правых сингулярных векторов размерности $n \times n$.

SVD является фундаментальным инструментом линейной алгебры с широким спектром применений, включая:

- Понижение размерности (например, метод главных компонент — PCA).
- Решение линейных систем уравнений.
- Сжатие данных.
- Рекомендательные системы.
- Обработка изображений и сигналов.

**Алгоритм вычисления SVD (структурированный подход):**

1. **Вычисление матрицы $A = F^{*T} F^*$**:  Эта матрица симметрична и положительно полуопределена.
2. **Приведение $A$ к тридиагональной форме методом Хаусхолдера**:  Этот шаг упрощает вычисление собственных значений и векторов.
3. **Нахождение собственных значений $A$ через QR-алгоритм**:  Собственные значения $A$ являются квадратами сингулярных значений $F^*$.
4. **Вычисление собственных векторов $A$**:  Собственные векторы $A$ образуют матрицу $V$ правых сингулярных векторов.
5. **Вычисление сингулярных значений**:  Сингулярные значения $\sigma_i$ вычисляются как квадратные корни из собственных значений $\lambda_i$: $\sigma_i = \sqrt{\lambda_i}$.
6. **Вычисление левых сингулярных векторов $U$**:  $U$ можно вычислить как $U = F^* V \Sigma^{-1}$, где $\Sigma^{-1}$ — обратная матрица сингулярных значений.  При наличии малых сингулярных значений используется корректировка для избежания деления на ноль.
7. **Транспонирование $V$ для получения $V^T$**:  Необходимо для завершения разложения.

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

Функция `SVD(F_star, FLOAT_TOLERANCE=1e-12)` выполняет сингулярное разложение матрицы `F_star` с использованием описанного выше структурированного подхода.

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

- `F_star` (`np.ndarray` или `list` из `list`): Входная матрица размерности $(m, n)$, для которой требуется выполнить SVD.
- `FLOAT_TOLERANCE` (`float`, по умолчанию: `1e-12`): Допустимая погрешность для численных операций. Используется для обработки малых сингулярных значений.

**Возвращаемые значения:**

- `U` (`np.ndarray`): Матрица левых сингулярных векторов размерности $(m, m)$.
- `singular_values` (`np.ndarray`): Вектор сингулярных значений размерности $(\min(m, n),)$.
- `VT` (`np.ndarray`): Транспонированная матрица правых сингулярных векторов размерности $(n, n)$.

**Пример использования:**

```python
import numpy as np
from matplobblib.nm.matrices.SVD import SVD  # Предполагается, что модуль находится в указанном пути

F_star = np.array([[1, 2], [3, 4], [5, 6]], dtype=np.float64)
U, s, VT = SVD(F_star)
print("U:", U)
print("Сингулярные значения:", s)
print("VT:", VT)
```

**Важные замечания:**

- Функция предполагает наличие вспомогательных функций `Householder`, `QR_alg` и `compute_orthonormal_basis` в соответствующих модулях.
- Численная нестабильность возможна при наличии малых сингулярных значений, что требует корректировки обратной матрицы.
- Эффективность QR-алгоритма и метода Хаусхолдера зависит от структуры входной матрицы и заданных параметров точности.

## Малоранговая аппроксимация

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

Малоранговая аппроксимация матрицы — это представление матрицы $F^*$ ранга $r$ в виде произведения матриц меньшего размера:

$F^* \approx F^*_r = U_r \Sigma_r V_r^T$,

где:

- $U_r$ — матрица, состоящая из первых $r$ столбцов матрицы $U$ (размерность $m \times r$).
- $\Sigma_r$ — диагональная матрица, содержащая $r$ наибольших сингулярных значений (размерность $r \times r$).
- $V_r^T$ — матрица, состоящая из первых $r$ строк матрицы $V^T$ (размерность $r \times n$).

Выбор $r$ наилучших сингулярных значений и соответствующих векторов минимизирует ошибку аппроксимации в евклидовой норме (теорема Эккарта-Янга).  Малоранговая аппроксимация позволяет уменьшить объем данных, сохраняя при этом наиболее важные характеристики матрицы.

Применения малоранговой аппроксимации:

- Сжатие данных (например, изображений).
- Удаление шума.
- Ускорение вычислений (за счет работы с матрицами меньшего размера).
- Выделение скрытых факторов в данных.

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

Функция `low_rank_approximation(U, singular_values, VT, r)` строит малоранговую аппроксимацию матрицы на основе её SVD.

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

- `U` (`np.ndarray`): Матрица левых сингулярных векторов, полученная из SVD.
- `singular_values` (`np.ndarray`): Одномерный массив сингулярных значений, упорядоченных по убыванию.
- `VT` (`np.ndarray`): Транспонированная матрица правых сингулярных векторов.
- `r` (`int`): Ранг аппроксимации. Должен быть в диапазоне $(0, \min(m, n)]$.

**Возвращаемые значения:**

- `F_star_r` (`np.ndarray`): Матрица малоранговой аппроксимации размерности $(m, n)$.
- `Ur` (`np.ndarray`): Усеченная матрица $U$ до размерности $(m, r)$.
- `Sigma_r` (`np.ndarray`): Диагональная матрица сингулярных значений размерности $(r, r)$.
- `VTr` (`np.ndarray`): Усеченная матрица $V^T$ до размерности $(r, n)$.

**Пример использования:**

```python
import numpy as np
from matplobblib.nm.matrices.SVD import SVD, low_rank_approximation  # Предполагается, что модуль находится в указанном пути

A = np.array([[1, 2], [3, 4], [5, 6]], dtype=np.float64)
U, s, VT = SVD(A)
F_star_r, Ur, Sigma_r, VTr = low_rank_approximation(U, s, VT, r=1)
print("F_star_r:", F_star_r)
```

**Важные замечания:**

- Сингулярные значения должны быть предварительно отсортированы по убыванию для корректной аппроксимации.  Функция `SVD` возвращает сингулярные значения в отсортированном виде.
- Если $r$ превышает количество ненулевых сингулярных значений, аппроксимация не улучшит точность.
- Численная устойчивость зависит от качества исходного SVD и структуры сингулярных значений.

## Ссылки

- [1] "The Singular Value Decomposition (SVD) and Low-Rank Matrix Approximation" - (https://example.com/svd-lowrank)
- [2] "Generalized Low Rank Approximations of Matrices" - (https://example.com/generalized-lowrank)
- [3] "SVD для PCA и рекомендательных систем" - (https://example.com/svd-pca)
- [4] "Lecture 4: Matrix rank, low-rank approximation, SVD" - (https://example.com/matrix-rank)
- [5] "Algorithms for `p Low-Rank Approximation" - (https://example.com/lowrank-algorithms)
- [7] "Оптимизация SVD для больших матриц" - (https://example.com/svd-optimization)
- [7] "Demystifying Neural Networks: Low-Rank Approximation" - (https://example.com/neural-lowrank)
- [8] "Геометрический смысл SVD" - (https://example.com/svd-geometry)
