Spec-Zone.ru › Eigen3

Быстрое справочное руководство


Модули и заголовочные файлы

Библиотека Eigen разделена на основной модуль и несколько дополнительных модулей. Каждый модуль имеет соответствующий заголовочный файл, который необходимо включить для использования модуля. Заголовочные файлы Dense и Eigen предоставляются для удобного доступа к нескольким модулям сразу.

Модуль Заголовочный файл Содержимое
Основной
#include <Eigen/Core>
Классы Matrix и Array, основные операции линейной алгебры (включая треугольные и самосопряженные произведения), манипуляции с массивами
Геометрия
#include <Eigen/Geometry>
Transform, Translation, Масштабирование, Rotation2D и 3D вращения (Quaternion, AngleAxis)
LU
#include <Eigen/LU>
Inverse, определитель, LU-разложения с решением (FullPivLU, PartialPivLU)
Холецкого
#include <Eigen/Cholesky>
LLT и LDLT факторизация Холецкого с решением
Хаусхолдера
#include <Eigen/Householder>
Преобразования Хаусхолдера; этот модуль используется несколькими модулями линейной алгебры
SVD
#include <Eigen/SVD>
SVD-разложения с решением наименьших квадратов (JacobiSVD, BDCSVD)
QR
#include <Eigen/QR>
QR-разложение с решением (HouseholderQR, ColPivHouseholderQR, FullPivHouseholderQR)
Собственные значения
#include <Eigen/Eigenvalues>
Разложения собственных значений, собственных векторов (EigenSolver, SelfAdjointEigenSolver, ComplexEigenSolver)
Разреженный
#include <Eigen/Sparse>
Хранение разреженных матриц и связанные основные операции линейной алгебры (SparseMatrix, SparseVector)
(см. Быстрое справочное руководство по разреженным матрицам для получения подробной информации о разреженных модулях)
#include <Eigen/Dense>
Включает заголовочные файлы Core, Geometry, LU, Cholesky, SVD, QR и Eigenvalues
#include <Eigen/Eigen>
Включает заголовочные файлы Dense и Sparse (вся библиотека Eigen)

Типы массивов, матриц и векторов

Обратите внимание: Библиотека Eigen предоставляет два типа плотных объектов: математические матрицы и векторы, которые оба представлены шаблоном класса Matrix, и общие 1D и 2D массивы, представленные шаблоном класса Array:

typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, Options> MyMatrixType;
typedef Array<Scalar, RowsAtCompileTime, ColsAtCompileTime, Options> MyArrayType;
  • Scalar — тип скаляра коэффициентов (например, float, double, bool, int, и т.д.).
  • RowsAtCompileTime и ColsAtCompileTime — количество строк и столбцов матрицы, известное на этапе компиляции, или Dynamic.
  • Options может быть ColMajor или RowMajor, по умолчанию ColMajor. (см. класс Matrix для получения дополнительной информации)

Разрешены все комбинации: вы можете иметь матрицу с фиксированным числом строк и динамическим числом столбцов и т. д. Следующие варианты допустимы:

Matrix<double, 6, Dynamic>                  // Dynamic number of columns (heap allocation)
Matrix<double, Dynamic, 2>                  // Dynamic number of rows (heap allocation)
Matrix<double, Dynamic, Dynamic, RowMajor>  // Fully dynamic, row major (heap allocation)
Matrix<double, 13, 3>                       // Fully fixed (usually allocated on stack)

В большинстве случаев вы можете просто использовать один из удобных псевдонимов типов для матриц и массивов. Некоторые примеры:

Матрицы Массивы
Matrix<float,Dynamic,Dynamic>   <=>   MatrixXf
Matrix<double,Dynamic,1>        <=>   VectorXd
Matrix<int,1,Dynamic>           <=>   RowVectorXi
Matrix<float,3,3>               <=>   Matrix3f
Matrix<float,4,1>               <=>   Vector4f
Array<float,Dynamic,Dynamic>    <=>   ArrayXXf
Array<double,Dynamic,1>         <=>   ArrayXd
Array<int,1,Dynamic>            <=>   RowArrayXi
Array<float,3,3>                <=>   Array33f
Array<float,4,1>                <=>   Array4f

