Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1702 - 1
/*
2
 * Vector.h
3
 * Copyright (C) James Goppert 2010 <james.goppert@gmail.com>
4
 *
5
 * This file is free software: you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License as published by the
7
 * Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This file is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 * See the GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License along
16
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18
 
19
#ifndef Vector_H
20
#define Vector_H
21
 
22
#include "../FastSerial/BetterStream.h"
23
#include <stdlib.h>
24
#include <inttypes.h>
25
#if defined(ARDUINO) && ARDUINO >= 100
26
        #include "Arduino.h"
27
#else
28
        #include <WProgram.h>
29
#endif
30
 
31
#ifdef ASSERT
32
const static char vectorSource[] ="Vector.hpp";
33
#endif
34
 
35
// vector
36
template <class dataType,class sumType=dataType>
37
class Vector
38
{
39
private:
40
    size_t size;
41
    size_t extraAllocationSize; // extra space to add after each allocation
42
    size_t sizeAllocated; // total allocated size
43
    dataType* data;
44
public:
45
    // default constructor
46
    Vector(const size_t & _size=0, const size_t & _extraAllocationSize=0) : size(0), extraAllocationSize(_extraAllocationSize), sizeAllocated(0), data(NULL) {
47
        setSize(_size);
48
    }
49
    // 3 vector constructor
50
    Vector(const dataType & a, const dataType & b, const dataType & c) : size(3), extraAllocationSize(extraAllocationSize), sizeAllocated(0), data(NULL) {
51
        setSize(size);
52
        (*this)[0]=a;
53
        (*this)[1]=b;
54
        (*this)[2]=c;
55
    }
56
 
57
    // construct from array
58
    Vector(const dataType* array, const size_t & _size, const size_t & _extraAllocationSize=0) : size(0), extraAllocationSize(_extraAllocationSize), sizeAllocated(0), data(NULL) {
59
        setSize(_size);
60
        for (size_t i=0; i<getSize(); i++)
61
            (*this)[i]=array[i];
62
    }
63
    // copy constructor
64
    Vector(const Vector &v) : size(0), extraAllocationSize(0), sizeAllocated(0), data(NULL) {
65
        setSize(v.getSize());
66
        for (size_t i=0; i<getSize(); i++)
67
            (*this)[i]=v[i];
68
    }
69
    // convert to float vector
70
    Vector<float> toFloat() const {
71
        Vector<float> v(getSize());
72
        for (size_t i=0; i<getSize(); i++)
73
            v[i]=(*this)[i];
74
        return v;
75
    }
76
    // destructor
77
    virtual ~Vector() {
78
        empty();
79
    }
80
    void empty() {
81
        if (data) delete [] data;
82
        data = NULL;
83
        sizeAllocated=0;
84
        size=0;
85
    }
86
    // set the size
87
    void setSize(const size_t & n) {
88
        if (n==0) {
89
            if (data) delete [] data;
90
            data = NULL;
91
            sizeAllocated=0;
92
        }
93
        if (n>sizeAllocated) {
94
            dataType * newData = new dataType[n+extraAllocationSize];
95
            memcpy(newData,data,sizeof(dataType)/sizeof(char)*getSize());
96
            memset(newData+size,0,sizeof(dataType)/sizeof(char)*(n-getSize()));
97
            delete[] data;
98
            data = newData;
99
            sizeAllocated=n+extraAllocationSize;
100
        }
101
        size=n;
102
    }
103
    // return size
104
    const size_t & getSize() const {
105
        return size;
106
    }
107
    // insert
108
    void insert(const size_t index, const dataType value) {
109
        //Serial.println("insert called");
110
#ifdef ASSERT
111
        assert(index<size+1,vectorSource,__LINE__);
112
#endif
113
        //Serial.print("Old Size: ");
114
        //Serial.println(getSize());
115
        setSize(getSize()+1);
116
        //Serial.print("New Size: ");
117
        //Serial.println(getSize());
118
        //Serial.print("Size of dataType");
119
        //Serial.println(sizeof(dataType));
120
        if (index != getSize()-1) {
121
            memmove(data+index+1,data+index,sizeof(dataType)/sizeof(char)*(getSize()-1-index));
122
            //Serial.println("memmove called and completed");
123
        }
124
        (*this)[index]=value;
125
        //Serial.println("insert done");
126
    }
127
    // remove
128
    void remove(const size_t & index) {
129
#ifdef ASSERT
130
        assert(index<size,vectorSource,__LINE__);
131
#endif
132
        memmove(data+index,data+index+1,getSize()-index-1);
133
        setSize(getSize()-1);
134
    }
135
    // push_back
136
    void push_back(const dataType & value) {
137
        //Serial.println("push_back called");
138
        insert(getSize(),value);
139
        //Serial.println("push_back done");
140
    }
141
    // pop_front
142
    dataType & pop_front() {
143
        dataType tmp = (*this)[0];
144
        remove(0);
145
        return tmp;
146
    }
147
    // push_back a vector
148
    void push_back(const Vector & vector) {
149
        for (size_t i=0; i<vector.getSize(); i++)
150
            push_back(vector[i]);
151
    }
152
    // const array access operator
153
    const dataType & operator[](const size_t & index) const {
154
#ifdef ASSERT
155
        assert(index<getSize(),vectorSource,__LINE__);
156
#endif
157
        return data[index];
158
    }
159
    // array access operator
160
    dataType & operator[](const size_t & index) {
161
#ifdef ASSERT
162
        assert(index<getSize(),vectorSource,__LINE__);
163
#endif
164
        return data[index];
165
    }
166
    // assignment operator
167
    Vector & operator=(const Vector & v) {
168
        setSize(v.getSize());
169
        for (size_t i=0; i<getSize(); i++)
170
            (*this)[i]=v[i];
171
        return *this;
172
    }
173
    // equal
174
    const bool operator==(const Vector& v) const {
175
#ifdef ASSERT
176
        assert(getSize()==v.getSize(),vectorSource,__LINE__);
177
#endif
178
        for (size_t i=0; i<getSize(); i++) {
179
            if ((*this)[i]!=v[i]) return false;
180
        }
181
        return true;
182
    }
183
    // not equal
184
    const bool operator!=(const Vector& v) const {
185
        return !((*this)==v);
186
    }
187
    // addition
188
    const Vector operator+(const Vector& v) const {
189
#ifdef ASSERT
190
        assert(v.getSize() == getSize(),vectorSource,__LINE__);
191
#endif
192
        Vector result(getSize());
193
        for (size_t i=0; i<getSize(); i++)
194
            result(i)=(*this)[i]+v[i];
195
        return result;
196
    }
197
    // addition
198
    const Vector operator+(const dataType& s) const {
199
        Vector result(getSize());
200
        for (size_t i=0; i<getSize(); i++)
201
            result[i]=(*this)[i]+s;
202
        return result;
203
    }
204
    // subtraction
205
    const Vector operator-(const Vector& v) const {
206
#ifdef ASSERT
207
        assert(v.getSize() == getSize(),vectorSource,__LINE__);
208
#endif
209
        Vector result(getSize());
210
        for (size_t i=0; i<getSize(); i++)
211
            result[i]=(*this)[i]-v[i];
212
        return result;
213
    }
214
    // negation
215
    const Vector operator-() const {
216
        Vector result(getSize());
217
        for (size_t i=0; i<getSize(); i++)
218
            result[i]=-(*this)[i];
219
        return result;
220
    }
221
    // +=
222
    Vector& operator+=(const Vector& v) {
223
#ifdef ASSERT
224
        assert(v.getSize() == getSize(),vectorSource,__LINE__);
225
#endif
226
        Vector result(getSize());
227
        for (size_t i=0; i<getSize(); i++)
228
            (*this)(i)+=v(i);
229
        return *this;
230
    }
231
    // -=
232
    Vector& operator-=( const Vector& v) {
233
#ifdef ASSERT
234
        assert(v.getSize() == getSize(),vectorSource,__LINE__);
235
#endif
236
        Vector result(getSize());
237
        for (size_t i=0; i<getSize(); i++)
238
            (*this)(i)-=v(i);
239
        return *this;
240
    }
241
    // elementwise  mult.
242
    const Vector operator*(const Vector & v) const {
243
        Vector result(getSize());
244
        for (size_t i=0; i<getSize(); i++)
245
            result(i)=(*this)(i)*v(i);
246
        return result;
247
    }
248
 
249
    // mult. by a scalar
250
    const Vector operator*(const dataType & s) const {
251
        Vector result(getSize());
252
        for (size_t i=0; i<getSize(); i++)
253
            result(i)=(*this)(i)*s;
254
        return result;
255
    }
256
    // div. by a scalar
257
    const Vector operator/(const dataType & s) const {
258
        Vector result(getSize());
259
        for (size_t i=0; i<getSize(); i++)
260
            result(i)=(*this)(i)/s;
261
        return result;
262
    }
263
    // elementwise div.
264
    const Vector operator/(const Vector & v) const {
265
        Vector result(getSize());
266
        for (size_t i=0; i<getSize(); i++)
267
            result(i)=(*this)(i)/v(i);
268
        return result;
269
    }
270
 
271
    // div. by a scalar
272
    Vector & operator/=(const dataType & s) {
273
        for (size_t i=0; i<getSize(); i++)
274
            (*this)(i)/=s;
275
        return *this;
276
    }
277
    // mult. by a scalar
278
    Vector & operator*=(const dataType & s) {
279
        for (size_t i=0; i<getSize(); i++)
280
            (*this)(i)*=s;
281
        return *this;
282
    }
283
    // cross/vector product
284
    const Vector cross(const Vector& v) const {
285
        Vector result(3), u=*this;
286
#ifdef ASSERT
287
        assert(u.getSize()==3 && v.getSize()==3,vectorSource,__LINE__);
288
#endif
289
        result(0) = u(1)*v(2)-u(2)*v(1);
290
        result(1) = -u(0)*v(2)+u(2)*v(0);
291
        result(2) = u(0)*v(1)-u(1)*v(0);
292
        return result;
293
    }
294
    // dot/scalar product
295
    const dataType dot(const Vector& v) const {
296
#ifdef ASSERT
297
        assert(getSize()==v.getSize(),vectorSource,__LINE__);
298
#endif
299
        dataType result;
300
        for (size_t i=0; i<getSize(); i++) result += (*this)(i)*v(i);
301
        return result;
302
    }
303
    // norm
304
    const dataType norm() const {
305
        return sqrt(dot(*this));
306
    }
307
    // unit vector
308
    const Vector unit() const {
309
        return (*this)*(1/norm());
310
    }
311
    // sum
312
    const sumType sum(const size_t & start=0,const int & end=-1) const {
313
        size_t end2;
314
        if (end==-1) end2=getSize()-1;
315
        else end2=end;
316
        sumType _sum = 0;
317
        for (size_t i=start; i<=end2; i++) _sum += (*this)(i);
318
        return _sum;
319
    }
320
    void sumFletcher(uint8_t & CK_A, uint8_t & CK_B, const size_t & start=0,const int & end=-1) const {
321
        size_t end2;
322
        if (end==-1) end2=getSize()-1;
323
        else end2=end;
324
 
325
        for (size_t i = start; i<=end2; i++) {
326
            CK_A += (*this)(i);
327
            CK_B += CK_A;
328
        }
329
    }
330
    // range
331
    const Vector range(const size_t & start, const size_t & stop) const {
332
        Vector v(stop-start+1);
333
        for (size_t i=start; i<=stop; i++) v(i-start) = (*this)(i);
334
        return v;
335
    }
336
    // to Array
337
    const dataType* toArray() const {
338
        dataType array[getSize()];
339
        for (size_t i=0; i<getSize(); i++) array[i] = (*this)(i);
340
        return array;
341
    }
342
    // printing
343
    void print(Stream & serial=Serial, const char * msg="", size_t format=0) const {
344
        serial.print(msg);
345
        for (size_t i=0; i<getSize(); i++) {
346
            serial.print((*this)(i),format);
347
            serial.print(" ");
348
        }
349
        serial.println();
350
    }
351
    // self test
352
    static bool selfTest(Stream & serial=Serial) {
353
        serial.println("Vector self test.");
354
        Vector u(3),v(3),w(3);
355
        u(0) = 1;
356
        u(1) = 2;
357
        u(2) = 3;
358
        v(0) = -4;
359
        v(1) = -5;
360
        v(2) = -6;
361
        u.print(serial,"u: ");
362
        v.print(serial,"v: ");
363
        (u+v).print(serial,"u + v: ");
364
        (u-v).print(serial,"u - v: ");
365
        Serial.print("u dot v: ");
366
        Serial.println(u.dot(v));
367
        Serial.print("size of u: ");
368
        Serial.println(u.getSize());
369
        Serial.print("size of v: ");
370
        Serial.println(v.getSize());
371
        w=u.cross(v);
372
        w.print(serial,"u cross v: ");
373
        Serial.print("size of u cross v: ");
374
        Serial.println(w.getSize());
375
        return true;
376
    }
377
 
378
};
379
 
380
#endif
381
 
382
// vim:ts=4:sw=4:expandtab