]> git.tdb.fi Git - libs/math.git/blobdiff - source/linal/vector.h
Rename the library to mspmath and make linal a sublibrary
[libs/math.git] / source / linal / vector.h
diff --git a/source/linal/vector.h b/source/linal/vector.h
new file mode 100644 (file)
index 0000000..933611e
--- /dev/null
@@ -0,0 +1,175 @@
+#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