Преобразование между мирами матриц и массивов:

Array44f a1, a2;
Matrix4f m1, m2;
m1 = a1 * a2;                     // coeffwise product, implicit conversion from array to matrix.
a1 = m1 * m2;                     // matrix product, implicit conversion from matrix to array.
a2 = a1 + m1.array();             // mixing array and matrix is forbidden
m2 = a1.matrix() + m1;            // and explicit conversion is required.
ArrayWrapper<Matrix4f> m1a(m1);   // m1a is an alias for m1.array(), they share the same coefficients
MatrixWrapper<Array44f> a1m(a1);

В остальной части этого документа мы будем использовать следующие символы, чтобы подчеркнуть особенности, характерные для данного типа объекта:

  • * только матрицы и векторы линейной алгебры
  • * только объекты массивов

Базовые манипуляции с матрицами

1D объекты 2D объекты Примечания
Конструкторы
Vector4d  v4;
Vector2f  v1(x, y);
Array3i   v2(x, y, z);
Vector4d  v3(x, y, z, w);
 
VectorXf  v5; // empty object
ArrayXf   v6(size);
Matrix4f  m1;
 
 
 
 
MatrixXf  m5; // empty object
MatrixXf  m6(nb_rows, nb_columns);
По умолчанию коэффициенты не инициализированы
Инициализатор запятыми
Vector3f  v1;     v1 << x, y, z;
ArrayXf   v2(4);  v2 << 1, 2, 3, 4;
Matrix3f  m1;   m1 << 1, 2, 3,
                      4, 5, 6,
                      7, 8, 9;

Инициализатор запятыми (часть 2)
int rows=5, cols=5;
MatrixXf m(rows,cols);
m << (Matrix3f() << 1, 2, 3, 4, 5, 6, 7, 8, 9).finished(),
     MatrixXf::Zero(3,cols-3),
     MatrixXf::Zero(rows-3,3),
     MatrixXf::Identity(rows-3,cols-3);
cout << m;

Вывод:

1 2 3 0 0
4 5 6 0 0
7 8 9 0 0
0 0 0 1 0
0 0 0 0 1

Информация о времени выполнения
vector.size();
 
vector.innerStride();
vector.data();
matrix.rows();          matrix.cols();
matrix.innerSize();     matrix.outerSize();
matrix.innerStride();   matrix.outerStride();
matrix.data();
Внутренний/Внешний* зависят от порядка хранения
Информация о времени компиляции
ObjectType::Scalar              ObjectType::RowsAtCompileTime
ObjectType::RealScalar          ObjectType::ColsAtCompileTime
ObjectType::Index               ObjectType::SizeAtCompileTime
Изменение размера
vector.resize(size);
 
 
vector.resizeLike(other_vector);
vector.conservativeResize(size);
matrix.resize(nb_rows, nb_cols);
matrix.resize(Eigen::NoChange, nb_cols);
matrix.resize(nb_rows, Eigen::NoChange);
matrix.resizeLike(other_matrix);
matrix.conservativeResize(nb_rows, nb_cols);

безоперационное действие, если новые размеры совпадают, иначе данные теряются

изменение размера с сохранением данных

Доступ к коэффициентам с проверкой диапазона
vector(i)     vector.x()
vector[i]     vector.y()
              vector.z()
              vector.w()
matrix(i,j)

Проверка диапазона отключена, если определены NDEBUG или EIGEN_NO_DEBUG

Доступ к коэффициентам без проверки диапазона
vector.coeff(i)
vector.coeffRef(i)
matrix.coeff(i,j)
matrix.coeffRef(i,j)

Присваивание/копирование
object = expression;
object_of_float = expression_of_double.cast<float>();

назначение автоматически изменяет размер назначения (если возможно)

Предопределённые матрицы

Матрица или вектор фиксированного размера Матрица динамического размера Вектор динамического размера
typedef {Matrix3f|Array33f} FixedXD;
FixedXD x;
 
x = FixedXD::Zero();
x = FixedXD::Ones();
x = FixedXD::Constant(value);
x = FixedXD::Random();
x = FixedXD::LinSpaced(size, low, high);
 
