===== Szablon inner_product =====
Szablon ''inner_product'' oblicza //iloczyn skalarny//((operator przypisujący dwóm argumentom wektorowym z przestrzeni liniowej wartość skalarną)) dwóch kolekcji. Działanie iloczynu skalarnego może być stanardowe lub zdefiniowane przez użytkownika.\\
Biblioteka ''stl'' dostarcza przeciążonej deklaracji ''inner_product'' w dwóch wariantach.\\
\\
====Deklaracja====
#include //lokalizacja inner_porduct
template
T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); // wariant pierwszy
template
T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,
T init,
BinaryFunction1 binary_op1, BinaryFunction2 binary_op2); // wariant drugi
\\
=====Wariant pierwszy - iloczyn skalarny euklidesowy=====
Prostsza z deklaracji ''inner_product'' udostępnia inerfejs do obliczenia zwykłego iloczynu skalarnego, znanego z geometrii euklidesowej.
===Parametery===
* //first1// iterator, który wskazuje na początek kolekcji pierwszej\\
* //last1// iterator, który wskazuje na koniec kolekcji pierwszej\\
* //first2// iterator, który wskazuje na początek kolekcji drugiej\\
* //init// wartość początkowa wyniku\\
===Działanie===
Funkcja inicjalizuje akumulator //a// = //init//, po czym oblicza kolejno w podanych zakresach: //a// = //a// + (*//it1//) ⋅ (*//it2//)
gdzie //it1// ∈ [//first1//, //last1//) , //it2// ∈ [//first2//, //first2// + //last1//-//first1//).\\
Jeśli zakresy kolekcji nie są równe, do obliczeń brany jest krótszy zakres. Zwracany jest oczywiście wynik działania.
Funckja ''inner_product'' ma złożoność liniową.
===Przykład===
Prosty przykład użycia ''inner_product'', czyli iloczyn skalarny wektorów:\\
vector v1;
vector v2;
v1.push_back(1);
v1.push_back(2); // v1 = [ 1, 2 ]
v2.push_back(2);
v2.push_back(3); // v2 = [ 2, 3 ]
//inner <= (1 + 1*2 )+ 2*3 = 9
int inner = inner_product(v1.begin(), v1.end(), v2.begin(), 1); // nie jest to "prawdziwy" iloczyn skalarny, bo inicjalizujemy wartością 1
printVector(cout, v2);
cout<<"Iloczyn skalarny = "<
=====Wariant drugi - iloczyn skalarny zdefinowany przez użytkownika=====
Druga z deklaracji ''inner_product'' jest poszerzona o dwa parametry:\\
* //binary_op1// operacja dwuargumentowa, która zastąpi dodawanie\\
* //binary_op2// operacja dwuargumentowa, która zastąpi mnożenie\\
===Działanie===
Funkcja inicjalizuje akumulator //a// = //init//, po czym oblicza //a// = //binary_op1//( //a// , //binary_op2//( (*//it1//) ,(*//it2//) ) ) dla podanego zekresu kolekcji. Zakresy iteratorów są takie same jak w pierwszym przypadku. \\
//binary_op1// i //binary_op2// muszą być funkcjami lub obiektami funkcyjnymi.
===Zdefiniowanie operacji do inner_product===
Aby wykorzystać ''inner_product'' do obliczania własnego iloczynu skalarnego należy zdefiniować własne operacje //binary_op1// i //binary_op2//. Najłatwiej to zrobić posługując się szablonem [[binary_operation]]. W przykładzie w pliku {{stl_algorytmy:inner_product.cpp | inner_product.cpp}} zdefiniowana jest funkcja ''multiplies_conj'', która mnoży liczbę zespoloną [[ liczby zespolone | complex]] przez liczbę sprzężoną z drugą liczbą.\\
#include // szablon binary_function
template struct multiplies_conj: public binary_function<_Tp, _Tp, _Tp> {// oblicza specyficzne mnożenie dla liczb zespolonych
_Tp operator()(const _Tp& __x, const _Tp& __y) const { // obiekt funkcyjny - przeciążony operator ()
return __x * conj(__y); // własne działanie - tutaj conj - zwraca liczbę sprzężoną do __y
}
};
Wykorzystując operację ''multiplies_conj'' oraz operację ''plus'' (również pochodną [[binary_function]]) łatwo jest już zdefiniować iloczyn skalarny dla wektorów liczb zespolonych:
#include // liczby zespolone complex
typedef complex ComplexInt;
vector c1;
vector c2;
c1.push_back(ComplexInt(1, 0));
c1.push_back(ComplexInt(3, 2)); // c1 = [ 1, 3 + 2j]
c2.push_back(ComplexInt(4, 5));
c2.push_back(ComplexInt(3, -1)); // c2 = [ 4 + 5j, 3 -j]
const ComplexInt complexZero(0, 0);
// complex <= 0 + ( 1*(4-5j) + ( (3+2j)*(3+j) ) ) = 4 + 9 - 2 - 5j + 3j + 6j = 11 +4j
ComplexInt complexInner = inner_product(c1.begin(), c1.end(), c2.begin(), complexZero,
plus(), multiplies_conj()); //zamiast zwykłego mnożenia - mnożenie przez liczbę sprzężoną
cout<<"Iloczyn skalarny = "<
====Zastosowanie inner_product====
Możliwych zastosowań ''inner_product'' można wymyśleć tyle, ile jest różnych przestrzeni z działaniem iloczynu skalarnego. Wiele problemów, niekoniecznie matematycznych, można wyrazić w postaci obliczania iloczynu skalarnego. Łatwo na przykład zastosować ten sposób obliczeń do porównywania ciągów znaków, do obliczania dopasowania do wzorca. Operacja iloczynu skalarnego jest dość prosta i szybka, dlatego warto z niej skorzystać w swoich projektach.
====Przykładowy kod====
Fragmenty kodu użyte w artykule znajdują się w pliku {{stl_algorytmy:inner_product.cpp | inner_product.cpp}}. Tam też można znaleźć przykład, jak policzyć kąt pomiędzy wektorami przy pomocy funkcji ''inner_product''.