source: foam/trunk/vision/src/Matrix.h @ 89

Revision 89, 7.8 KB checked in by dave, 11 years ago (diff)

renamed faceident as it's not so simple these days

Line 
1// Copyright (C) 2009 foam
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation; either version 2 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16
17#include <assert.h>
18#include <iostream>
19#include "Vector.h"
20
21#ifndef FOAM_MATRIX
22#define FOAM_MATRIX
23
24template<class T>
25class Matrix
26{
27public:
28        Matrix();
29        Matrix(unsigned int r, unsigned int c);
30        ~Matrix();
31        Matrix(const Matrix &other);
32        Matrix(unsigned int r, unsigned int c, float *data);
33
34        // Row proxy classes to allow matrix[r][c] notation
35        class Row
36        {
37        public:
38                Row(Matrix *owner, unsigned int r)
39                {
40                        m_Data=&owner->GetRawData()[r*owner->GetCols()];
41                        m_Cols=owner->GetCols();
42                }
43               
44                T &operator[](unsigned int c)
45                {
46                        assert(c<m_Cols);
47                        return m_Data[c];
48                }
49               
50        private:
51                T *m_Data;
52                unsigned int m_Cols;
53        };
54
55        class ConstRow
56        {
57        public:
58                ConstRow(const Matrix *owner, unsigned int r)
59                {
60                        m_Data=&owner->GetRawDataConst()[r*owner->GetCols()];
61                        m_Cols=owner->GetCols();
62                }
63               
64                const T &operator[](unsigned int c) const
65                {
66                        assert(c<m_Cols);
67                        return m_Data[c];
68                }
69               
70        private:
71                const T *m_Data;
72                unsigned int m_Cols;
73        };
74
75       
76        Row operator[](unsigned int r)
77        {
78                assert(r<m_Rows);
79                return Row(this,r);
80        }
81
82        ConstRow operator[](unsigned int r) const
83        {
84                assert(r<m_Rows);
85                return ConstRow(this,r);
86        }
87 
88        unsigned int GetRows() const { return m_Rows; }
89        unsigned int GetCols() const { return m_Cols; }
90        T *GetRawData() { return m_Data; }
91        const T *GetRawDataConst() const { return m_Data; }
92        Vector<T> GetRowVector(unsigned int r) const;
93        Vector<T> GetColVector(unsigned int c) const;
94        void SetRowVector(unsigned int r, const Vector<T> &row);
95        void SetColVector(unsigned int c, const Vector<T> &col);
96         
97        void Print() const;
98        void SetAll(T s);
99        void Zero() { SetAll(0); }
100        bool IsInf();
101        Matrix Transposed();
102
103        Matrix &operator=(const Matrix &other);
104        Matrix operator+(const Matrix &other) const;
105        Matrix operator-(const Matrix &other) const;
106        Matrix operator*(const Matrix &other) const;
107        Matrix &operator+=(const Matrix &other);
108        Matrix &operator-=(const Matrix &other);
109        Matrix &operator*=(const Matrix &other);
110       
111        void SortRows(Vector<T> &v);
112        void SortCols(Vector<T> &v);
113
114        static void RunTests();
115       
116private:
117
118        unsigned int m_Rows;
119        unsigned int m_Cols;
120       
121        T *m_Data;
122       
123};
124
125template<class T>
126Matrix<T>::Matrix(unsigned int r, unsigned int c) :
127m_Rows(r),
128m_Cols(c)
129{
130        m_Data=new T[r*c];
131}
132
133template<class T>
134Matrix<T>::Matrix() :
135m_Rows(0),
136m_Cols(0),
137m_Data(NULL)
138{
139}
140
141template<class T>
142Matrix<T>::Matrix(unsigned int r, unsigned int c, float *data) :
143m_Rows(r),
144m_Cols(c),
145m_Data(data)
146{
147}
148
149template<class T>
150Matrix<T>::~Matrix()
151{
152        delete[] m_Data;
153}
154
155template<class T>
156Matrix<T>::Matrix(const Matrix &other)
157{
158        m_Rows = other.m_Rows;
159        m_Cols = other.m_Cols;
160        m_Data=new T[m_Rows*m_Cols];
161        memcpy(m_Data,other.m_Data,m_Rows*m_Cols*sizeof(T));
162}
163
164template<class T>
165Matrix<T> &Matrix<T>::operator=(const Matrix &other)
166{
167        if (m_Data!=NULL)
168        {
169                delete[] m_Data;
170        }
171       
172        m_Rows = other.m_Rows;
173        m_Cols = other.m_Cols;
174        m_Data=new T[m_Rows*m_Cols];
175        memcpy(m_Data,other.m_Data,m_Rows*m_Cols*sizeof(T));
176       
177        return *this;
178}
179
180template<class T>
181void Matrix<T>::Print() const
182{
183        for (unsigned int i=0; i<m_Rows; i++)
184        {
185                for (unsigned int j=0; j<m_Cols; j++)
186                {
187                        std::cerr<<(*this)[i][j]<<" ";
188                }
189                std::cerr<<std::endl;
190        }
191}
192
193template<class T>
194void Matrix<T>::SetAll(T s)
195{
196        for (unsigned int i=0; i<m_Rows; i++)
197        {
198                for (unsigned int j=0; j<m_Cols; j++)
199                {
200                        (*this)[i][j]=s;
201                }
202        }
203}
204
205template<class T>
206bool Matrix<T>::IsInf()
207{
208        for (unsigned int i=0; i<m_Rows; i++)
209        {
210                for (unsigned int j=0; j<m_Cols; j++)
211                {
212                        if (isinf((*this)[i][j])) return true;
213                        if (isnan((*this)[i][j])) return true;
214                }
215        }
216        return false;
217}
218
219template<class T>
220Matrix<T> Matrix<T>::Transposed()
221{
222        Matrix<T> copy(*this);
223        for (unsigned int i=0; i<m_Rows; i++)
224        {
225                for (unsigned int j=0; j<m_Cols; j++)
226                {
227                        copy[i][j]=(*this)[j][i];
228                }
229        }
230        return copy;
231}
232
233
234template<class T>
235Matrix<T> Matrix<T>::operator+(const Matrix &other) const
236{
237        assert(m_Rows=other.m_Rows);
238        assert(m_Cols=other.m_Cols);
239       
240        Matrix<T> ret(m_Rows,m_Cols);
241        for (unsigned int i=0; i<m_Rows; i++)
242        {
243                for (unsigned int j=0; j<m_Cols; j++)
244                {
245                        ret[i][j]=(*this)[i][j]+other[i][j];
246                }
247        }
248        return ret;
249}
250
251template<class T>
252Matrix<T> Matrix<T>::operator-(const Matrix &other) const
253{
254        assert(m_Rows=other.m_Rows);
255        assert(m_Cols=other.m_Cols);
256       
257        Matrix<T> ret(m_Rows,m_Cols);
258        for (unsigned int i=0; i<m_Rows; i++)
259        {
260                for (unsigned int j=0; j<m_Cols; j++)
261                {
262                        ret[i][j]=(*this)[i][j]-other[i][j];
263                }
264        }
265        return ret;
266}
267
268template<class T>
269Matrix<T> Matrix<T>::operator*(const Matrix &other) const
270{
271        assert(m_Cols==other.m_Rows);
272       
273        Matrix<T> ret(m_Rows,other.m_Cols);
274       
275        for (unsigned int i=0; i<m_Rows; i++)
276        {
277                for (unsigned int j=0; j<other.m_Cols; j++)
278                {
279                        ret[i][j]=0;
280                        for (unsigned int k=0; k<m_Cols; k++)
281                        {
282                                ret[i][j]+=(*this)[i][k]*other[k][j];
283                        }
284                }
285        }
286        return ret;
287}
288
289template<class T>
290Matrix<T> &Matrix<T>::operator+=(const Matrix &other)
291{
292        (*this)=(*this)+other;
293        return *this;
294}
295
296template<class T>
297Matrix<T> &Matrix<T>::operator-=(const Matrix &other)
298{
299        (*this)=(*this)-other;
300        return *this;
301}
302
303template<class T>
304Matrix<T> &Matrix<T>::operator*=(const Matrix &other)
305{
306        (*this)=(*this)*other;
307        return *this;
308}
309
310
311//todo: use memcpy for these 4 functions
312template<class T>
313Vector<T> Matrix<T>::GetRowVector(unsigned int r) const
314{
315        assert(r<m_Rows);
316        Vector<T> ret(m_Cols);
317        for (unsigned int j=0; j<m_Cols; j++)
318        {
319                ret[j]=(*this)[r][j];
320        }
321        return ret;
322}
323
324template<class T>
325Vector<T> Matrix<T>::GetColVector(unsigned int c) const
326{
327        assert(c<m_Cols);
328        Vector<T> ret(m_Rows);
329        for (unsigned int i=0; i<m_Rows; i++)
330        {
331                ret[i]=(*this)[i][c];
332        }
333        return ret;
334}
335
336template<class T>
337void Matrix<T>::SetRowVector(unsigned int r, const Vector<T> &row)
338{
339        assert(r<m_Rows);
340        assert(row.Size()==m_Cols);
341        for (unsigned int j=0; j<m_Cols; j++)
342        {
343                (*this)[r][j]=row[j];
344        }
345}
346
347template<class T>
348void Matrix<T>::SetColVector(unsigned int c, const Vector<T> &col)
349{
350        assert(c<m_Cols);
351        assert(col.Size()==m_Rows);
352        for (unsigned int i=0; i<m_Rows; i++)
353        {
354                (*this)[i][c]=col[i];
355        }
356}
357
358// sort rows by v
359template<class T>
360void Matrix<T>::SortRows(Vector<T> &v)
361{
362        assert(v.Size()==m_Rows);
363       
364        bool sorted=false;
365        while(!sorted)
366        {
367                sorted=true;
368               
369                for (unsigned int i=0; i<v.Size()-1; i++)
370                {
371                        if (v[i]<v[i+1])
372                        {
373                                sorted=false;
374                                float vtmp = v[i];
375                                v[i]=v[i+1];
376                                v[i+1]=vtmp;
377                               
378                                Vector<float> rtmp = GetRowVector(i);
379                                SetRowVector(i,GetRowVector(i+1));
380                                SetRowVector(i+1,rtmp);
381                        }
382                }
383        }
384}
385
386// sort cols by v
387template<class T>
388void Matrix<T>::SortCols(Vector<T> &v)
389{
390        assert(v.Size()==m_Cols);
391       
392        bool sorted=false;
393        while(!sorted)
394        {
395                sorted=true;
396               
397                for (unsigned int i=0; i<v.Size()-1; i++)
398                {
399                        if (v[i]<v[i+1])
400                        {
401                                sorted=false;
402                                float vtmp = v[i];
403                                v[i]=v[i+1];
404                                v[i+1]=vtmp;
405                               
406                                Vector<float> rtmp = GetColVector(i);
407                                SetColVector(i,GetColVector(i+1));
408                                SetColVector(i+1,rtmp);
409                        }
410                }
411        }
412}
413
414
415template<class T>
416void Matrix<T>::RunTests()
417{
418        Matrix<T> m(10,10);
419        m.SetAll(0);
420        assert(m[0][0]==0);
421        m[5][2]=0.5;
422        assert(m[5][2]==0.5);
423        Matrix<T> om(m);
424        assert(om[5][2]==0.5);
425        Matrix<T> a(2,3);
426        a[0][0]=1; a[0][1]=2; a[0][2]=3;
427        a[1][0]=4; a[1][1]=5; a[1][2]=6;
428        Matrix<T> b(3,1);
429        b[0][0]=3;
430        b[1][0]=1;
431        b[2][0]=2;
432        Matrix<T> c=a*b;
433        assert(c[0][0]==11 && c[1][0]==29);
434}
435
436#endif
Note: See TracBrowser for help on using the repository browser.