x.setZero();
x.setOnes();
x.setConstant(value);
x.setRandom();
x.setLinSpaced(size, low, high);
typedef {MatrixXf|ArrayXXf} Dynamic2D;
Dynamic2D x;
 
x = Dynamic2D::Zero(rows, cols);
x = Dynamic2D::Ones(rows, cols);
x = Dynamic2D::Constant(rows, cols, value);
x = Dynamic2D::Random(rows, cols);
N/A
 
x.setZero(rows, cols);
x.setOnes(rows, cols);
x.setConstant(rows, cols, value);
x.setRandom(rows, cols);
N/A
typedef {VectorXf|ArrayXf} Dynamic1D;
Dynamic1D x;
 
x = Dynamic1D::Zero(size);
x = Dynamic1D::Ones(size);
x = Dynamic1D::Constant(size, value);
x = Dynamic1D::Random(size);
x = Dynamic1D::LinSpaced(size, low, high);
 
x.setZero(size);
x.setOnes(size);
x.setConstant(size, value);
x.setRandom(size);
x.setLinSpaced(size, low, high);

Единичная и базисные векторы *
x = FixedXD::Identity();
x.setIdentity();
 
Vector3f::UnitX() // 1 0 0
Vector3f::UnitY() // 0 1 0
Vector3f::UnitZ() // 0 0 1
Vector4f::Unit(i)
x.setUnit(i);
x = Dynamic2D::Identity(rows, cols);
x.setIdentity(rows, cols);
 
 
 
N/A
N/A
 
 
VectorXf::Unit(size,i)
x.setUnit(size,i);
VectorXf::Unit(4,1) == Vector4f(0,1,0,0)
                    == Vector4f::UnitY()

Обратите внимание, что разрешено вызывать любую из функций set* для вектора или матрицы динамического размера без передачи новых размеров. Например:

MatrixXi M(3,3);
M.setIdentity();

Картирование внешних массивов

Непрерывное
хранилище памяти
float data[] = {1,2,3,4};
Map<Vector3f> v1(data);       // uses v1 as a Vector3f object
Map<ArrayXf>  v2(data,3);     // uses v2 as a ArrayXf object
Map<Array22f> m1(data);       // uses m1 as a Array22f object
Map<MatrixXf> m2(data,2,2);   // uses m2 as a MatrixXf object
Типичное использование
шагов
float data[] = {1,2,3,4,5,6,7,8,9};
Map<VectorXf,0,InnerStride<2> >  v1(data,3);                      // = [1,3,5]
Map<VectorXf,0,InnerStride<> >   v2(data,3,InnerStride<>(3));     // = [1,4,7]
Map<MatrixXf,0,OuterStride<3> >  m2(data,2,3);                    // both lines     |1,4,7|
Map<MatrixXf,0,OuterStride<> >   m1(data,2,3,OuterStride<>(3));   // are equal to:  |2,5,8|

Арифметические операторы

Сложение
Вычитание
mat3 = mat1 + mat2;           mat3 += mat1;
mat3 = mat1 - mat2;           mat3 -= mat1;
Произведение скаляра
mat3 = mat1 * s1;             mat3 *= s1;           mat3 = s1 * mat1;
mat3 = mat1 / s1;             mat3 /= s1;
Произведение матрицы/вектора *
col2 = mat1 * col1;
row2 = row1 * mat1;           row1 *= mat1;
mat3 = mat1 * mat2;           mat3 *= mat1; 
Транспонирование
сопряжение *
mat1 = mat2.transpose();      mat1.transposeInPlace();
mat1 = mat2.adjoint();        mat1.adjointInPlace();
Точечное произведение
внутреннее произведение *
scalar = vec1.dot(vec2);
scalar = col1.adjoint() * col2;
scalar = (col1.adjoint() * col2).value();
ВнЕшнЕЕ произведение *
mat = col1 * col2.transpose();

Норма
Нормализация *
scalar = vec1.norm();         scalar = vec1.squaredNorm()
vec2 = vec1.normalized();     vec1.normalize(); // inplace 

Векторное произведение *
#include <Eigen/Geometry>
vec3 = vec1.cross(vec2);

Операции по коэффициентам & массивы

Помимо вышеупомянутых операторов, Eigen поддерживает множество операторов и функций поэлементного применения. Большинство из них однозначно интерпретируются в мире массивов*. Следующие операторы доступны для массивов, или доступны через .array() для векторов и матриц:

