| @@ -1,25 +1,140 @@ | |||
| #include <iostream> | |||
| #include <vector> | |||
| #include <algorithm> | |||
| #include <numeric> | |||
| template <class T, int N> | |||
| // a class implementing a mathematical vector | |||
| template <class K, size_t N> | |||
| class Vector { | |||
| public: | |||
| Vector<T,N> operator+(const Vector<T,N>& y); // Vektoraddition | |||
| //T operator*(const Vector<T,n>& y); // Skalarprodukt | |||
| // constructor, initializes vector with zeroes of length N | |||
| Vector() : _vector(N, 0) {} | |||
| // initialize by passing vector vec to initialize the vector object with | |||
| Vector(std::vector<K> vec) { _vector = vec; } | |||
| // copy constructor, assignment, destructor not needed | |||
| // all handled by std::vector | |||
| // reference [] operator, used for assignments | |||
| K& operator[](int i) { | |||
| return _vector[i]; | |||
| } | |||
| // const ref [] operator | |||
| K operator[](int i) const { | |||
| return _vector[i]; | |||
| } | |||
| // return an iterator pointing to the first element of the underlying std::vector | |||
| typename std::vector<K>::const_iterator begin() const { | |||
| return _vector.begin(); | |||
| } | |||
| // return an iterator pointing to the last element of the underlying std::vector | |||
| typename std::vector<K>::const_iterator end() const { | |||
| return _vector.end(); | |||
| } | |||
| // dot product of two vectors of the same length | |||
| template <class K2> | |||
| K operator*(const Vector<K2,N>& y) { | |||
| std::vector<K> result(N); // new empty std::vector of correct size | |||
| // now multiply one element of the first with one of the second vector | |||
| std::transform(_vector.begin(), _vector.end(), y.begin(), result.begin(), std::multiplies<K>()); | |||
| // and sum up the products | |||
| return std::accumulate(result.begin(), result.end(), 0); | |||
| } | |||
| // vector addition | |||
| template <class K2> | |||
| Vector<K, N> operator+(const Vector<K2, N>& y) { | |||
| std::vector<K> result(N); // new empty std::vector of correct size | |||
| // add elements by adding one element of the first to one of the second vector | |||
| std::transform(_vector.begin(), _vector.end(), y.begin(), result.begin(), std::plus<K>()); | |||
| return Vector(result); | |||
| } | |||
| // return the maximum value in the vector | |||
| K max() { | |||
| return *std::max_element(_vector.begin(), _vector.end()); | |||
| } | |||
| // return the minimum value in the vector | |||
| K min() { | |||
| return *std::min_element(_vector.begin(), _vector.end()); | |||
| } | |||
| // return the average value of the vector | |||
| K average() { | |||
| // sum up all elements | |||
| K sum = std::accumulate(_vector.begin(), _vector.end(), 0); | |||
| return sum / N; // and divide by length | |||
| } | |||
| // run the specified function on each vector element | |||
| template <class F> | |||
| Vector<K,N> map(F op) const { | |||
| std::vector<K> result(N); // initialize new std::vector of correct size | |||
| // run op on each element | |||
| std::transform(_vector.begin(), _vector.end(), result.begin(), op); | |||
| return Vector(result); | |||
| } | |||
| private: | |||
| std::vector<T> _vector[N]; | |||
| std::vector<K> _vector; // the private std::vector container | |||
| }; | |||
| template <class A, int N> | |||
| Vector<A,N> Vector<A, N>::operator+(const Vector<B,N>& y) { | |||
| //for(int i = 0; i < _vector.last; i++) { | |||
| // std::cout << _vector[i] << std::endl; | |||
| //} | |||
| return y; | |||
| // print vector | |||
| template <class K, size_t N> | |||
| std::ostream& operator<<(std::ostream& os, const Vector<K,N>& v) { | |||
| os << "["; // opening brackets | |||
| for (size_t i = 0; i < N; i++) { | |||
| os << v[i]; // print element | |||
| if(i < N-1) { | |||
| os << ", "; // if not the last one, add comma | |||
| } | |||
| } | |||
| os << "]"; // closing brackets | |||
| return os; | |||
| } | |||
| // scalar multiplication | |||
| template <class K, size_t N, class K2> | |||
| Vector<K, N> operator*(const Vector<K,N>& v, const K2 k) { | |||
| // multiply a scalar value using the generic map function | |||
| return v.map(std::bind1st(std::multiplies<K>(), k)); | |||
| } | |||
| // scalar multiplication for scalar * vector | |||
| template <class K, size_t N, class K2> | |||
| Vector<K, N> operator*(const K2 k, const Vector<K,N>& v) { | |||
| return v * k; | |||
| } | |||
| // example function | |||
| double foo(double val) { | |||
| return val*2+3; | |||
| } | |||
| // testing out functionalities | |||
| int main() { | |||
| Vector<double, 3> a; | |||
| Vector<double, 3> b; | |||
| b = a+a; | |||
| Vector<float, 3> b; | |||
| a[0] = 0; | |||
| a[1] = 0; | |||
| a[2] = 4; | |||
| b[0] = 42; | |||
| b[1] = -20; | |||
| b[2] = 3; | |||
| std::cout << "Vektor a: " << a << ", Vektor b: " << b << std::endl; | |||
| std::cout << "a+b: " << a+b << std::endl; | |||
| std::cout << "a*b: " << a*b << std::endl; | |||
| std::cout << "42*b: " << 42*b << std::endl; | |||
| std::cout << "b*42: " << b*42 << std::endl; | |||
| std::cout << "max(a): " << a.max() << std::endl; | |||
| std::cout << "min(a): " << a.min() << std::endl; | |||
| std::cout << "mean(a): " << a.average() << std::endl; | |||
| std::cout << "foo angewendet auf b: " << b.map(foo) << std::endl; | |||
| } | |||