# Модуль интерполяции `matplobblib.nm.interp`

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

## 1. Интерполяция многочленом Лагранжа

Модуль содержит две функции для интерполяции с использованием многочлена Лагранжа:

### 1.1 `lagrange_interpolation(x_values, y_values, x)`

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

Вычисляет значение интерполяционного многочлена Лагранжа в заданной точке `x` на основе набора узлов интерполяции `(x_values, y_values)`.

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

Интерполяционный многочлен Лагранжа – это многочлен минимальной степени, который проходит через все заданные точки `(xᵢ, yᵢ)`.  Для набора из `n` точек он имеет вид:

```
L(x) = Σᵢ₌₀ⁿ⁻¹ yᵢ * lᵢ(x)
```

где `lᵢ(x)` – базисные полиномы Лагранжа, определяемые как:

```
lᵢ(x) = Πⱼ₌₀,ⱼ≠ᵢⁿ⁻¹ (x - xⱼ) / (xᵢ - xⱼ)
```

Этот метод гарантирует существование и единственность интерполяционного многочлена при условии, что все значения `xᵢ` различны.  Однако, при использовании большого количества узлов может возникнуть эффект Рунге – появление сильных осцилляций между узлами, особенно для гладких функций.

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

- `x_values` (array_like): Массив узлов интерполяции (координаты x). Все элементы должны быть уникальными. Пример: `[x₀, x₁, ..., xₙ₋₁]`
- `y_values` (array_like): Массив значений функции в узлах интерполяции. Пример: `[y₀, y₁, ..., yₙ₋₁]`. Длина `y_values` должна совпадать с длиной `x_values`.
- `x` (float): Точка, в которой вычисляется значение интерполяционного полинома.

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

- `float`: Интерполированное значение в точке `x`.

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

```python
from matplobblib.nm.interp import lagrange_interpolation

print(lagrange_interpolation([0, 1, 2], [1, 4, 9], 0.5))  # Вывод: 2.25
print(lagrange_interpolation([1, 2, 3], [1, 4, 9], 5))    # Вывод: 25.0
```

**Замечания:**

1. Формула Лагранжа реализует полином степени `n-1`, проходящий через все `n` заданных точек.
2. При наличии повторяющихся значений в `x_values` возникнет деление на ноль.
3. Эффект Рунге может проявляться при интерполяции большим количеством узлов.

**Ссылки:**

