===== 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''.