Относительно поэлементных операций в boost::ublas

Я считаю, что boost:: ublas не очень хорошо поддерживает поэлементные операции и операции в последовательности (но эффективность довольно высокая:)) Я пытаюсь

D = A^2 .* B^3 .* C

где A, B, C - квадратные матрицы одинакового размера, оператор ".*" обозначает поэлементную операцию, а ^ - степень матрицы. С бустом: ублас, я написал

for (int n=0; n<300; n++)
{
  for (int k=0; k<300; k++)
  {
    D(n, k) = pow(abs(A(n, k)), 2)*pow(abs(B(n, k)), 3)*C(n, k);
  }
}

В моей программе у меня есть много последовательных операций, подобных тем, что показаны выше, в любом случае, я могу получить тот же результат, но используя одну строку кода вместо цикла?

Кроме того, я замечаю, что кажется неправильным присваивать постоянную всем элементам матрицы или вектора, например

boost::numeric::ublas::vector v(100); v = 0,2;

Вместо этого я должен использовать цикл для повторного выполнения задания, есть ли лучший способ сохранить код? Мой алгоритм очень длинный и в нем так много утомительных операций, как те, что указаны выше. Я попробовал другую числовую библиотеку Armadillo, которая предоставляет хороший способ просто выполнять операции, но в настоящее время она не допускает разреженных матриц (которая потратит около 10 раз на выполнение моего кода).

1 ответ

Вы можете легко присвоить константу вектору или матрице:

vector<double> v = scalar_vector<double>(100, 0.2);

обычный вектор (но не c_vector или bounded_vector) даже имеет конструктор:

vector<double> v(100, 0.2);

Что касается операций с элементами, вы также можете легко определить свой собственный, это просто стандартный код, например, для абсолютной мощности:):

namespace boost { namespace numeric { namespace ublas {
template<class M, class P>
struct scalar_power:
    public scalar_binary_functor<M, P> {
    typedef typename scalar_binary_functor<M, P>::argument1_type argument1_type;
    typedef typename scalar_binary_functor<M, P>::argument2_type argument2_type;
    typedef typename scalar_binary_functor<M, P>::result_type result_type;

    static BOOST_UBLAS_INLINE
    result_type apply (argument1_type t1, argument2_type t2) {
        return pow(abs(t1), t2);
    }
};

template<class M, class P>
BOOST_UBLAS_INLINE
typename enable_if< is_convertible<P, typename M::value_type>,
typename matrix_binary_scalar2_traits<M, const P, scalar_power<typename M::value_type, P> >::result_type
>::type
operator ^ (const matrix_expression<M> &m,
            const P &p) {
    typedef typename matrix_binary_scalar2_traits<M, const P, scalar_power<typename M::value_type, P> >::expression_type expression_type;
    return expression_type (m(), p);
}
}}}

После этого ваше выражение становится:

D = element_prod(A^2, element_prod(B^3, C));
Другие вопросы по тегам