Spec-Zone.ru › Eigen3

Утверждения

Утверждения

Макрос eigen_assert по умолчанию определяется как eigen_plain_assert. Мы используем eigen_plain_assert вместо assert, чтобы обойти известную ошибку для GCC <= 4.3. По сути, eigen_plain_assert является assert.

Переопределение утверждений

И eigen_assert, и eigen_plain_assert определены в Macros.h. Непосредственное определение eigen_assert даёт возможность изменить его поведение. Вы можете переопределить этот макрос, если хотите сделать что-то другое, например, бросить исключение, и вернуться к его поведению по умолчанию с помощью eigen_plain_assert. Приведённый ниже код сообщает Eigen, что необходимо бросить исключение std::runtime_error:

#include <stdexcept>
#undef eigen_assert
#define eigen_assert(x) \
  if (!(x)) { throw (std::runtime_error("Put your message here")); }

Отключение утверждений

Утверждения влияют на время выполнения и могут быть отключены. Вы можете подавить eigen_assert, определив EIGEN_NO_DEBUG перед включением заголовков Eigen. EIGEN_NO_DEBUG не определено по умолчанию, если не определено NDEBUG.

Статические утверждения

Статические утверждения не стандартизированы до C++11. Однако в библиотеке Eigen существует множество условий, которые можно и нужно проверять на этапе компиляции. Например, мы используем статические утверждения, чтобы предотвратить компиляцию следующего кода.

Matrix3d()  + Matrix4d();   // adding matrices of different sizes
Matrix4cd() * Vector3cd();  // invalid product known at compile time

Статические утверждения определены в StaticAssert.h. Если существует встроенный static_assert, мы используем его. В противном случае, мы реализовали макрос утверждения, который может отображать ограниченный набор сообщений.

Можно легко создать статические утверждения без сообщений, например:

#define STATIC_ASSERT(x) \
  switch(0) { case 0: case x:; }

Однако в приведенном выше примере очевидно, что невозможно понять, почему утверждение не выполнилось. Поэтому мы определяем struct в пространстве имён Eigen::internal для обработки доступных сообщений.

template<bool condition>
struct static_assertion {};
 
template<>
struct static_assertion<true>
{
  enum {
    YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX,
    YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES,
    // see StaticAssert.h for all enums.
  };
};

Затем мы определяем EIGEN_STATIC_ASSERT(CONDITION,MSG), чтобы получить доступ к Eigen::internal::static_assertion<bool(CONDITION)>::MSG. Если условие оценивается как false, ваша компилятор выведет множество сообщений, объясняющих, что в static_assert<false> нет MSG. Тем не менее, это не то, что нас интересует. Как вы можете видеть, все члены static_assert<true> — ВСЕ_БУКВЫ_В_ЗАГЛАВНЫХ_БУКВАХ_И_ОНИ_ВОПИЮТ.

Предупреждение
При использовании этого макроса MSG должен быть членом static_assertion<true>, в противном случае статическое утверждение всегда не выполняется. В настоящее время он может использоваться только в области функций.

Производные статические утверждения

Существуют другие макросы, производные от EIGEN_STATIC_ASSERT, для повышения удобочитаемости. Их имена говорят сами за себя.

  • EIGEN_STATIC_ASSERT_FIXED_SIZE(TYPE) - выполняется, если TYPE имеет фиксированный размер.
  • EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(TYPE) - выполняется, если TYPE имеет динамический размер.
  • EIGEN_STATIC_ASSERT_LVALUE(Derived) - не выполняется, если Derived является только для чтения.
  • EIGEN_STATIC_ASSERT_ARRAYXPR(Derived) - выполняется, если Derived является выражением массива.
  • EIGEN_STATIC_ASSERT_SAME_XPR_KIND(Derived1, Derived2) - не выполняется, если два выражения являются одним массивом и одной матрицей.

Поскольку Eigen обрабатывает как выражения фиксированного, так и динамического размера, некоторые условия нельзя однозначно определить на этапе компиляции. Мы классифицируем их как строгие и условные утверждения.

Строгие утверждения

Эти утверждения не выполняются, если условие может не выполняться. Например, MatrixXd может не быть вектором, поэтому он не выполняет EIGEN_STATIC_ASSERT_VECTOR_ONLY.

  • EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE) - выполняется, если TYPE должен быть вектором.
  • EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(TYPE, SIZE) - выполняется, если TYPE должен быть вектором заданного размера.
  • EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(TYPE, ROWS, COLS) - выполняется, если TYPE должен быть матрицей с заданными строками и столбцами.

Условные утверждения

Эти утверждения не выполняются, если условие не может выполняться. Например, MatrixXd и Matrix4d могут иметь одинаковый размер, поэтому они выполняют EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE.

  • EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(TYPE0,TYPE1) - не выполняется, если типы двух векторо-выражений должны иметь разные размеры.
  • EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(TYPE0,TYPE1) - не выполняется, если типы двух матричных выражений должны иметь разные размеры.
  • EIGEN_STATIC_ASSERT_SIZE_1x1(TYPE) - не выполняется, если TYPE не может быть выражением 1x1.

См. StaticAssert.h для получения подробной информации о том, какие сообщения они генерируют.

Отключение статических утверждений

Если EIGEN_NO_STATIC_ASSERT определено, статические утверждения преобразуются в eigen_assert, работающие как:

#define EIGEN_STATIC_ASSERT(CONDITION,MSG) eigen_assert((CONDITION) && #MSG);

Это экономит время компиляции, но увеличивает время выполнения. EIGEN_NO_STATIC_ASSERT не определено по умолчанию.

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

Spec-Zone.ru

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