// =============================================================================== // // A library defining possible operations among std::vector // // =============================================================================== #include #include #include #include // se se vogliono usare algoritmi STL #include // per inner_product using namespace std; // =============================================================================== // somma di due vettori : somma componente per componente // =============================================================================== template std::vector operator+(const std::vector &a, const std::vector &b) { // below different ways to check if vectors have the same size // assert(a.size() == b.size()); // if ( a.size() != b.size() ) throw "Trying to sum vectors with different size" ; if ( a.size() != b.size() ) { cout << "Trying to sum vectors with different size, exiting" << endl ; exit(-1); } ; std::vector result(a.size()); for (int i = 0; i < static_cast(a.size()); i++) result[i] = a[i] + b[i]; // Alternativamente si puo' usare l'algoritmo transform della STL // // std::transform(a.begin(), a.end(), b.begin(), result.begin() , std::plus()); return result; } // =============================================================================== // differenza di due vettori componente per componente // [ preferisco re-implementarlo perche' si fanno meno operazioni rispetto result = a + (-1.*b) ] // =============================================================================== template std::vector operator-(const std::vector &a, const std::vector &b) { // below different ways to check if vectors have the same size // assert(a.size() == b.size()); // if ( a.size() != b.size() ) throw "Trying to sum vectors with different size" ; if ( a.size() != b.size() ) { cout << "Trying to sum vectors with different size, exiting" << endl ; exit(-1); } ; std::vector result(a.size()); for (int i = 0; i < static_cast(a.size()); i++) result[i] = a[i] - b[i]; // Alternativamente si puo' usare l'algoritmo transform della STL // // std::transform(a.begin(), a.end(), b.begin(), result.begin() , std::minus()); return result; } // =============================================================================== // prodotto scalare tra due vettori // =============================================================================== template T operator*(const std::vector &a, const std::vector &b) { // below different ways to check if vectors have the same size // assert(a.size() == b.size()); // if ( a.size() != b.size() ) throw "Trying to sum vectors with different size" ; if ( a.size() != b.size() ) { cout << "Trying to sum vectors with different size, exiting" << endl ; exit(-1); } ; T sum = 0 ; for (int i = 0; i < static_cast(a.size()); i++) sum += a[i] * b[i]; // Alternativamente si puo' usare l'algoritmo inner_product della STL // // sum = std::inner_product(std::begin(a), std::end(a), std::begin(b), 1.0); return sum; } // =============================================================================== // prodotto tra uno scalare e un vettore // =============================================================================== template std::vector operator*( T c , const std::vector &a) { std::vector result(a.size()); for (int i = 0; i < static_cast(a.size()); i++) result[i] = c * a[i]; // Alternativamente si puo' usare l'algoritmo inner product // // std::transform(std::begin(a), std::end(a), std::begin(result), [&c](T x){ return x * c; } ); return result; } // =============================================================================== // prodotto tra un vettore e uno scalare // =============================================================================== template std::vector operator*( const std::vector &a , T c) { std::vector result(a.size()); for (int i = 0; i < static_cast(a.size()); i++) result[i] = c * a[i]; // oppure il ciclo for puo' essere sostituito da ( ~ stesso numero di operazioni con il // move constructor del vector altrimenti sarebbe meno efficiente ) // // result = c * a ; // Alternativamente si puo' usare l'algoritmo transform della STL con una lambda function // // std::transform(std::begin(a), std::end(a), std::begin(result), [&c](T x){ return x * c; } ); return result; } // =============================================================================== // divisione tra un vettore e uno scalare // =============================================================================== template std::vector operator/( const std::vector &a , T c) { std::vector result(a.size()); for (int i = 0; i < static_cast(a.size()); i++) result[i] = a[i] / c ; // oppure il ciclo for puo' essere sostituito da // double fact = 1./c // result = a * fact ; // Alternativamente si puo' usare l'algoritmo transform della STL con una lambda function // // std::transform(std::begin(a), std::end(a), std::begin(result), [&c](T x){ return x / c; } ); return result; } // =============================================================================== // somma ad a un vettore b e il risultato viene messo in a // =============================================================================== template std::vector& operator+=(std::vector& a, const std::vector& b) { // below different ways to check if vectors have the same size // assert(a.size() == b.size()); // if ( a.size() != b.size() ) throw "Trying to sum vectors with different size" ; if ( a.size() != b.size() ) { cout << "Trying to sum vectors with different size, exiting" << endl ; exit(-1); } ; for (int i = 0; i < static_cast(a.size()); i++) a[i] += b[i]; // Alternativamente si puo' usare l'algoritmo transform della STL // // std::transform(a.begin(), a.end(), b.begin(), a.begin() , std::plus()); return a; } // =============================================================================== // sottrai ad a un vettore b e il risultato viene messo in a // =============================================================================== template std::vector& operator-=(std::vector& a, const std::vector& b) { // below different ways to check if vectors have the same size // assert(a.size() == b.size()); // if ( a.size() != b.size() ) throw "Trying to sum vectors with different size" ; if ( a.size() != b.size() ) { cout << "Trying to sum vectors with different size, exiting" << endl ; exit(-1); } ; for (int i = 0; i < static_cast(a.size()); i++) a[i] -= b[i]; // Alternativamente si puo' usare l'algoritmo transform della STL // // std::transform(a.begin(), a.end(), b.begin(), a.begin() , std::minus()); return a; } // =============================================================================== // Possiamo usare funzioni generiche che agiscono sui vettori // =============================================================================== // metodo comodo per stampare il vettore template void Print( const std::vector &v ) { std::cout << "Printing vector" << std::endl; for ( auto it = v.begin() ; it != v.end() ; it++ ) std::cout << *it << " " ; std::cout << std::endl; std::cout << "End of printing vector" << std::endl; }; /* template class linearVector : public std::vector { public : linearVector ( ) : std::vector(){} ; linearVector ( int size ) : std::vector(size){} ; linearVector operator+( const linearVector &a ) { assert(a.size() == this->size()); linearVector result(a.size()) ; for (int i = 0; i < static_cast(a.size()); i++) result[i] = a[i] + (*this)[i]; return result; } }; */