--- /dev/null
+#ifndef MSP_LINAL_VECTOR_H_
+#define MSP_LINAL_VECTOR_H_
+
+#include <algorithm>
+#include <cmath>
+
+namespace Msp {
+namespace LinAl {
+
+/**
+A general mathematical vector.
+*/
+template<typename T, unsigned N>
+class Vector
+{
+protected:
+ T data[N];
+
+public:
+ Vector();
+ Vector(const T *d);
+ template<typename U>
+ Vector(const Vector<U, N> &v);
+
+ T &operator[](unsigned i);
+ const T &operator[](unsigned i) const;
+
+ Vector &operator*=(T);
+ Vector &operator/=(T);
+ Vector &operator+=(const Vector &);
+ Vector &operator-=(const Vector &);
+
+ T norm() const;
+ Vector &normalize();
+};
+
+
+template<typename T, unsigned N>
+inline Vector<T, N>::Vector()
+{
+ std::fill(data, data+N, T());
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N>::Vector(const T *d)
+{
+ std::copy(d, d+N, data);
+}
+
+template<typename T, unsigned N>
+template<typename U>
+inline Vector<T, N>::Vector(const Vector<U, N> &v)
+{
+ std::copy(v.data, v.data+N, data);
+}
+
+template<typename T, unsigned N>
+T &Vector<T, N>::operator[](unsigned i)
+{
+ return data[i];
+}
+
+template<typename T, unsigned N>
+const T &Vector<T, N>::operator[](unsigned i) const
+{
+ return data[i];
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> &Vector<T, N>::operator*=(T s)
+{
+ for(unsigned i=0; i<N; ++i)
+ data[i] *= s;
+ return *this;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator*(const Vector<T, N> &v, T s)
+{
+ Vector<T, N> r(v);
+ return r *= s;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator*(T s, const Vector<T, N> &v)
+{
+ return v*s;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> &Vector<T, N>::operator/=(T s)
+{
+ for(unsigned i=0; i<N; ++i)
+ data[i] /= s;
+ return *this;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator/(const Vector<T, N> &v, T s)
+{
+ Vector<T, N> r(v);
+ return r /= s;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> &Vector<T, N>::operator+=(const Vector<T, N> &v)
+{
+ for(unsigned i=0; i<N; ++i)
+ data[i] += v[i];
+ return *this;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator+(const Vector<T, N> &v1, const Vector<T, N> &v2)
+{
+ Vector<T, N> r(v1);
+ return r += v2;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> &Vector<T, N>::operator-=(const Vector<T, N> &v)
+{
+ for(unsigned i=0; i<N; ++i)
+ data[i] -= v[i];
+ return *this;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator-(const Vector<T, N> &v1, const Vector<T, N> &v2)
+{
+ Vector<T, N> r(v1);
+ return r -= v2;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator-(const Vector<T, N> &v)
+{
+ Vector<T, N> r(v);
+ for(unsigned i=0; i<N; ++i)
+ r[i] = -r[i];
+ return r;
+}
+
+template<typename T, unsigned N>
+inline T inner_product(const Vector<T, N> &v1, const Vector<T, N> &v2)
+{
+ T r = T();
+ for(unsigned i=0; i<N; ++i)
+ r += v1[i]*v2[i];
+ return r;
+}
+
+template<typename T, unsigned N>
+inline T Vector<T, N>::norm() const
+{
+ return sqrt(inner_product(*this, *this));
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> &Vector<T, N>::normalize()
+{
+ return *this /= norm();
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> normalize(const Vector<T, N> &v)
+{
+ Vector<T, N> r(v);
+ return r.normalize();
+}
+
+} // namespace LinAl
+} // namespace Msp
+
+#endif