- Интерполяционная формула Лагранжа - Википедия
- Интерполяционный многочлен Лагранжа - Prezi (Пример ссылки, замените на актуальную)
- Интерполяционный многочлен Лагранжа (полином Лагранжа) (Пример ссылки, замените на актуальную)
- Построить интерполяционный многочлен в форме Лагранжа (Пример ссылки, замените на актуальную)
- [[PDF] Интерполяция многочленом Лагранжа](https://example.com/lagrange-pdf) (Пример ссылки, замените на актуальную)

### 1.2 `lagrange_interpolation_func_get(x_values, y_values)`

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

Строит интерполяционный полином Лагранжа для заданных точек и возвращает функцию, которая вычисляет значение этого полинома в любой точке.

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

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

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

- `x_values` (array_like): Список или массив значений координат x, по которым строится интерполяция. Все элементы должны быть уникальными. Пример: `[x₀, x₁, ..., xₙ₋₁]`
- `y_values` (array_like): Список или массив значений координат y, соответствующих `x_values`. Пример: `[y₀, y₁, ..., yₙ₋₁]`. Длина `y_values` должна совпадать с длиной `x_values`.

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

- `callable`: Функция, реализующая интерполяционный полином Лагранжа. Принимает аргумент `x` (float) и возвращает интерполированное значение (float).

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

```python
from matplobblib.nm.interp import lagrange_interpolation_func_get

f = lagrange_interpolation_func_get([0, 1, 2], [1, 4, 9])
print(f(0.5))  # Вывод: 2.25
print(f(1.5))  # Вывод: 6.25
```

**Замечания:**

1. Метод Лагранжа строит полином степени `n-1`, проходящий через все `n` заданных точек.
2. При большом количестве точек возможен эффект Рунге.
3. Требование уникальности `x_values` связано с вычислением базисных полиномов.

**Ссылки:**

- Интерполяционная формула Лагранжа - Википедия
- Интерполяционный многочлен Лагранжа - Циклопедия (Пример ссылки, замените на актуальную)
- Методы интерполяции и аппроксимации - PDF (Пример ссылки, замените на актуальную)
- Бахвалов Н.С., Жидков Н.П., Кобельков Г.М. Численные методы. М.: Лаборатория Базовых Знаний, 2002.
- Kincaid D., Cheney W. Numerical Analysis: Mathematics of Scientific Computing. Brooks/Cole, 2002.
- Интерполяция с помощью формулы Лагранжа - Циклопедия (Пример ссылки, замените на актуальную)

## 2. Интерполяция с учетом временной задержки

Модуль предоставляет функцию для получения значений из истории с учетом временной задержки:

### 2.1 `get_delayed_value(history, delay_time, t0)`

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

Получает значение из истории изменений с использованием линейной интерполяции для заданного времени `delay_time`.  Поддерживает экстраполяцию на границах истории.  Предназначена для работы с системами, имеющими временную задержку.

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

Линейная интерполяция используется для оценки значения функции между двумя известными точками, предполагая линейное изменение функции на этом участке.  Формула линейной интерполяции между точками `(x₀, y₀)` и `(x₁, y₁)` для точки `x` имеет вид:

```
f(x) = y₀ + (x - x₀) * (y₁ - y₀) / (x₁ - x₀)
```

Вне интервала известных значений выполняется экстраполяция, при которой используются крайние значения истории.  Этот метод широко применяется для численного восстановления данных в системах с временной задержкой.

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

1. Проверяет корректность входных данных (непустая история, допустимый диапазон времени).
2. Использует бинарный поиск (`bisect_right`) для определения соседних точек в истории.
3. Выполняет линейную интерполяцию между соседними точками или экстраполяцию на границах.

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

- `history` (list[tuple[float, float]]): История изменений в формате списка кортежей `(время, значение)`. Должна быть отсортирована по возрастанию времени.
- `delay_time` (float): Время, для которого требуется получить значение (обычно `t_current - tau`, где `tau` - величина задержки).
- `t0` (float): Начальное время системы (используется для обработки случаев `delay_time < t0`).

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

- `float`: Интерполированное значение для времени `delay_time`. Возвращает первое значение из истории, если `delay_time <= t0` или меньше минимального времени в истории. Возвращает последнее значение из истории, если `delay_time` больше максимального времени в истории.

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

```python
from matplobblib.nm.interp import get_delayed_value

history = [(0.0, 1.0), (2.0, 3.0), (4.0, 2.0)]
print(get_delayed_value(history, 1.0, 0.0))  # Вывод: 2.0
print(get_delayed_value(history, 5.0, 0.0))  # Вывод: 2.0
```

**Замечания:**

1. История должна быть предварительно отсортирована по времени для корректной работы.
2. Линейная интерполяция подходит для гладких функций, но может давать погрешность при резких изменениях данных.
3. Для повышения точности можно использовать полиномиальные методы интерполяции.

**Ссылки:**

- Linear interpolation - Wikipedia
- Linear Interpolation Formula - BYJU'S
- Linear Interpolation Formula: Definition, Formula, Solved Examples
- numpy.interp — NumPy v2.2 Manual

## 3. Заключение

Модуль `matplobblib.nm.interp` предоставляет полезные инструменты для интерполяции данных, включая полиномиальную интерполяцию Лагранжа и линейную интерполяцию с учетом временной задержки. Выбор метода интерполяции зависит от конкретной задачи и характеристик данных.  Для достижения наилучших результатов рекомендуется учитывать теоретические аспекты и ограничения каждого метода.
