Я работаю в программном обеспечении моделирования, и одна из многих операций над массивами — масштабирование вектора по числу.
У меня есть такой код:
//Just some initialization code, don't bother about this part
int n = 10000;
std::vector<double> input(n, 42.0);
std::vector<double> output(input.size());
double alpha = 69.0;
//the actual calculation:
for (size_t i = 0; i < n; ++i) {
output[i] = input[i] * alpha;
}
У меня есть библиотека MKL, поэтому, если мои вычисления выполняются «на месте», можно написать следующее:
cblas_dscal(n, alpha, &input[0], 1);
Однако это изменит input
переменная, что не то, что я хочу.
Я пытался использовать mkl_domatcopy()
но это очень медленно для этой операции.
Решение, которое я придумал, называлось cblas_dcopy()
затем cblas_dscal()
,
Это не лучший из всех миров, но он все еще быстрее, чем простой цикл.
Из справки МКЛ:
Процедуры cblas_? Axpy выполняют вектор-векторную операцию, определенную как
Y знак равно * Икс + Y
где: это скаляр, Икс а также Y векторы с числом элементов равным N.
В BLAS-подобных расширениях есть подпрограмма, которая называется cblas_? axpby
Вот выдержка из документации:
Масштабирует два вектора, добавляет их друг к другу и сохраняет результат в
вектор.
Разница в cblas_?axpy
является то, что у вас есть второй параметр масштабирования на вектор результата у. В вашем случае вы можете просто установить b := 0.0
и, таким образом, масштабирование не по месту за один вызов вместо двух cblas_dcopy()
а также cblas_dscal()
,
Ваш код может выглядеть так:
//Just some initialization code, don't bother about this part
int n = 10000;
std::vector<double> input(n, 42.0);
std::vector<double> output(input.size());
double alpha = 69.0;
//the actual calculation:
cblas_daxpby (output.size(), alpha, input.data(), 1, 0.0, output.data(), 1);