00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef MORE_VECTIN_H
00032 #define MORE_VECTIN_H
00033
00034 #include <functional>
00035 #include <iosfwd>
00036 #include <more/math/math.h>
00037 #include <more/meta.h>
00038 #include <more/io/syncstream.h>
00039
00040 #ifdef MORE_CHECK_RANGE
00041 # include <assert.h>
00042 # define MORE_CHECKRNG(i, N) assert(0 <= i && i < N)
00043 #else
00044 # define MORE_CHECKRNG(i, N)
00045 #endif
00046
00047 namespace more {
00048 namespace num {
00049
00050 #ifndef MORE_ENUMERATE
00051 #define MORE_ENUMERATE
00052 template<typename T>
00053 inline int enumerator(T x) { return static_cast<int>(x); }
00054 #endif
00055
00056 template <int I, int J> struct assert_ {};
00057 template <int I> struct assert_<I, I> { typedef int eval; };
00058
00059 template <class T, int N>
00060 class vectin {
00061 template<typename U, int M> friend class vectin;
00062 private:
00063 T w[N];
00064 public:
00065 typedef T scalar_type;
00066 typedef T* iterator;
00067 typedef const T* const_iterator;
00068
00069 vectin() {}
00070 vectin(const vectin& x)
00071 { for (int i = 0; i < N; i++) w[i] = x.w[i]; }
00072 vectin(zero_tag)
00073 { for (int i = 0; i < N; ++i) w[i] = T(zero); }
00074 explicit vectin(T x0) {
00075 typedef typename assert_<N, 1>::eval bad_number_of_arguments;
00076 w[0] = x0;
00077 }
00078 vectin(T x0, T x1) {
00079 typedef typename assert_<N, 2>::eval bad_number_of_arguments;
00080 w[0] = x0; w[1] = x1;
00081 }
00082 vectin(T x0, T x1, T x2) {
00083 typedef typename assert_<N, 3>::eval bad_number_of_arguments;
00084 w[0]=x0; w[1]=x1; w[2]=x2;
00085 }
00086 vectin(T x0, T x1, T x2, T x3) {
00087 typedef typename assert_<N, 4>::eval bad_number_of_arguments;
00088 w[0]=x0; w[1]=x1; w[2]=x2; w[3]=x3;
00089 }
00090 explicit vectin(const T* px) {
00091 for (int i = 0; i < N; ++i) w[i] = px[i];
00092 }
00093 vectin& operator=(vectin const& rhs) {
00094 for (int i = 0; i < N; ++i) w[i] = rhs.w[i];
00095 return *this;
00096 }
00097 template<typename U>
00098 vectin& operator=(vectin<U, 3> const& rhs) {
00099 for (int i = 0; i < N; ++i) w[i] = rhs.w[i];
00100 return *this;
00101 }
00102
00103 T& operator[](int i) { MORE_CHECKRNG(i, N); return w[i]; }
00104 T const& operator[](int i) const
00105 { MORE_CHECKRNG(i, N); return w[i]; }
00106 T& operator()(int i) { MORE_CHECKRNG(i, N); return w[i]; }
00107 T const& operator()(int i) const
00108 { MORE_CHECKRNG(i, N); return w[i]; }
00109 template<typename U>
00110 T& operator()(U const& i) { return (*this)(enumerator(i)); }
00111 template<typename U>
00112 T const& operator()(U const& i) const
00113 { return (*this)(enumerator(i)); }
00114
00115 vectin& operator+=(vectin const& rhs)
00116 { for (int i = 0; i < N; ++i) w[i] += rhs.w[i]; return *this; }
00117 vectin& operator-=(vectin const& rhs)
00118 { for (int i = 0; i < N; ++i) w[i] -= rhs.w[i]; return *this; }
00119 template<typename U>
00120 vectin& operator*=(const U& rhs)
00121 { for (int i = 0; i < N; ++i) w[i] *= rhs; return *this; }
00122 template<typename U>
00123 vectin& operator/=(const U& rhs)
00124 { for (int i = 0; i < N; ++i) w[i] /= rhs; return *this; }
00125
00126 static const int CTC_size = N;
00127 static int size() { return N; }
00128 void resize(int n) { assert(n == N); }
00129 static int size0() { return N; }
00130 void sync(io::syncstream& ios)
00131 { for (int i = 0; i < N; ++i) ios | w[i]; }
00132
00133 iterator begin() { return &w[0]; }
00134 iterator end() { return &w[0] + N; }
00135 const_iterator begin() const { return &w[0]; }
00136 const_iterator end() const { return &w[0] + N; }
00137 };
00138
00139 template <class T, int N> inline
00140 vectin<T, N> operator+(vectin<T, N> x, vectin<T, N> y) {
00141 vectin<T, N> v;
00142 for (int i = 0; i < N; i++) v[i] = x[i]+y[i];
00143 return v;
00144 }
00145 template <class T, int N> inline
00146 vectin<T, N> operator-(vectin<T, N> x, vectin<T, N> y) {
00147 vectin<T, N> v;
00148 for (int i = 0; i < N; i++) v[i] = x[i]-y[i];
00149 return v;
00150 }
00151 template <class T, int N>
00152 inline vectin<T, N> operator-(vectin<T, N> x) {
00153 vectin<T, N> v;
00154 for (int i = 0; i < N; i++) v[i] = -x[i];
00155 return v;
00156 }
00157 template <typename T, typename U, int N>
00158 inline vectin<typename times_type_<T, U>::eval, N>
00159 operator*(const vectin<T, N>& x, U y) {
00160 vectin<typename times_type_<T, U>::eval, N> v;
00161 for (int i = 0; i < N; i++) v[i] = x[i]*y;
00162 return v;
00163 }
00164 template <typename T, typename U, int N>
00165 inline vectin<typename times_type_<T, U>::eval, N>
00166 operator*(T y, const vectin<U, N>& x) {
00167 vectin<typename times_type_<T, U>::eval, N> v;
00168 for (int i = 0; i < N; i++) v[i] = x[i]*y;
00169 return v;
00170 }
00171 template <class T, int N>
00172 inline vectin<T, N> operator/(vectin<T, N> x, T y) {
00173 vectin<T, N> v;
00174 for (int i = 0; i < N; i++) v[i] = x[i]/y;
00175 return v;
00176 }
00177 template <class T, int N>
00178 inline bool operator<(vectin<T, N> x, vectin<T, N> y) {
00179 for (int i = 0; i < N; i++) {
00180 if (x[i] < y[i]) return true;
00181 else if (y[i] < x[i]) return false;
00182 }
00183 return false;
00184 }
00185 template <class T, int N>
00186 inline bool operator==(vectin<T, N> x, vectin<T, N> y) {
00187 for (int i = 0; i < N; i++)
00188 if (!(x[i] == y[i])) return false;
00189 return true;
00190 }
00191
00192 template <class T>
00193 vectin<T, 2> makevec(T x0, T x1)
00194 { return vectin<T, 2>(x0, x1); }
00195
00196 template <class T>
00197 vectin<T, 3> makevec(T x0, T x1, T x2)
00198 { return vectin<T, 3>(x0, x1, x2); }
00199
00200 template<typename T, int N>
00201 inline std::ostream& operator<<(std::ostream& os, vectin<T, N> x) {
00202 os << '(' << x(0);
00203 for (int i = 1; i < N; ++i) os << ", " << x(i);
00204 os << ')';
00205 return os;
00206 }
00207 }}
00208
00209 namespace more {
00210 namespace math {
00211 template<typename T, int N>
00212 struct norm_type_< num::vectin<T, N> >
00213 { typedef typename norm_type_<T>::eval eval; };
00214 template<typename T, int N>
00215 struct scalar_type_< num::vectin<T, N> >
00216 { typedef T eval; };
00217 template<typename T, int N>
00218 struct element_type_< num::vectin<T, N> >
00219 { typedef num::vectin<typename element_type_<T>::eval, N> eval; };
00220 }}
00221
00222 namespace more {
00223 namespace num {
00224 using more::math::norm;
00225
00226 template<typename T, int N>
00227 inline typename norm_type_<T>::eval
00228 metric_distance(vectin<T, N> const& x, vectin<T, N> const& y) {
00229 typename norm_type_<T>::eval res = norm(x(0) - y(0));
00230 for (int i = 1; i < N; ++i) res += norm(x(i) - y(i));
00231 return sqrt(res);
00232 }
00233 template<typename T, int N>
00234 inline typename norm_type_<T>::eval
00235 metric_norm(vectin<T, N> const& x, vectin<T, N> const& y) {
00236 typename norm_type_<T>::eval res = norm(x(0) - y(0));
00237 for (int i = 1; i < N; ++i) res += norm(x(i) - y(i));
00238 return res;
00239 }
00240 template<typename T, int N>
00241 inline typename norm_type_<T>::eval
00242 norm(vectin<T, N> const& x) {
00243 typename norm_type_<T>::eval res = norm(x(0));
00244 for (int i = 1; i < N; ++i) res += norm(x(i));
00245 return res;
00246 }
00247
00248 template<typename T, int N>
00249 inline typename norm_type_<T>::eval
00250 abs(vectin<T, N> const& x) { return sqrt(norm(x)); }
00251
00252 template<typename T, int N>
00253 inline int
00254 finite(vectin<T, N> const& x) { return finite(norm(x)); }
00255
00256 template<typename T, int N>
00257 inline T
00258 component(vectin<T, N> const& x, int i) { return x(i); }
00259
00260 template<typename T, int N>
00261 inline void
00262 swap(vectin<T, N>& x, vectin<T, N>& y)
00263 { for (int i = 0; i < N; ++i) swap(x[i], y[i]); }
00264
00265 template<typename T, int N>
00266 inline typename scalar_type_<T>::eval
00267 dot(vectin<T, N> const& x, vectin<T, N> const& y) {
00268 typename scalar_type_<T>::eval sum = 0;
00269 for (int i = 0; i < N; ++i) sum += dot(x(i), y(i));
00270 return sum;
00271 }
00272 template<typename T, typename U>
00273 inline vectin<typename times_type_<T, U>::eval, 3>
00274 crossprod(const vectin<T, 3>& x, const vectin<U, 3>& y) {
00275 return vectin<typename times_type_<T, U>::eval, 3>
00276 (x[1]*y[2]-x[2]*y[1], x[2]*y[0]-x[0]*y[2],
00277 x[0]*y[1]-x[1]*y[0]);
00278 }
00279 template<typename T, typename U, int N>
00280 inline typename times_type_<T, U>::eval
00281 dotprod(const vectin<T, N>& x, const vectin<U, N>& y) {
00282 typename times_type_<T, U>::eval sum = 0;
00283 for (int i = 0; i < N; ++i) sum += x(i)*y(i);
00284 return sum;
00285 }
00286
00287
00288
00289
00290 template<typename Position>
00291 struct euclidian_metric
00292 : std::binary_function< Position, Position,
00293 typename norm_type_<Position>::eval > {
00294 typename more::norm_type_<Position>::eval
00295 operator()(Position const& x, Position const& y) const {
00296 return std::sqrt(more::norm(x - y));
00297 }
00298 };
00299 }
00300 using namespace num;
00301 }
00302
00303 #undef MORE_CHECKRNG
00304 #endif