#ifndef STIM_VECTOR_H #define STIM_VECTOR_H #include #include #include #include #include #include namespace stim { template struct vec : public std::vector { using std::vector::size; using std::vector::at; using std::vector::resize; using std::vector::push_back; vec(){ } /// Create a vector with a set dimension d vec(size_t d) { resize(d,0); } // //efficiency constructors, makes construction easier for 1D-4D vectors vec(T x, T y) { resize(2, 0); at(0) = x; at(1) = y; } vec(T x, T y, T z) { resize(3, 0); at(0) = x; at(1) = y; at(2) = z; } vec(T x, T y, T z, T w) { resize(4, 0); at(0) = x; at(1) = y; at(2) = z; at(3) = w; } vec(std::string str){ std::stringstream ss(str); T c; while(ss >> c){ push_back(c); } } //copy constructor vec( const vec& other){ size_t N = other.size(); resize(N); //resize the current vector to match the copy for(size_t i=0; i push(T x) { push_back(x); return *this; } vec push(T x, T y) { push_back(x); push_back(y); return *this; } vec push(T x, T y, T z) { push_back(x); push_back(y); push_back(z); return *this; } vec push(T x, T y, T z, T w) { push_back(x); push_back(y); push_back(z); push_back(w); return *this; } /// Casting operator. Creates a new vector with a new type U. template< typename U > operator vec(){ size_t N = size(); vec result; for(int i=0; i cyl2cart() const { vec cyl; cyl.push_back(at(0)*std::sin(at(1))); cyl.push_back(at(0)*std::cos(at(1))); cyl.push_back(at(2)); return(cyl); } /// Convert the vector from cartesian to spherical coordinates (x, y, z -> r, theta, phi where theta = [0, 2*pi]) vec cart2sph() const { vec sph; sph.push_back(std::sqrt(at(0)*at(0) + at(1)*at(1) + at(2)*at(2))); sph.push_back(std::atan2(at(1), at(0))); if(sph[0] == 0) sph.push_back(0); else sph.push_back(std::acos(at(2) / sph[0])); return sph; } /// Convert the vector from cartesian to spherical coordinates (r, theta, phi -> x, y, z where theta = [0, 2*pi]) vec sph2cart() const { vec cart; cart.push_back(at(0) * std::cos(at(1)) * std::sin(at(2))); cart.push_back(at(0) * std::sin(at(1)) * std::sin(at(2))); cart.push_back(at(0) * std::cos(at(2))); return cart; } /// Computes the normalized vector (where each coordinate is divided by the L2 norm) vec norm() const { size_t N = size(); //compute and return the unit vector vec result; //compute the vector length T l = len(); //normalize for(size_t i=0; i cross(const vec rhs) const { vec result(3); //compute the cross product (only valid for 3D vectors) result[0] = (at(1) * rhs[2] - at(2) * rhs[1]); result[1] = (at(2) * rhs[0] - at(0) * rhs[2]); result[2] = (at(0) * rhs[1] - at(1) * rhs[0]); return result; } /// Compute the Euclidean inner (dot) product T dot(vec rhs) const { T result = (T)0; size_t N = size(); for(int i=0; i operator+(vec rhs) const { size_t N = size(); vec result(N); for(int i=0; i operator+(T rhs) const { size_t N = size(); vec result(N); for(int i=0; i operator-(vec rhs) const { size_t N = size(); vec result(N); for(size_t i=0; i operator-(T rhs) const { size_t N = size(); vec result(N); for(size_t i=0; i operator*(T rhs) const { size_t N = size(); vec result(N); for(size_t i=0; i operator/(T rhs) const { size_t N = size(); vec result(N); for(size_t i=0; i operator*=(T rhs){ size_t N = size(); for(size_t i=0; i operator+=(vec rhs){ size_t N = size(); for(size_t i=0; i & operator=(T rhs){ size_t N = size(); for(size_t i=0; i(){ stim::vec3 r; size_t N = std::min(size(), 3); for(size_t i = 0; i < N; i++) r[i] = at(i); return r; } /// Casting and assignment template vec & operator=(vec rhs){ size_t N = rhs.size(); resize(N); for(size_t i=0; i operator-() const{ size_t N = size(); vec r(N); //negate the vector for(size_t i=0; i std::ostream& operator<<(std::ostream& os, stim::vec v) { os< stim::vec operator*(T lhs, stim::vec rhs) { stim::vec r; return rhs * lhs; } #endif