| @@ -1,25 +1,140 @@ | |||||
| #include <iostream> | #include <iostream> | ||||
| #include <vector> | #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 { | class Vector { | ||||
| public: | 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: | 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() { | int main() { | ||||
| Vector<double, 3> a; | 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; | |||||
| } | } | ||||