Арифметические операторы
array1 * array2     array1 / array2     array1 *= array2    array1 /= array2
array1 + scalar     array1 - scalar     array1 += scalar    array1 -= scalar
Сравнения
array1 < array2     array1 > array2     array1 < scalar     array1 > scalar
array1 <= array2    array1 >= array2    array1 <= scalar    array1 >= scalar
array1 == array2    array1 != array2    array1 == scalar    array1 != scalar
array1.min(array2)  array1.max(array2)  array1.min(scalar)  array1.max(scalar)
Тригонометрические, степенные и
смешанные функции
и аналоги STL
array1.abs2()
array1.abs()                  abs(array1)
array1.sqrt()                 sqrt(array1)
array1.log()                  log(array1)
array1.log10()                log10(array1)
array1.exp()                  exp(array1)
array1.pow(array2)            pow(array1,array2)
array1.pow(scalar)            pow(array1,scalar)
                              pow(scalar,array2)
array1.square()
array1.cube()
array1.inverse()
 
array1.sin()                  sin(array1)
array1.cos()                  cos(array1)
array1.tan()                  tan(array1)
array1.asin()                 asin(array1)
array1.acos()                 acos(array1)
array1.atan()                 atan(array1)
array1.sinh()                 sinh(array1)
array1.cosh()                 cosh(array1)
array1.tanh()                 tanh(array1)
array1.arg()                  arg(array1)
 
array1.floor()                floor(array1)
array1.ceil()                 ceil(array1)
array1.round()                round(aray1)
 
array1.isFinite()             isfinite(array1)
array1.isInf()                isinf(array1)
array1.isNaN()                isnan(array1)

Следующие операторы поэлементного применения доступны для всех типов выражений (матрицы, векторы и массивы), а также для вещественных и комплексных типов скаляров:

Eigen's API API в стиле STL* Комментарии
mat1.real()
mat1.imag()
mat1.conjugate()
real(array1)
imag(array1)
conj(array1)
// read-write, no-op for real expressions
// read-only for real, read-write for complexes
// no-op for real expressions

Некоторые операторы поэлементного применения доступны для матриц и векторов через следующие методы cwise*:

Матрица API * Через преобразования в Массив
mat1.cwiseMin(mat2)         mat1.cwiseMin(scalar)
mat1.cwiseMax(mat2)         mat1.cwiseMax(scalar)
mat1.cwiseAbs2()
mat1.cwiseAbs()
mat1.cwiseSqrt()
mat1.cwiseInverse()
mat1.cwiseProduct(mat2)
mat1.cwiseQuotient(mat2)
mat1.cwiseEqual(mat2)       mat1.cwiseEqual(scalar)
mat1.cwiseNotEqual(mat2)
mat1.array().min(mat2.array())    mat1.array().min(scalar)
mat1.array().max(mat2.array())    mat1.array().max(scalar)
mat1.array().abs2()
mat1.array().abs()
mat1.array().sqrt()
mat1.array().inverse()
mat1.array() * mat2.array()
mat1.array() / mat2.array()
mat1.array() == mat2.array()      mat1.array() == scalar
mat1.array() != mat2.array()

Основное различие между двумя API заключается в том, что API, основанное на методах cwise*, возвращает выражение в мире матриц, в то время как второе API (основанное на .array()) возвращает выражение массива. Обратите внимание, что .array() не имеет затрат, оно только изменяет доступное API и интерпретацию данных.

Также очень просто применить любую пользовательскую функцию foo с помощью DenseBase::unaryExpr вместе с std::ptr_fun (c++03, устарело или удалено в более новых версиях C++), std::ref (c++11) или лямбда-выражениями (c++11):

mat1.unaryExpr(std::ptr_fun(foo));
mat1.unaryExpr(std::ref(foo));
mat1.unaryExpr([](double x) { return foo(x); });

Обратите внимание, что передать указатель на обычную функцию напрямую в unaryExpr нельзя, поэтому её необходимо обернуть, как показано выше.

Сводные операции

