]> git.tdb.fi Git - libs/math.git/blob - source/linal/vector.h
392e3a12772dcdc6e3b9f12dba937c7d38779e29
[libs/math.git] / source / linal / vector.h
1 #ifndef MSP_LINAL_VECTOR_H_
2 #define MSP_LINAL_VECTOR_H_
3
4 #include <algorithm>
5 #include <cmath>
6
7 namespace Msp {
8 namespace LinAl {
9
10 /**
11 A general mathematical vector.
12 */
13 template<typename T, unsigned N>
14 class Vector
15 {
16 protected:
17         T data[N];
18
19 public:
20         Vector();
21         Vector(const T *d);
22         template<typename U>
23         Vector(const Vector<U, N> &v);
24
25         T &operator[](unsigned i) { return data[i]; }
26         const T &operator[](unsigned i) const { return data[i]; }
27
28         Vector &operator*=(T);
29         Vector &operator/=(T);
30         Vector &operator+=(const Vector &);
31         Vector &operator-=(const Vector &);
32
33         T norm() const;
34         Vector &normalize();
35 };
36
37
38 template<typename T, unsigned N>
39 inline Vector<T, N>::Vector()
40 {
41         std::fill(data, data+N, T());
42 }
43
44 template<typename T, unsigned N>
45 inline Vector<T, N>::Vector(const T *d)
46 {
47         std::copy(d, d+N, data);
48 }
49
50 template<typename T, unsigned N>
51 template<typename U>
52 inline Vector<T, N>::Vector(const Vector<U, N> &v)
53 {
54         std::copy(v.data, v.data+N, data);
55 }
56
57 template<typename T, unsigned N>
58 inline Vector<T, N> &Vector<T, N>::operator*=(T s)
59 {
60         for(unsigned i=0; i<N; ++i)     
61                 data[i] *= s;
62         return *this;
63 }
64
65 template<typename T, unsigned N>
66 inline Vector<T, N> operator*(const Vector<T, N> &v, T s)
67 {
68         Vector<T, N> r(v);
69         return r *= s;
70 }
71
72 template<typename T, unsigned N>
73 inline Vector<T, N> operator*(T s, const Vector<T, N> &v)
74 {
75         return v*s;
76 }
77
78 template<typename T, unsigned N>
79 inline Vector<T, N> &Vector<T, N>::operator/=(T s)
80 {
81         for(unsigned i=0; i<N; ++i)     
82                 data[i] /= s;
83         return *this;
84 }
85
86 template<typename T, unsigned N>
87 inline Vector<T, N> operator/(const Vector<T, N> &v, T s)
88 {
89         Vector<T, N> r(v);
90         return r /= s;
91 }
92
93 template<typename T, unsigned N>
94 inline Vector<T, N> &Vector<T, N>::operator+=(const Vector<T, N> &v)
95 {
96         for(unsigned i=0; i<N; ++i)     
97                 data[i] += v[i];
98         return *this;
99 }
100
101 template<typename T, unsigned N>
102 inline Vector<T, N> operator+(const Vector<T, N> &v1, const Vector<T, N> &v2)
103 {
104         Vector<T, N> r(v1);
105         return r += v2;
106 }
107
108 template<typename T, unsigned N>
109 inline Vector<T, N> &Vector<T, N>::operator-=(const Vector<T, N> &v)
110 {
111         for(unsigned i=0; i<N; ++i)     
112                 data[i] -= v[i];
113         return *this;
114 }
115
116 template<typename T, unsigned N>
117 inline Vector<T, N> operator-(const Vector<T, N> &v1, const Vector<T, N> &v2)
118 {
119         Vector<T, N> r(v1);
120         return r -= v2;
121 }
122
123 template<typename T, unsigned N>
124 inline Vector<T, N> operator-(const Vector<T, N> &v)
125 {
126         Vector<T, N> r(v);
127         for(unsigned i=0; i<N; ++i)
128                 r[i] = -r[i];
129         return r;
130 }
131
132 template<typename T, unsigned N>
133 inline bool operator==(const Vector<T, N> &v, const Vector<T, N> &w)
134 {
135         for(unsigned i=0; i<N; ++i)
136                 if(v[i]!=w[i])
137                         return false;
138         return true;
139 }
140
141 template<typename T, unsigned N>
142 inline T inner_product(const Vector<T, N> &v1, const Vector<T, N> &v2)
143 {
144         T r = T();
145         for(unsigned i=0; i<N; ++i)
146                 r += v1[i]*v2[i];
147         return r;
148 }
149
150 template<typename T, unsigned N>
151 inline T Vector<T, N>::norm() const
152 {
153         return sqrt(inner_product(*this, *this));
154 }
155
156 template<typename T, unsigned N>
157 inline Vector<T, N> &Vector<T, N>::normalize()
158 {
159         return *this /= norm();
160 }
161
162 template<typename T, unsigned N>
163 inline Vector<T, N> normalize(const Vector<T, N> &v)
164 {
165         Vector<T, N> r(v);
166         return r.normalize();
167 }
168
169 } // namespace LinAl
170 } // namespace Msp
171
172 #endif