doc/math/array.md
2026-04-01 15:18:27 +03:00

673 lines
34 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## array
## 1
### habr
- [Алгоритм моделирования многомерного массива данных, распределенных по нормальному закону](https://habr.com/ru/articles/145315/)
### excel
- https://www.excel-vba.ru/chto-umeet-excel/dinamicheskie-massivy-v-excel/ Начнем с того, что динамические массивы будут доступны пользователям следующих версий Excel:
- 365 офис (по подписке)
- офис 2021 (для MAC и для Windows)
### js
- https://selectel.ru/blog/array-methods-part-1/
## 2
### tuples_or_sets
- https://www.reddit.com/r/learnpython/comments/ve6fe5/why_use_tuples_or_sets_instead_of_lists/?tl=ru Список
Очень похож на кортеж в использовании, но очень отличается по концепции. Техническое объяснение состоит в том, что список - это изменяемая упорядоченная коллекция, то есть ее состояние может меняться, но порядок элементов гарантирован.
- https://informatics.msk.ru/mod/book/view.php?id=49881
## 3 AI
### array
В функции есть несколько массивов - как входящие данные и несколько массивов - как результат функции. Как записать математически?
Понял, вы хотите, чтобы математическая запись функции с несколькими массивами на входе и выходе была оформлена только с помощью `$` (инлайн) и `$$` (дисплей) — так формулы гарантированно корректно отображаются на GitHub (через MathJax). Ниже привожу варианты, используя только эти конструкции.
---
## 1. Математическая нотация
В математике массивы обычно рассматриваются как элементы множеств
### Вариант 1: Декартово произведение (дисплейная формула)
$$
f: A_1 \times A_2 \times \dots \times A_k \;\longrightarrow\; B_1 \times B_2 \times \dots \times B_m
$$
### Вариант 2: Значение функции — кортеж (дисплейная формула)
$$
f(a_1, a_2, \dots, a_k) = (b_1, b_2, \dots, b_m)
$$
где $a_i \in A_i$, $b_j \in B_j$.
### Вариант 3: Векторная форма (если все массивы одного типа)
$$
f: A^k \to B^m,\qquad f(\mathbf{a}) = \mathbf{b}
$$
с $\mathbf{a} \in A^k$, $\mathbf{b} \in B^m$.
### Вариант 4: Теоретико-множественное определение (с использованием $\subseteq$)
$$
f \subseteq (A_1 \times \dots \times A_k) \times (B_1 \times \dots \times B_m)
$$
и для каждого входа существует ровно один выход.
---
## 2. Программирование (кратко, с акцентом на сигнатуры)
На GitHub в блоках кода формулы не нужны, поэтому просто приведу примеры сигнатур.
**Python (кортеж):**
```python
def process(arr1: list, arr2: list) -> tuple[list, list]:
...
```
**C (выходные параметры):**
```c
void process(int* in1, int* in2, int* out1, int* out2);
```
**Go (структура):**
```go
type Result struct { Out1 []int; Out2 []int }
func process(in1, in2 []int) Result
```
Если нужно именно математическое описание для GitHub — используйте приведённые выше формулы с `$` и `$$`, они будут отображаться корректно.
---
## 3. Замечания
- В математике часто стремятся объединить несколько выходных массивов в один (например, в виде матрицы, где столбцы — отдельные массивы), чтобы функция возвращала один объект.
- В программировании предпочтение отдаётся ясности: лучше явно указать типы и имена возвращаемых значений (через кортеж, объект или структуру), чем смешивать их в одном массиве.
- Если входные массивы имеют одинаковую структуру, их часто передают как один массив массивов (список списков).
## 4
Если вы хотите математически записать функцию, которая принимает два массива (`in1`, `in2`) и возвращает два массива (`out1`, `out2`), используя разделитель (например, `;`), то можно применить несколько подходов. В строгой математике функция обычно отображает входы в выходы, поэтому выходы не указываются в списке аргументов. Однако для наглядности или в неформальных текстах часто используют обозначения, где точка с запятой отделяет входные параметры от выходных. Ниже приведены наиболее близкие варианты, которые работают в математических текстах и на GitHub с использованием только `$` и `$$`.
---
### 1. Запись с разделителем в определении функции (нестрогая, но понятная)
Можно просто написать имя функции и перечислить входы и выходы через точку с запятой, пояснив смысл.
$$
F(\text{in1}, \text{in2}; \text{out1}, \text{out2})
$$
*Подразумевается, что `in1`, `in2` — аргументы, `out1`, `out2` — результаты.*
---
### 2. Запись как отношение (математически корректно)
Функцию можно рассматривать как отношение между входами и выходами. Тогда точка с запятой отделяет входные переменные от выходных.
$$
R(\text{in1}, \text{in2}; \text{out1}, \text{out2})
$$
где $R$ — отношение, связывающее входы с выходами. Если это отношение функционально по входам, то оно фактически задаёт функцию.
---
### 3. Использование кортежей и стрелки
Классический способ — показать отображение из декартова произведения множеств входов в декартово произведение множеств выходов. Разделитель `;` можно использовать внутри текста для пояснения.
$$
F: A_1 \times A_2 \;\longrightarrow\; B_1 \times B_2
$$
$$
F(\text{in1}, \text{in2}) = (\text{out1}, \text{out2})
$$
*Точка с запятой может быть добавлена в словесном описании: «где in1, in2 — входные массивы; out1, out2 — выходные».*
---
### 4. Нотация, имитирующая программирование (с разделителем)
Если вы хотите в точности повторить стиль `fun(in1, in2 ; out1, out2)`, то в математическом тексте это можно оформить так:
$$
\text{fun}(\text{in1}, \text{in2} \;;\; \text{out1}, \text{out2})
$$
или
$$
\text{fun}(\text{in1}, \text{in2}; \text{out1}, \text{out2})
$$
с пояснением, что выходные параметры перечислены после точки с запятой.
---
### 5. Запись с использованием вертикальной черты (альтернатива)
Иногда для разделения входов и выходов используют вертикальную черту, но точка с запятой тоже встречается:
$$
F(\text{in1}, \text{in2} \mid \text{out1}, \text{out2})
$$
---
### Рекомендация для GitHub
Для гарантированного отображения используйте только `$` и `$$`. Например:
```markdown
$$ \text{fun}(\text{in1}, \text{in2}; \text{out1}, \text{out2}) $$
```
Это будет выглядеть как одна формула, а точка с запятой будет просто символом разделения. Если нужна более строгая математическая форма, выберите вариант с отношением или со стрелкой.
---
### Итог
Наиболее близкие к вашему запросу варианты:
- **Неформальный:** $\text{fun}(\text{in1}, \text{in2}; \text{out1}, \text{out2})$
- **Формальный (отношение):** $R(\text{in1}, \text{in2}; \text{out1}, \text{out2})$
- **Классический:** $F: A_1 \times A_2 \to B_1 \times B_2$, $F(\text{in1}, \text{in2}) = (\text{out1}, \text{out2})$
## 5
Приведи вариант, когда используется упорядоченная коллекция, т.е. in1 имеет всегда первую позицию и отображается (при применении функции) в out 1. Тоже самое с in2 и out2.
Отвечу по пунктам.
---
## 1. Чем отличается вариант 1 от варианта 2?
В предыдущем ответе я привёл два похожих варианта:
1. **Неформальная функция с разделителем**
$$
\text{fun}(\text{in1}, \text{in2}; \text{out1}, \text{out2})
$$
Это просто **обозначение**, принятое в некоторых инженерных или алгоритмических текстах: точка с запятой визуально отделяет входные переменные от выходных. Математически такая запись не является стандартной сигнатурой функции — это скорее мнемоническое соглашение.
2. **Отношение**
$$
R(\text{in1}, \text{in2}; \text{out1}, \text{out2})
$$
Здесь $R$ — это **бинарное отношение** между кортежами входов и кортежами выходов. Если для каждого набора входов существует **ровно один** набор выходов, то такое отношение эквивалентно функции. Однако в математике отношение — более общее понятие (может допускать несколько выходов для одних входов). Запись с точкой с запятой в данном случае показывает, что переменные слева — это аргументы, справа — значения.
**Главное отличие**:
- В (1) мы просто **обозначаем функцию**, но не уточняем её природу.
- В (2) мы явно говорим, что имеем дело с **отношением**, что строже, но для детерминированной функции избыточно.
Если ваша функция детерминирована и всегда возвращает ровно два массива, то разница лишь в уровне строгости. На практике для описания алгоритмов чаще используют (1) как краткую запись.
---
## 2. Лучший вариант, когда `in1` отображается в `out1`, а `in2` — в `out2` (упорядоченная коллекция)
Если подразумевается, что функция работает **покомпонентно** (первый вход соответствует первому выходу, второй — второму) и при этом сохраняется структура, то лучше использовать **явное указание компонент отображения**. Есть несколько способов сделать это математически корректно и наглядно.
### Способ А: Прямое произведение функций
Записать, что функция $F$ является парой независимых функций $F_1$ и $F_2$:
$$
F: A_1 \times A_2 \;\longrightarrow\; B_1 \times B_2
$$
$$
F(\text{in1}, \text{in2}) = \bigl( f_1(\text{in1}),\; f_2(\text{in2}) \bigr)
$$
где $f_1: A_1 \to B_1$, $f_2: A_2 \to B_2$.
Это самый математически строгий вариант. Он чётко показывает, что первый выход зависит только от первого входа, а второй — только от второго.
### Способ Б: Запись с индексами
Если функция не обязательно распадается на независимые подфункции, но результат сохраняет порядок (первый выход соответствует первому входу, но может зависеть от обоих входов), то можно явно указать:
$$
F(\text{in1}, \text{in2}) = (\text{out1}, \text{out2})
$$
с дополнительным условием:
*«Здесь out1 — результат, ассоциированный с in1; out2 — результат, ассоциированный с in2»*.
В тексте это можно подчеркнуть словами или введя обозначение $F = (F_1, F_2)$.
### Способ В: Использование кортежей и проекций
Можно определить функцию через проекции:
$$
\text{out1} = \pi_1\bigl( F(\text{in1}, \text{in2}) \bigr), \quad
\text{out2} = \pi_2\bigl( F(\text{in1}, \text{in2}) \bigr)
$$
где $\pi_i$ — проекция на $i$-ю компоненту. Это показывает, что выходы упорядочены.
---
## 3. Примеры для наглядности
### Пример 1 (независимые преобразования)
Пусть $in1$ — массив чисел, $in2$ — массив строк. Функция сортирует массив чисел и переводит строки в верхний регистр.
Математическая запись:
$$
\text{process}: \mathbb{R}^n \times \Sigma^* \;\longrightarrow\; \mathbb{R}^n \times \Sigma^*
$$
$$
\text{process}(X, S) = \bigl( \text{sort}(X),\; \text{toUpper}(S) \bigr)
$$
Здесь $out1$ зависит только от $in1$, $out2$ — только от $in2$.
### Пример 2 (связанные преобразования)
Пусть $in1$ и $in2$ — два массива одинаковой длины, функция возвращает их сумму и разность.
Запись с сохранением порядка:
$$
F(X, Y) = (X + Y,\; X - Y)
$$
Здесь $out1$ соответствует паре $(in1, in2)$, $out2$ тоже соответствует паре, но чётко указано, что первый выход — сумма, второй — разность.
---
## 4. Рекомендуемый вариант для вашего случая
Если вы хотите подчеркнуть, что **первый вход отображается в первый выход, а второй вход — во второй выход** (и при этом результаты могут зависеть от обоих входов, но ассоциация сохраняется), то лучше всего использовать **явное определение компонент**:
$$
F(\text{in1}, \text{in2}) = \bigl( \text{out1}(\text{in1}, \text{in2}),\; \text{out2}(\text{in1}, \text{in2}) \bigr)
$$
Если же связь **покомпонентная и независимая** (out1 зависит только от in1, out2 — только от in2), то более строго:
$$
F(\text{in1}, \text{in2}) = \bigl( f_1(\text{in1}),\; f_2(\text{in2}) \bigr)
$$
Для краткости в тексте можно также использовать разделитель `;`, но обязательно пояснить, что он отделяет входы от выходов, а порядок сохраняется:
$$
\text{fun}(\text{in1}, \text{in2}; \text{out1}, \text{out2}) \quad\text{с условием, что out1 соответствует in1, out2 — in2}.
$$
---
## 5. Итоговая рекомендация (для GitHub, только $ и $$)
На GitHub используйте дисплейные формулы для наглядности:
```markdown
$$
F(\text{in1}, \text{in2}) = \bigl( \text{out1}(\text{in1}, \text{in2}),\; \text{out2}(\text{in1}, \text{in2}) \bigr)
$$
```
Или если требуется именно запись с точкой с запятой:
```markdown
$$
\text{fun}(\text{in1}, \text{in2}; \text{out1}, \text{out2})
$$
*где out1 — результат, соответствующий in1, out2 — результат, соответствующий in2.*
```
Оба варианта корректно отображаются и не требуют сложных пакетов.
## 6 tensor
В тензорной алгебре массивы интерпретируются как тензоры определённого ранга. Если функция преобразует два входных тензора в два выходных, причём первый вход соответствует первому выходу, а второй — второму, это можно выразить через **прямую сумму отображений** или через **тензорные операторы**, действующие на пару тензоров. Ниже приведены основные варианты записи в зависимости от того, являются ли преобразования независимыми или связанными.
---
## 1. Независимые линейные преобразования (прямое произведение)
Если $\text{in}_1$ и $\text{out}_1$ — тензоры одного типа, а $\text{in}_2$ и $\text{out}_2$ — другого, и преобразования линейны, то можно записать как **прямую сумму (блочно-диагональный) оператор**:
Пусть
$\mathsf{T}_1: \mathcal{T}^{(p,q)} \to \mathcal{T}^{(r,s)}$ — оператор, преобразующий $\text{in}_1$ в $\text{out}_1$
$\mathsf{T}_2: \mathcal{U}^{(p',q')} \to \mathcal{U}^{(r',s')}$ — оператор, преобразующий $\text{in}_2$ в $\text{out}_2$
Тогда комбинированное отображение:
$$
\mathsf{T} = \mathsf{T}_1 \oplus \mathsf{T}_2 : \mathcal{T}^{(p,q)} \times \mathcal{U}^{(p',q')} \longrightarrow \mathcal{T}^{(r,s)} \times \mathcal{U}^{(r',s')}
$$
$$
\mathsf{T}(\text{in}_1, \text{in}_2) = \bigl( \mathsf{T}_1(\text{in}_1),\; \mathsf{T}_2(\text{in}_2) \bigr).
$$
Здесь $\oplus$ обозначает **прямую сумму операторов** (блочную диагональ).
---
## 2. Общий (возможно, нелинейный) независимый случай
Если преобразования могут быть нелинейными, но сохраняется независимость, используется **декартово произведение отображений**:
$$
F = f_1 \times f_2, \quad F(\text{in}_1, \text{in}_2) = \bigl( f_1(\text{in}_1),\, f_2(\text{in}_2) \bigr).
$$
В тензорной нотации это можно записать как:
$$
(\text{out}_1)^{\alpha\ldots}_{\beta\ldots} = \mathcal{F}_1^{\alpha\ldots}_{\beta\ldots}(\text{in}_1),\qquad
(\text{out}_2)^{\mu\ldots}_{\nu\ldots} = \mathcal{F}_2^{\mu\ldots}_{\nu\ldots}(\text{in}_2).
$$
---
## 3. Связанное преобразование (выход зависит от обоих входов, но сохраняется ассоциация)
Здесь первый выход может зависеть от обоих входов, но по смыслу он «привязан» к первому входу. Один из способов — ввести **тензорный оператор** $\mathcal{M}$, который действует на пару входов и выдаёт пару выходов, а затем спроецировать:
Пусть $\mathcal{M}$ — оператор (линейный или нелинейный), отображающий $\text{in}_1 \otimes \text{in}_2$ (или пару) в $\text{out}_1 \otimes \text{out}_2$
Тогда:
$$
(\text{out}_1, \text{out}_2) = \mathcal{M}(\text{in}_1, \text{in}_2) \quad\text{или}\quad
\text{out}_1 \otimes \text{out}_2 = \mathcal{M}(\text{in}_1 \otimes \text{in}_2).
$$
Чтобы явно выделить первый и второй выход, используют **проекторы** $\pi_1$ и $\pi_2$:
$$
\text{out}_1 = \pi_1\!\left( \mathcal{M}(\text{in}_1, \text{in}_2) \right),\qquad
\text{out}_2 = \pi_2\!\left( \mathcal{M}(\text{in}_1, \text{in}_2) \right).
$$
В компонентной записи (например, для тензоров второго ранга):
$$
(\text{out}_1)^{ij} = M^{ij}_{\;klpq} (\text{in}_1)^{kl} (\text{in}_2)^{pq} + \dots
$$
$$
(\text{out}_2)^{rs} = N^{rs}_{\;klpq} (\text{in}_1)^{kl} (\text{in}_2)^{pq} + \dots
$$
где $M$ и $N$ — тензоры операторов, задающие преобразование.
---
## 4. Использование прямого произведения пространств и тензорного оператора
Можно рассматривать объединённое пространство входов $V = V_1 \oplus V_2$ и выходов $W = W_1 \oplus W_2$. Тогда любое линейное отображение $L: V \to W$ можно представить в виде блочной матрицы:
$$
L = \begin{pmatrix}
A & B \\
C & D
\end{pmatrix},
$$
где:
- $A: V_1 \to W_1$ — отображение $\text{in}_1$ в $\text{out}_1$,
- $B: V_2 \to W_1$ — влияние $\text{in}_2$ на $\text{out}_1$,
- $C: V_1 \to W_2$ — влияние $\text{in}_1$ на $\text{out}_2$,
- $D: V_2 \to W_2$ — отображение $\text{in}_2$ в $\text{out}_2$.
Если требуется, чтобы первый выход ассоциировался с первым входом (но мог зависеть от второго), то $A$ и $B$ ненулевые, $C$ — нулевой (чтобы второй выход не зависел от первого). Если же оба выхода могут зависеть от обоих входов, то ненулевыми могут быть все блоки. Запись:
```
$$
\begin{pmatrix}
\text{out}_1 \\
\text{out}_2
\end{pmatrix}
=
\begin{pmatrix}
A & B \\
C & D
\end{pmatrix}
\begin{pmatrix}
\text{in}_1 \\
\text{in}_2
\end{pmatrix}.
$$
```
В нелинейном случае вместо матрицы — нелинейный оператор.
---
## 5. Тензорная сеть / диаграммная нотация
В тензорной алгебре часто используют графические диаграммы (тензорные сети). Для пары входов и пары выходов можно изобразить:
- Если преобразования независимы: две отдельные диаграммы (два «чёрных ящика»), каждая соединяет свой вход со своим выходом.
- Если преобразования связаны: входные тензоры подводятся к общему узлу (оператору), который выдаёт два выходных тензора.
Формульно это можно записать как:
$$
\text{out}_1 = \mathcal{O}_1(\text{in}_1, \text{in}_2),\qquad
\text{out}_2 = \mathcal{O}_2(\text{in}_1, \text{in}_2),
$$
где $\mathcal{O}_1$ и $\mathcal{O}_2$ — некоторые тензорные операторы.
---
## 6. Примеры конкретных операторов
### Пример А (свёртка с ядром)
Пусть $\text{in}_1$ — матрица $X_{ij}$, $\text{out}_1$ — матрица $Y_{kl}$, а $\text{in}_2$ — вектор $u_m$, $\text{out}_2$ — скаляр $v$. Связанное преобразование:
$$
Y_{kl} = \sum_{i,j,m} K^{(1)}_{klijm} X_{ij} u_m,\qquad
v = \sum_{i,j,m} K^{(2)}_{mij} X_{ij} u_m,
$$
где $K^{(1)}$ и $K^{(2)}$ — тензоры ядер.
### Пример Б (прямое произведение как частный случай)
Если $C=0$ и $B=0$ в блочной матрице, то:
$$
\text{out}_1 = A(\text{in}_1),\qquad
\text{out}_2 = D(\text{in}_2),
$$
что возвращает нас к независимому случаю.
---
## 7. Итоговая рекомендация для записи на GitHub (только $ и $$)
Для строгой тензорной записи с сохранением ассоциации «первый вход → первый выход» можно использовать:
```markdown
$$
\begin{pmatrix} \text{out}_1 \\ \text{out}_2 \end{pmatrix}
=
\begin{pmatrix} \mathcal{A} & \mathcal{B} \\ \mathcal{C} & \mathcal{D} \end{pmatrix}
\begin{pmatrix} \text{in}_1 \\ \text{in}_2 \end{pmatrix},
$$
```
где $\mathcal{A}, \mathcal{B}, \mathcal{C}, \mathcal{D}$ — тензорные операторы. Если $\mathcal{C}=0$, то второй выход не зависит от первого входа.
Для нелинейного случая:
```markdown
$$
(\text{out}_1)^{\alpha\ldots}_{\beta\ldots} = \mathcal{F}_1^{\alpha\ldots}_{\beta\ldots}(\text{in}_1, \text{in}_2),\qquad
(\text{out}_2)^{\mu\ldots}_{\nu\ldots} = \mathcal{F}_2^{\mu\ldots}_{\nu\ldots}(\text{in}_1, \text{in}_2).
$$
```
Если требуется подчеркнуть независимость:
```markdown
$$
F = f_1 \times f_2,\qquad
F(\text{in}_1, \text{in}_2) = \bigl( f_1(\text{in}_1),\, f_2(\text{in}_2) \bigr).
$$
```
Все варианты корректно отображаются на GitHub и используют только стандартную математическую нотацию.
## 7
после "В тензорной нотации это можно записать как:"
пишет Double subscripts: use braces to clarify
Вы правы, в LaTeX (и на GitHub через MathJax) конструкция вида `\text{out}_1^{\alpha\ldots}_{\beta\ldots}` может вызвать ошибку «Double subscripts», если интерпретатор пытается одновременно обработать нижний индекс `_1` и последующие нижние индексы. Нужно явно группировать индексы с помощью фигурных скобок.
Ниже привожу исправленные варианты записи в тензорной алгебре, которые корректно работают на GitHub. Использую только `$` и `$$`.
---
## 1. Независимые преобразования (прямое произведение)
$$
F = f_1 \times f_2,\qquad F(\text{in}_1, \text{in}_2) = \bigl( f_1(\text{in}_1),\, f_2(\text{in}_2) \bigr).
$$
В компонентной форме (тензорная нотация с правильной группировкой индексов):
$$
(\text{out}_1)^{\alpha_1\ldots\alpha_r}_{\beta_1\ldots\beta_s} = \mathcal{F}_1^{\alpha_1\ldots\alpha_r}_{\beta_1\ldots\beta_s}\bigl( (\text{in}_1)^{\mu_1\ldots\mu_p}_{\nu_1\ldots\nu_q} \bigr),
$$
$$
(\text{out}_2)^{\gamma_1\ldots\gamma_t}_{\delta_1\ldots\delta_u} = \mathcal{F}_2^{\gamma_1\ldots\gamma_t}_{\delta_1\ldots\delta_u}\bigl( (\text{in}_2)^{\xi_1\ldots\xi_a}_{\eta_1\ldots\eta_b} \bigr).
$$
Здесь каждый оператор $\mathcal{F}_1$, $\mathcal{F}_2$ действует только на свой вход.
---
## 2. Связанное преобразование (выходы зависят от обоих входов)
Общая форма:
$$
(\text{out}_1)^{\alpha_1\ldots\alpha_r}_{\beta_1\ldots\beta_s} = \mathcal{O}_1^{\alpha_1\ldots\alpha_r}_{\beta_1\ldots\beta_s}\bigl( (\text{in}_1)^{\mu_1\ldots\mu_p}_{\nu_1\ldots\nu_q},\; (\text{in}_2)^{\xi_1\ldots\xi_a}_{\eta_1\ldots\eta_b} \bigr),
$$
$$
(\text{out}_2)^{\gamma_1\ldots\gamma_t}_{\delta_1\ldots\delta_u} = \mathcal{O}_2^{\gamma_1\ldots\gamma_t}_{\delta_1\ldots\delta_u}\bigl( (\text{in}_1)^{\mu_1\ldots\mu_p}_{\nu_1\ldots\nu_q},\; (\text{in}_2)^{\xi_1\ldots\xi_a}_{\eta_1\ldots\eta_b} \bigr).
$$
---
## 3. Линейное преобразование в виде блочной матрицы (тензорная версия)
Если преобразование линейно и пространства имеют тензорную структуру, можно записать в виде свёртки с тензором четвёртого ранга (для каждой пары). Например, для простых векторов (ранг 1):
$$
(\text{out}_1)^i = \sum_{j} A^i_{\,j} (\text{in}_1)^j + \sum_{k} B^i_{\,k} (\text{in}_2)^k,
$$
$$
(\text{out}_2)^\ell = \sum_{m} C^\ell_{\,m} (\text{in}_1)^m + \sum_{n} D^\ell_{\,n} (\text{in}_2)^n.
$$
Здесь $A$, $B$, $C$, $D$ — матрицы (тензоры второго ранга), задающие отображение.
В более компактной блочной форме:
```
$$
\begin{pmatrix}
(\text{out}_1)^i \\[2pt]
(\text{out}_2)^\ell
\end{pmatrix}
=
\begin{pmatrix}
A^i_{\,j} & B^i_{\,k} \\[2pt]
C^\ell_{\,m} & D^\ell_{\,n}
\end{pmatrix}
\ast
\begin{pmatrix}
(\text{in}_1)^j \\[2pt]
(\text{in}_2)^k
\end{pmatrix},
$$
```
где $\ast$ означает свёртку по соответствующим индексам.
---
## 4. Тензорная сеть (диаграммная нотация текстом)
Если требуется только описать структуру без конкретных индексов, можно использовать символы:
$$
\text{out}_1 = \mathcal{M}_1 \bigl( \text{in}_1 \otimes \text{in}_2 \bigr),\qquad
\text{out}_2 = \mathcal{M}_2 \bigl( \text{in}_1 \otimes \text{in}_2 \bigr),
$$
где $\mathcal{M}_1$ и $\mathcal{M}_2$ — тензорные операторы, возможно, получаемые проекцией из общего оператора $\mathcal{M}$:
$$
\mathcal{M}: \text{in}_1 \otimes \text{in}_2 \longrightarrow \text{out}_1 \otimes \text{out}_2,
$$
$$
\text{out}_1 = \pi_1\!\left( \mathcal{M}(\text{in}_1 \otimes \text{in}_2) \right),\quad
\text{out}_2 = \pi_2\!\left( \mathcal{M}(\text{in}_1 \otimes \text{in}_2) \right).
$$
---
## 5. Почему важно использовать фигурные скобки
В LaTeX нижний индекс (или верхний) относится к предыдущему «атомарному» символу. Если вы пишете `\text{out}_1^{\alpha}` — это нормально. Но если после `_1` идёт ещё один нижний индекс, например `\text{out}_1^{\alpha}_{\beta}`, интерпретатор может воспринять это как попытку поставить два нижних индекса к одному символу, что и вызывает ошибку. Правильно:
- Группировать всё, что относится к индексам: `\text{out}_1^{\alpha}_{\beta}``{\text{out}_1}^{\alpha}_{\beta}` или `\text{out}_1^{\alpha}{}_{\beta}` (если нужно смещение).
- Либо использовать `\text{out}_{1}^{\alpha\beta}` для нескольких верхних индексов.
Для тензорных записей с несколькими индексами удобнее задать один символ для тензора и затем перечислить все индексы в одной группе:
```latex
{\text{out}_1}^{\alpha_1\ldots\alpha_r}_{\beta_1\ldots\beta_s}
```
Или, если тензор имеет фиксированное имя, просто:
```latex
T^{\alpha_1\ldots\alpha_r}_{\beta_1\ldots\beta_s}
```
---
## 6. Пример полностью корректной записи для GitHub
```markdown
$$
{\text{out}_1}^{\alpha_1\ldots\alpha_r}_{\beta_1\ldots\beta_s} =
\mathcal{F}_1^{\alpha_1\ldots\alpha_r}_{\beta_1\ldots\beta_s}
\bigl( {\text{in}_1}^{\mu_1\ldots\mu_p}_{\nu_1\ldots\nu_q} \bigr),
\qquad
{\text{out}_2}^{\gamma_1\ldots\gamma_t}_{\delta_1\ldots\delta_u} =
\mathcal{F}_2^{\gamma_1\ldots\gamma_t}_{\delta_1\ldots\delta_u}
\bigl( {\text{in}_2}^{\xi_1\ldots\xi_a}_{\eta_1\ldots\eta_b} \bigr).
$$
```
Все индексы сгруппированы, двойных подстрочников нет, формула корректно отображается.
---
Если вам нужен самый простой вариант, сохраняющий идею «первый вход → первый выход, второй вход → второй выход», рекомендую использовать блочную матричную запись (п. 3) или прямое произведение отображений (п. 1). Оба варианта легко читаются и не вызывают проблем с индексами.