Eigen предоставляет несколько методов сводки, таких как: minCoeff() , maxCoeff() , sum() , prod() , trace() *, norm() *, squaredNorm() *, all() и any() . Все операции сводки могут быть выполнены по матрице, столбцу или строке . Пример использования:

      5 3 1
mat = 2 7 8
      9 4 6 
mat.minCoeff(); 
1 
mat.colwise().minCoeff(); 
2 3 1 
mat.rowwise().minCoeff(); 
1
2
4

Специальные версии minCoeff и maxCoeff :

int i, j;
s = vector.minCoeff(&i);        // s == vector[i]
s = matrix.maxCoeff(&i, &j);    // s == matrix(i,j)

Типичные случаи использования all() и any():

if((array1 > 0).all()) ...      // if all coefficients of array1 are greater than 0 ...
if((array1 < array2).any()) ... // if there exist a pair i,j such that array1(i,j) < array2(i,j) ...

Подматрицы

ПОЖАЛУЙСТА, ПОМОГИТЕ НАМ УЛУЧШИТЬ ЭТОТ РАЗДЕЛ. Eigen 3.4 поддерживает значительно улучшенный API для подматриц, включая срез и индексирование массивов: Срезы и индексирование

Чтение и запись столбца или строки матрицы (или массива):

mat1.row(i) = mat2.col(j);
mat1.col(j1).swap(mat1.col(j2));

Чтение и запись подвекторов:

Стандартные версии Оптимизированные версии, когда размер
известен на этапе компиляции

vec1.head(n)
vec1.head<n>()
первые n коэффициенты
vec1.tail(n)
vec1.tail<n>()
последние n коэффициенты
vec1.segment(pos,n)
vec1.segment<n>(pos)
коэффициенты в диапазоне
[pos : pos + n - 1]

Чтение и запись подматриц:

mat1.block(i,j,rows,cols)
(ещё)
mat1.block<rows,cols>(i,j)
(ещё)
подматрица rows x cols
начиная с позиции (i,j)
mat1.topLeftCorner(rows,cols)
mat1.topRightCorner(rows,cols)
mat1.bottomLeftCorner(rows,cols)
mat1.bottomRightCorner(rows,cols)
mat1.topLeftCorner<rows,cols>()
mat1.topRightCorner<rows,cols>()
mat1.bottomLeftCorner<rows,cols>()
mat1.bottomRightCorner<rows,cols>()
подматрица rows x cols
взятая в одном из четырёх углов
mat1.topRows(rows)
mat1.bottomRows(rows)
mat1.leftCols(cols)
mat1.rightCols(cols)
mat1.topRows<rows>()
mat1.bottomRows<rows>()
mat1.leftCols<cols>()
mat1.rightCols<cols>()
специализированные версии block()
когда блок соответствует двум углам

Разные операции

ПОЖАЛУЙСТА, ПОМОГИТЕ НАМ УЛУЧШИТЬ ЭТОТ РАЗДЕЛ. Eigen 3.4 поддерживает новый API для изменения формы: Изменение формы

Обращение

Векторы, строки и/или столбцы матрицы могут быть обращены (см. DenseBase::reverse(), DenseBase::reverseInPlace(), VectorwiseOp::reverse()).

vec.reverse()           mat.colwise().reverse()   mat.rowwise().reverse()
vec.reverseInPlace()

Дублирование

Векторы, матрицы, строки и/или столбцы могут быть продублированы в любом направлении (см. DenseBase::replicate(), VectorwiseOp::replicate())

vec.replicate(times)                                          vec.replicate<Times>
mat.replicate(vertical_times, horizontal_times)               mat.replicate<VerticalTimes, HorizontalTimes>()
mat.colwise().replicate(vertical_times, horizontal_times)     mat.colwise().replicate<VerticalTimes, HorizontalTimes>()
mat.rowwise().replicate(vertical_times, horizontal_times)     mat.rowwise().replicate<VerticalTimes, HorizontalTimes>()

Диагональные, треугольные и самосопряженные матрицы

(мир матриц *)

Диагональные матрицы

