Как читать код C ++ или: что делать без документации? - PullRequest
2 голосов
/ 10 декабря 2011

Вопрос может показаться немного странным: я хочу выполнить числовые матричные вычисления, используя ublas Boost и ATLAS / Lapack.Я использую числовые привязки Boost для взаимодействия между этими двумя библиотеками.Тем не менее, либо я просто не могу найти его, либо нет соответствующей документации о том, как использовать эти привязки.Кроме того, я новичок в Boost (и вообще в C ++), поэтому мне трудно понять, как я могу использовать функции, предоставляемые Lapack, в моем коде.

Задача, которую я хочу решить, в конце концов, - найти собственные значения и -векторы симметричной полосчатой ​​матрицы.Насколько я понял, я бы использовал для этого lapack::steqr.Дело в том, я не знаю, как правильно вызвать функцию.В коде числовых привязок я вижу что-то вроде этого:

template <typename D, typename E, typename Z, typename W>
inline
int steqr( char compz, D& d, E& e, Z& z, W& work ) {

  int const n = traits::vector_size (d);
  assert( traits::vector_size (e) == n-1 );
  assert( traits::matrix_size1 (z) == n );
  assert( traits::matrix_size2 (z) == n );
  assert( compz=='N' || compz=='V' || compz=='I' );
  ...

Теперь, как мне это сделать?Я пробовал steqr<double, double, double, double>(...) и двойные массивы, которые не работали.Затем, чтобы выяснить правильные аргументы для использования, я выбрал одно из утверждений и попытался найти что-нибудь, что работает с traits::matrix_size1(...) - Даже то, что мне не удалось собрать, ни с двойным массивом, ни с ublas::matrix,

Итак, мой вопрос в общем: когда я нахожу такую ​​библиотеку без полной документации, как мне узнать, как вызывать функции?Я в основном из Си и очень запутался со всеми этими шаблонами.Единственный ли способ действительно отследить все в коде?Или есть маленькие хитрости?Или я могу, вероятно, извлечь информацию из сообщений об ошибках?

Один из примеров такого сообщения об ошибке, для следующего кода:

ublas::matrix<double> empty(N,N);
std::cout << traits::matrix_size1<ublas::matrix>(empty) << std::endl;

Затем я получаю во время компиляции:

eigenvalues.cpp:40:85: error: no matching function for call to ‘matrix_size1(boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<>, boost::numeric::ublas::unbounded_array<double, std::allocator<double> > >&)’
eigenvalues.cpp:40:85: note: candidate is:
/usr/include/boost/numeric/bindings/traits/matrix_traits.hpp:148:18: note: template<class M> std::ptrdiff_t boost::numeric::bindings::traits::matrix_size1(M&)

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

Опять же: этот вопрос немного более общий о том, как поступать с такими вещами.Я знаю основную концепцию классов и шаблонов, но это слишком абстрактно для моих знаний.

1 Ответ

1 голос
/ 10 декабря 2011

Поскольку я не очень хорошо разбираюсь в шаблонах с ++, мне лично гораздо проще использовать интерфейс cblas, который является лишь тонкой оболочкой по сравнению с исходным кодом на Фортране.

При таком подходе вам придется создать свой собственный класс для матриц, который был бы совместим с пониманием Фортраном того, что такое матрица.Самый простой способ - это, вероятно, наследовать от std::vector или std::valarray и предоставить собственную операцию индексирования.Да, это немного работы.Но это не так плохо, как кажется :-).

И, кстати, остерегайтесь использования подпрограмм одинарной точности (ssteqr) с аргументами двойной точности.LAPACK не сообщит ни об одной ошибке, но результат будет явно неверным.

...