int main() {

 int v1[] = { 1, 2, 3 };

 int v2[] = { 4, 6, 8 };

 cout << 'the dot product of (1,2,3) and (4,6,8) is ';

 cout << inner_product(v1, v1 + 3, v2, 0) << endl;

}

Программа примера 11.19 выдает следующий результат.

the dot product of (1,2,3) and (4,6,8) is 40

Обсуждение

Скалярное произведение (dot product) является одной из форм обобщенного скалярного произведения (inner product), называемой евклидовым скалярным произведением (Euclidean Inner Product). Функция inner_product объявляется следующим образом.

template<class In, class In2, class T>

T inner_product(In first, In last, In2 first2, T init);

template<class In, class In2, class T, class BinOp, class BinOp2>

T inner_product(In first, In last, In2 first2, T init, BinOp op, BinOp2 op2);

Первый вариант функции inner_product суммирует произведения соответствующих элементов двух контейнеров. Второй вариант функции inner_product позволяет вам самому предоставить операцию над парой чисел и функцию суммирования. В примере 11.20 продемонстрирована простая реализация функции inner_product.

Пример 11.20. Пример реализации функции inner_product()

template<class In, class In2, class T, class BinOp, class BinOp2>

T inner_product(In first, In last, In2 first2, T init, BinOp op, Binop2 op2) {

 while (first != last) {

  BinOp(init, BinOp2(*first++, *first2++));

 }

 return init;

}

Благодаря гибкости реализации функции inner_product вы можете ее использовать для многих других целей, а не только для расчета скалярного произведения (например, ее можно использовать для вычисления расстояния между двумя векторами или для вычисления нормы вектора).

Смотри также

Рецепты 11.11 и 11.12.

11.11. Вычисление нормы вектора

Проблема

Требуется найти норму (т. е. длину) числового вектора.

Решение

Можно использовать функцию inner_product из заголовочного файла <numeric> для умножения вектора на самого себя, как показано в примере 11.21.

Пример 11.21. Вычисление нормы вектора

#include <numeric>

#include <vector>

#include <cmath>

#include <iostream>

using namespace std;

template<typename Iter_T>

long double vectorNorm(Iter_T first, Iter_T last) {

 return sqrt(inner_product(first, last, first, 0.0L));

}

int main() {

 int v[] = { 3, 4 };

 cout << 'The length of the vector (3.4) is ';

 cout << vectorNorm(v, v + 2) << endl;

}

Программа примера 11.21 выдает следующий результат.

The length of the vector (3,4) is 5

Обсуждение

В примере 11.21 функция inner_product из заголовочного файла <numeric> используется для вычисления скалярного произведения числового вектора на самого себя. Квадратный корень полученного значения, как известно, является нормой вектора, или длиной вектора.

Вместо того чтобы в функции vectorNorm выводить тип результата по аргументам, я решил для него использовать тип long double, чтобы терять как можно меньше данных. Если вектор представляет собой набор значений целого типа, маловероятно, что в реальных условиях норма вектора может быть адекватно представлена целым типом.

11.12. Вычисление расстояния между векторами

Проблема

Требуется найти евклидово расстояние между векторами.

Решение

Евклидово расстояние между векторами определяется как квадратный корень суммы квадратов разностей соответствующих элементов. Рассчитать его можно так, как показано в примере 11.22.

Пример 11.22. Расчет расстояния между двумя векторами

#include <cmath>

#include <iostream>

using namespace std;

template<class Iter_T, class Iter2_T>

double vectorDistance(Iter_T first, Iter_T last, Iter2_T first2) {

 double ret = 0.0;

 while (first != last) {

  double dist = (*first++) - (*first2++);

  ret += dist * dist;

 }

 return ret > 0.0 ? sqrt(ret) : 0.0;

}

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

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

Отметить Добавить цитату