--- /dev/null
+#ifndef MSP_LINAL_DYNAMICVECTOR_H_
+#define MSP_LINAL_DYNAMICVECTOR_H_
+
+#include <algorithm>
+#include <cmath>
+#include <stdexcept>
+
+namespace Msp {
+namespace LinAl {
+
+class size_mismatch: public std::logic_error
+{
+public:
+ size_mismatch(const std::string &w): std::logic_error(w) { }
+ virtual ~size_mismatch() throw() { }
+};
+
+
+/**
+A general mathematical vector. Size is specified at runtime. May be slower
+than a fixed-size vector. There are no compile-time diagnostics for mismatched
+vector sizes.
+*/
+template<typename T>
+class DynamicVector
+{
+public:
+ typedef T ElementType;
+
+private:
+ unsigned size_;
+ T *data;
+
+public:
+ DynamicVector(unsigned);
+ DynamicVector(unsigned, const T *);
+ DynamicVector(const DynamicVector &);
+ DynamicVector &operator=(const DynamicVector &);
+ ~DynamicVector();
+
+ unsigned size() const { return size_; }
+
+ T &operator[](unsigned);
+ const T &operator[](unsigned) const;
+
+ DynamicVector &operator*=(T);
+ DynamicVector &operator/=(T);
+ DynamicVector &operator+=(const DynamicVector &);
+ DynamicVector &operator-=(const DynamicVector &);
+
+ T norm() const;
+ DynamicVector &normalize();
+};
+
+template<typename T>
+inline DynamicVector<T>::DynamicVector(unsigned s):
+ size_(s),
+ data(new T[size_])
+{
+ std::fill(data, data+size_, T());
+}
+
+template<typename T>
+inline DynamicVector<T>::DynamicVector(unsigned s, const T *d):
+ size_(s),
+ data(new T[size_])
+{
+ std::copy(d, d+size_, data);
+}
+
+template<typename T>
+inline DynamicVector<T>::DynamicVector(const DynamicVector &other):
+ size_(other.size()),
+ data(new T[size_])
+{
+ std::copy(other.data, other.data+size_, data);
+}
+
+template<typename T>
+inline DynamicVector<T> &DynamicVector<T>::operator=(const DynamicVector<T> &other)
+{
+ if(size_!=other.size())
+ {
+ delete[] data;
+ size_ = other.size();
+ data = new T[size_];
+ }
+
+ std::copy(other.data, other.data+size_, data);
+
+ return *this;
+}
+
+template<typename T>
+inline DynamicVector<T>::~DynamicVector()
+{
+ delete[] data;
+}
+
+template<typename T>
+inline T &DynamicVector<T>::operator[](unsigned i)
+{
+ if(i>=size_)
+ throw std::out_of_range("DynamicVector::operator[]");
+
+ return data[i];
+}
+
+template<typename T>
+inline const T &DynamicVector<T>::operator[](unsigned i) const
+{
+ if(i>=size_)
+ throw std::out_of_range("DynamicVector::operator[]");
+
+ return data[i];
+}
+
+template<typename T>
+inline DynamicVector<T> &DynamicVector<T>::operator*=(T s)
+{
+ for(unsigned i=0; i<size_; ++i)
+ data[i] *= s;
+ return *this;
+}
+
+template<typename T>
+inline DynamicVector<T> operator*(const DynamicVector<T> &v, T s)
+{
+ DynamicVector<T> r(v);
+ return r *= s;
+}
+
+template<typename T>
+inline DynamicVector<T> operator*(T s, const DynamicVector<T> &v)
+{
+ return v*s;
+}
+
+template<typename T>
+inline DynamicVector<T> &DynamicVector<T>::operator/=(T s)
+{
+ for(unsigned i=0; i<size_; ++i)
+ data[i] /= s;
+ return *this;
+}
+
+template<typename T>
+inline DynamicVector<T> operator/(const DynamicVector<T> &v, T s)
+{
+ DynamicVector<T> r(v);
+ return r /= s;
+}
+
+template<typename T>
+inline DynamicVector<T> &DynamicVector<T>::operator+=(const DynamicVector<T> &v)
+{
+ if(size_!=v.size())
+ throw size_mismatch("vector+vector");
+
+ for(unsigned i=0; i<size_; ++i)
+ data[i] += v.data[i];
+
+ return *this;
+}
+
+template<typename T>
+inline DynamicVector<T> operator+(const DynamicVector<T> &v1, const DynamicVector<T> &v2)
+{
+ DynamicVector<T> r(v1);
+ return r += v2;
+}
+
+template<typename T>
+inline DynamicVector<T> &DynamicVector<T>::operator-=(const DynamicVector<T> &v)
+{
+ if(size_!=v.size())
+ throw size_mismatch("vector-vector");
+
+ for(unsigned i=0; i<size_; ++i)
+ data[i] -= v.data[i];
+
+ return *this;
+}
+
+template<typename T>
+inline DynamicVector<T> operator-(const DynamicVector<T> &v1, const DynamicVector<T> &v2)
+{
+ DynamicVector<T> r(v1);
+ return r -= v2;
+}
+
+template<typename T>
+inline DynamicVector<T> operator-(const DynamicVector<T> &v)
+{
+ DynamicVector<T> r(v);
+ for(unsigned i=0; i<r.size(); ++i)
+ r[i] = -r[i];
+ return r;
+}
+
+template<typename T>
+inline bool operator==(const DynamicVector<T> &v1, const DynamicVector<T> &v2)
+{
+ if(v1.size()!=v2.size())
+ throw size_mismatch("vector==vector");
+
+ for(unsigned i=0; i<v1.size(); ++i)
+ if(v1[i]!=v2[i])
+ return false;
+
+ return true;
+}
+
+template<typename T>
+inline T inner_product(const DynamicVector<T> &v1, const DynamicVector<T> &v2)
+{
+ if(v1.size()!=v2.size())
+ throw size_mismatch("inner_product");
+
+ T r = T();
+ for(unsigned i=0; i<v1.size(); ++i)
+ r += v1[i]*v2[i];
+ return r;
+}
+
+template<typename T>
+inline T DynamicVector<T>::norm() const
+{
+ using std::sqrt;
+ return sqrt(inner_product(*this, *this));
+}
+
+template<typename T>
+inline DynamicVector<T> &DynamicVector<T>::normalize()
+{
+ return *this /= norm();
+}
+
+template<typename T>
+inline DynamicVector<T> normalize(const DynamicVector<T> &v)
+{
+ DynamicVector<T> r(v);
+ return r.normalize();
+}
+
+} // namespace LinAL
+} // namespace Msp
+
+#endif