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

template

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

template

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

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.

<p>11.11. Вычисление нормы вектора</p>Проблема

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

Решение

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

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

#include

#include

#include

#include

using namespace std;

template

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 из заголовочного файла используется для вычисления скалярного произведения числового вектора на самого себя. Квадратный корень полученного значения, как известно, является нормой вектора, или длиной вектора.

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

<p>11.12. Вычисление расстояния между векторами</p>Проблема

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

Решение

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

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

#include

#include

using namespace std;

template

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;

}

int main() {

 int v1[] = { 1, 5 };

 int v2[] = { 4, 9 };

 cout << "distance between vectors (1,5) and (4,9) is ";

 cout << vectorDistance(v1, v1 + 2, v2) << endl;

}

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

distance between vectors (1,5) and (4,9) is 5

Обсуждение
Перейти на страницу:

Похожие книги