#ifndef GEOMETRY_UTILS_VECTORN_H #define GEOMETRY_UTILS_VECTORN_H #include #include #include #include #include "GeometryUtilsMath.h" namespace geometry_utils { template struct VectorNBase { typedef typename boost::shared_ptr > Ptr; typedef typename boost::shared_ptr > ConstPtr; static const size_t length = N; boost::array data; VectorNBase() { data.fill(0); } VectorNBase(T val) { data.fill(val); } VectorNBase(const VectorNBase& in) : data(in.data) {} VectorNBase(const boost::array& in) : data(in) {} VectorNBase(T (&in)[N]) { for (size_t i = 0; i < N; i++) data[i] = in[i]; } VectorNBase(const Eigen::Matrix& in) { for (size_t i = 0; i < N; i++) data[i] = in(i, 0); } inline T& operator()(unsigned int i) { return data[i]; } inline const T& operator()(unsigned int i) const { return data[i]; } inline T& Get(unsigned int i) { return data[i]; } inline const T& Get(unsigned int i) const { return data[i]; } inline VectorNBase& operator=(const VectorNBase& rhs) { if (this == &rhs) return *this; data = rhs.data; return *this; } inline VectorNBase operator*(T rhs) const { T d[N]; for (size_t i = 0; i < N; i++) d[i] = data[i] * rhs; return VectorNBase(d); } inline VectorNBase operator+(const VectorNBase& rhs) const { T d[N]; for (size_t i = 0; i < N; i++) d[i] = data[i] + rhs.data[i]; return VectorNBase(d); } inline VectorNBase operator-() const { T d[N]; for (size_t i = 0; i < N; i++) d[i] = -data[i]; return VectorNBase(d); } inline VectorNBase operator-(const VectorNBase& rhs) const { T d[N]; for (size_t i = 0; i < N; i++) d[i] = data[i] - rhs.data[i]; return VectorNBase(d); } inline VectorNBase operator%(const VectorNBase& rhs) const { T d[N]; for (size_t i = 0; i < N; i++) d[i] = data[i] * rhs.data[i]; return VectorNBase(d); } inline T operator^(const VectorNBase& rhs) const { T dot = 0; for (size_t i = 0; i < N; i++) dot += data[i] * rhs.data[i]; return dot; } inline VectorNBase operator/(const VectorNBase& rhs) const { T d[N]; for (size_t i = 0; i < N; i++) d[i] = data[i] / rhs.data[i]; return VectorNBase(d); } inline VectorNBase operator+=(const VectorNBase& rhs) { for (size_t i = 0; i < N; i++) data[i] += rhs.data[i]; return *this; } inline VectorNBase operator-=(const VectorNBase& rhs) { for (size_t i = 0; i < N; i++) data[i] -= rhs.data[i]; return *this; } inline VectorNBase operator%=(const VectorNBase& rhs) { for (size_t i = 0; i < N; i++) data[i] *= rhs.data[i]; return *this; } inline VectorNBase operator/=(const VectorNBase& rhs) { for (size_t i = 0; i < N; i++) data[i] /= rhs.data[i]; return *this; } inline VectorNBase operator*=(const T& rhs) { for (size_t i = 0; i < N; i++) data[i] *= rhs; return *this; } inline VectorNBase operator/=(const T& rhs) { for (size_t i = 0; i < N; i++) data[i] /= rhs; return *this; } inline bool operator==(const VectorNBase& that) const { return this->Equals(that); } inline bool operator!=(const VectorNBase& that) const { return !this->Equals(that); } inline bool Equals(const VectorNBase& that, const T ptol = 1e-8) const { return (*this - that).Norm() < ptol; } inline T Norm() const { return math::sqrt((*this) ^ (*this)); } inline VectorNBase Normalize() const { return (*this) / Norm(); } inline VectorNBase Abs() const { T d[N]; for (size_t i = 0; i < N; i++) d[i] = std::abs(data[i]); return VectorNBase(d); } inline void Ones() { data.fill(1); } inline void Zeros() { data.fill(0); } inline T Dot(const VectorNBase& v) const { return (*this) ^ v; } inline VectorNBase Scale(T s) const { return (*this) * s; } inline void Print(const std::string& prefix = std::string()) const { if (!prefix.empty()) std::cout << prefix << std::endl; std::cout << (*this) << std::endl; } inline Eigen::Matrix Eigen() const { return Eigen::Matrix(data.data()); } }; template inline VectorNBase operator*(const T& lhs, const VectorNBase& rhs) { return rhs * lhs; } template inline std::ostream& operator<<(std::ostream& out, const VectorNBase& m) { for (size_t i = 0; i < N - 1; i++) out << m.data[i] << " "; out << m.data[N - 1]; return out; } template inline Eigen::Matrix Eigen(const VectorNBase& in) { return in.Eigen(); } template inline T Norm(const VectorNBase& v) { return v.Norm(); } template inline T Dot(const VectorNBase& v1, const VectorNBase& v2) { return v1.Dot(v2); } } #endif