2016-01-05 3 views
1

Я надеюсь, что эта дискуссия может помочь любому, у кого есть проблемы с Armadillo и Eigen3.Armadillo vs Eigen3 Сроки разницы

Я написал класс оболочки, Mat, который обертывает либо arma :: Mat из библиотеки armadillo, либо Eigen :: Matrix из библиотеки Eigen3. Это контролируется флагом во время компиляции.

Кроме того, я написал класс Тензора, который использует Mat как хранилище. Основной особенностью этого класса является использование нотации Voigt для уплотнения тензоров более высокого порядка, которые должны быть правильно сохранены в матрице.

Наконец, я написал тест, который умножает тензор 2-го порядка (т. Е. Матрицу) и тензор 1-го порядка (т. Е. Вектор) несколько раз и записывает время, необходимое для завершения операторов. Я делаю это со своим классом Mat и с моим классом Tensor.

Поскольку Tensor wraps Mat, я бы ожидал, что его время будет больше. Это касается Армадилло, в среднем около 20%. Однако при использовании Eigen использование Tensor происходит быстрее, что совершенно не имеет для меня никакого смысла.

Что-нибудь торчит кому-нибудь?

EDIT: Предоставление более подробной информации.

Я первый обернул arma :: Mat in myOwn :: armaMat и Eigen :: Matrix в myOwn :: eigenMat. Оба они просто обертывают armadillo и API Eigen в общую структуру. Наконец, на основе флага компилятора myOwn :: Mat обертывает armaMat или eigenMat. Я не уверен в каких-либо флагах оптимизации, которые мы включили.

Как описано выше, myOwn :: Tensor использует myOwn :: Mat в качестве хранилища. Из-за физических приложений я буду использовать класс Тензор, он будет задуман как 2D (т. Е. 2-на-2, если это 2-й порядок) или 3D (т. Е. 3-на-3). (Напротив, Mat может быть любого размера).

Оператором, который я использую для целей синхронизации, является: матрица 2 на 2 (тензор 2-го порядка), умноженная на матрицу 2 на 1 (тензор 1-го порядка). Когда я использую только Mat, я, по существу, использую эмпирическое выражение для ампадильо или Эйгена.

При использовании моего класса тензора, я перегрузка оператора *, как, например:

template< typename T1, bool Sym > 
moris::Mat<T1> 
operator*(
     moris::Tensor< T1, 2, 2, true > const & aTensor1, 
     moris::Tensor< T1, 1, 2, Sym > const & aTensor2) 
{ 

    moris::Mat<T1> tVector(2, 1); 

    tVector(0) = aTensor1[0]*aTensor2[0] + aTensor1[2]*aTensor2[1]; 
    tVector(1) = aTensor1[2]*aTensor2[0] + aTensor1[1]*aTensor2[1]; 

    return tVector; 
} 

[] и оператор получает доступ к данному тензору образует основной Мат для хранения (с помощью Фойхты конвенции).

+0

Каковы размеры матриц? Вы называете матрично-векторные продукты Eigen/Armidillo в случаях Мата и Тензора? Кроме того, обязательно компиляция с оптимизацией компилятора включена.Наконец, если эти замечания не помогли выявить какие-либо проблемы, тогда трудно помочь больше, не видя кода того, что вы делаете. – ggael

+0

Я обновил вопрос, чтобы ответить на некоторые из вопросов, которые вы подняли. –

ответ

5

«Это сложно».

Мы предлагаем крепления как для Armadillo, так и для Eigen-R через дополнительные пакеты RcppArmadillo и RcppEigen, поэтому вопрос о сравнении и скачках очень много.

И я не думаю, что есть четкий ответ. Чтобы сделать вещи «хуже», Армадилло обычно ссылается на какой-либо LAPACK/BLAS, который вы установили, и поэтому вы можете использовать многоядерный параллелизм, тогда как Eigen предпочитает свои собственные подпрограммы. При подготовке моего Rcpp book я сделал некоторые тайминги и нашел некоторые контр-интуитивные результаты.

В конце дня вам может понадобиться профиль проблема.

+0

Я ценю ваш ответ, спасибо! Что меня больше всего беспокоит, так это то, что при использовании Eigen использование класса Tensor быстрее, чем класс Mat, хотя Tensor обертывает Mat. –

Смежные вопросы