Операция Код
представление вектора в виде диагональной матрицы
mat1 = vec1.asDiagonal();
Объявление диагональной матрицы
DiagonalMatrix<Scalar,SizeAtCompileTime> diag1(size);
diag1.diagonal() = vector;
Доступ к диагонали и над/поддиагоналям матрицы как к вектору (чтение/запись)
vec1 = mat1.diagonal();        mat1.diagonal() = vec1;      // main diagonal
vec1 = mat1.diagonal(+n);      mat1.diagonal(+n) = vec1;    // n-th super diagonal
vec1 = mat1.diagonal(-n);      mat1.diagonal(-n) = vec1;    // n-th sub diagonal
vec1 = mat1.diagonal<1>();     mat1.diagonal<1>() = vec1;   // first super diagonal
vec1 = mat1.diagonal<-2>();    mat1.diagonal<-2>() = vec1;  // second sub diagonal

Оптимизированные произведения и обращение
mat3  = scalar * diag1 * mat1;
mat3 += scalar * mat1 * vec1.asDiagonal();
mat3 = vec1.asDiagonal().inverse() * mat1
mat3 = mat1 * diag1.inverse()

Треугольные представления

TriangularView предоставляет представление треугольной части плотной матрицы и позволяет выполнять оптимизированные операции с ней. Противоположная треугольная часть никогда не ссылается и может использоваться для хранения другой информации.

Примечание
Шаблонный член-функция .triangularView() требует ключевое слово template , если используется с объектом, тип которого зависит от шаблона; см. Ключевые слова template и typename в C++ для получения подробностей.
Операция Код
Ссылка на треугольную часть с необязательной
единичной или нулевой диагональю (чтение/запись):
m.triangularView<Xxx>()

Xxx = Upper, Lower, StrictlyUpper, StrictlyLower, UnitUpper, UnitLower
Запись в определённую треугольную часть:
(только указанная треугольная часть оценивается)
m1.triangularView<Eigen::Lower>() = m2 + m3 
Преобразование в плотную матрицу с обнулением противоположной треугольной части:
m2 = m1.triangularView<Eigen::UnitUpper>()
Произведения:
m3 += s1 * m1.adjoint().triangularView<Eigen::UnitUpper>() * m2
m3 -= s1 * m2.conjugate() * m1.adjoint().triangularView<Eigen::Lower>() 
Решение линейных уравнений:
\( M_2 := L_1^{-1} M_2 \)
\( M_3 := {L_1^*}^{-1} M_3 \)
\( M_4 := M_4 U_1^{-1} \)

L1.triangularView<Eigen::UnitLower>().solveInPlace(M2)
L1.triangularView<Eigen::Lower>().adjoint().solveInPlace(M3)
U1.triangularView<Eigen::Upper>().solveInPlace<OnTheRight>(M4)

Симметричные/самосопряжённые представления

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

Примечание
Шаблонный член-функция .selfadjointView() требует ключевое слово template , если используется с объектом, тип которого зависит от шаблона; см. Ключевые слова template и typename в C++ для получения подробностей.
Операция Код
Преобразование в плотную матрицу:
m2 = m.selfadjointView<Eigen::Lower>();
Произведение с другой общей матрицей или вектором:
m3  = s1 * m1.conjugate().selfadjointView<Eigen::Upper>() * m3;
m3 -= s1 * m3.adjoint() * m1.selfadjointView<Eigen::Lower>();
Обновление ранга 1 и ранга K:
\( upper(M_1) \mathrel{{+}{=}} s_1 M_2 M_2^* \)
\( lower(M_1) \mathbin{{-}{=}} M_2^* M_2 \)

M1.selfadjointView<Eigen::Upper>().rankUpdate(M2,s1);
M1.selfadjointView<Eigen::Lower>().rankUpdate(M2.adjoint(),-1); 
Обновление ранга 2: ( \( M \mathrel{{+}{=}} s u v^* + s v u^* \))
M.selfadjointView<Eigen::Upper>().rankUpdate(u,v,s);
Решение линейных уравнений:
( \( M_2 := M_1^{-1} M_2 \))
// via a standard Cholesky factorization
m2 = m1.selfadjointView<Eigen::Upper>().llt().solve(m2);
// via a Cholesky factorization with pivoting
m2 = m1.selfadjointView<Eigen::Lower>().ldlt().solve(m2);

© Eigen.
Licensed under the MPL2 License.
https://eigen.tuxfamily.org/dox/group__QuickRefPage.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API