1 |
786 |
skrzyp |
// This file is part of the uSTL library, an STL implementation.
|
2 |
|
|
//
|
3 |
|
|
// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net>
|
4 |
|
|
// This file is free software, distributed under the MIT License.
|
5 |
|
|
|
6 |
|
|
#ifndef UMATRIX_H_740EBFEF554E833645E0FD72419A8185
|
7 |
|
|
#define UMATRIX_H_740EBFEF554E833645E0FD72419A8185
|
8 |
|
|
|
9 |
|
|
#include "utuple.h"
|
10 |
|
|
|
11 |
|
|
namespace ustl {
|
12 |
|
|
|
13 |
|
|
/// \class matrix umatrix.h ustl.h
|
14 |
|
|
/// \ingroup Sequences
|
15 |
|
|
///
|
16 |
|
|
/// \brief A two-dimensional array of NX*NY elements of type T.
|
17 |
|
|
///
|
18 |
|
|
template <size_t NX, size_t NY, typename T>
|
19 |
|
|
class matrix : public tuple<NX*NY,T> {
|
20 |
|
|
public:
|
21 |
|
|
typedef tuple<NX,T> row_type;
|
22 |
|
|
typedef tuple<NY,T> column_type;
|
23 |
|
|
typedef tuple<NX*NY,T> tuple_type;
|
24 |
|
|
typedef typename tuple_type::value_type value_type;
|
25 |
|
|
typedef typename tuple_type::size_type size_type;
|
26 |
|
|
typedef typename tuple_type::pointer pointer;
|
27 |
|
|
typedef typename tuple_type::const_pointer const_pointer;
|
28 |
|
|
typedef typename tuple_type::reference reference;
|
29 |
|
|
typedef typename tuple_type::const_reference const_reference;
|
30 |
|
|
typedef typename tuple_type::iterator iterator;
|
31 |
|
|
typedef typename tuple_type::const_iterator const_iterator;
|
32 |
|
|
typedef typename tuple_type::range_t range_t;
|
33 |
|
|
typedef typename tuple_type::const_range_t const_range_t;
|
34 |
|
|
typedef typename tuple_type::reverse_iterator reverse_iterator;
|
35 |
|
|
typedef typename tuple_type::const_reverse_iterator const_reverse_iterator;
|
36 |
|
|
public:
|
37 |
|
|
inline matrix (void) { }
|
38 |
|
|
inline size_type columns (void) const { return (NX); }
|
39 |
|
|
inline size_type rows (void) const { return (NY); }
|
40 |
|
|
inline const_iterator at (size_type i) const { return (matrix::begin() + i * NX); }
|
41 |
|
|
inline iterator at (size_type i) { return (matrix::begin() + i * NX); }
|
42 |
|
|
inline const_iterator operator[] (size_type i) const { return (at (i)); }
|
43 |
|
|
inline iterator operator[] (size_type i) { return (at (i)); }
|
44 |
|
|
inline row_type row (size_type r) const { return (row_type (at (r))); }
|
45 |
|
|
inline column_type column (size_type c) const;
|
46 |
|
|
template <typename T2>
|
47 |
|
|
inline const matrix& operator= (const matrix<NX,NY,T2>& src) { tuple_type::operator= (src); return (*this); }
|
48 |
|
|
inline const matrix& operator= (const matrix<NX,NY,T>& src) { tuple_type::operator= (src); return (*this); }
|
49 |
|
|
inline const matrix& operator+= (const_reference v) { tuple_type::operator+= (v); return (*this); }
|
50 |
|
|
inline const matrix& operator-= (const_reference v) { tuple_type::operator-= (v); return (*this); }
|
51 |
|
|
inline const matrix& operator*= (const_reference v) { tuple_type::operator*= (v); return (*this); }
|
52 |
|
|
inline const matrix& operator/= (const_reference v) { tuple_type::operator/= (v); return (*this); }
|
53 |
|
|
inline const matrix operator+ (const_reference v) const
|
54 |
|
|
{ matrix result (*this); result += v; return (result); }
|
55 |
|
|
inline const matrix operator- (const_reference v) const
|
56 |
|
|
{ matrix result (*this); result -= v; return (result); }
|
57 |
|
|
inline const matrix operator* (const_reference v) const
|
58 |
|
|
{ matrix result (*this); result *= v; return (result); }
|
59 |
|
|
inline const matrix operator/ (const_reference v) const
|
60 |
|
|
{ matrix result (*this); result /= v; return (result); }
|
61 |
|
|
};
|
62 |
|
|
|
63 |
|
|
template <size_t NX, size_t NY, typename T>
|
64 |
|
|
inline typename matrix<NX,NY,T>::column_type matrix<NX,NY,T>::column (size_type c) const
|
65 |
|
|
{
|
66 |
|
|
column_type result;
|
67 |
|
|
const_iterator src (matrix::begin() + c);
|
68 |
|
|
iterator dest (result.begin());
|
69 |
|
|
for (uoff_t i = 0; i < NY; ++ i, ++ dest, src += NX)
|
70 |
|
|
*dest = *src;
|
71 |
|
|
return (result);
|
72 |
|
|
}
|
73 |
|
|
|
74 |
|
|
//----------------------------------------------------------------------
|
75 |
|
|
// Define SIMD specializations for member functions.
|
76 |
|
|
|
77 |
|
|
#if CPU_HAS_SSE
|
78 |
|
|
#define MATRIX_R(v) "m"(v[0]),"m"(v[4]),"m"(v[8]),"m"(v[12])
|
79 |
|
|
#define MATRIX_W(v) "=m"(v[0]),"=m"(v[4]),"=m"(v[8]),"=m"(v[12])
|
80 |
|
|
#define SSE_TUPLE_SPECS(n,type) \
|
81 |
|
|
template <> inline tuple<n,type>::tuple (void) \
|
82 |
|
|
{ asm volatile ("xorps %%xmm0, %%xmm0\n\t" \
|
83 |
|
|
"movups %%xmm0, %0\n\t" \
|
84 |
|
|
"movups %%xmm0, %1\n\t" \
|
85 |
|
|
"movups %%xmm0, %2\n\t" \
|
86 |
|
|
"movups %%xmm0, %3" \
|
87 |
|
|
: "=m"(m_v[0]),"=m"(m_v[4]),"=m"(m_v[8]),"=m"(m_v[12]) \
|
88 |
|
|
::"xmm0","memory"); \
|
89 |
|
|
} \
|
90 |
|
|
namespace simd { \
|
91 |
|
|
SIMD_PASSIGN_SPEC(n,type) \
|
92 |
|
|
{ \
|
93 |
|
|
asm volatile ("movups %2, %%xmm0\n\t" \
|
94 |
|
|
"movups %3, %%xmm1\n\t" \
|
95 |
|
|
"movups %%xmm0, %0\n\t" \
|
96 |
|
|
"movups %%xmm1, %1" \
|
97 |
|
|
: "=m"(oout[0]),"=m"(oout[4]) \
|
98 |
|
|
: "m"(oin[0]),"m"(oin[4]) \
|
99 |
|
|
: "xmm0", "xmm1", "memory"); \
|
100 |
|
|
asm volatile ("movups %2, %%xmm0\n\t" \
|
101 |
|
|
"movups %3, %%xmm1\n\t" \
|
102 |
|
|
"movups %%xmm0, %0\n\t" \
|
103 |
|
|
"movups %%xmm1, %1" \
|
104 |
|
|
: "=m"(oout[8]),"=m"(oout[12]) \
|
105 |
|
|
: "m"(oin[8]),"m"(oin[12]) \
|
106 |
|
|
: "xmm0", "xmm1", "memory"); \
|
107 |
|
|
} \
|
108 |
|
|
}
|
109 |
|
|
SSE_TUPLE_SPECS(16,float)
|
110 |
|
|
SSE_TUPLE_SPECS(16,int32_t)
|
111 |
|
|
SSE_TUPLE_SPECS(16,uint32_t)
|
112 |
|
|
#undef SSE_TUPLE_SPECS
|
113 |
|
|
#undef TOUCH_MATRIX_R
|
114 |
|
|
#undef TOUCH_MATRIX_W
|
115 |
|
|
#undef MATRIX_R
|
116 |
|
|
#undef MATRIX_W
|
117 |
|
|
#endif
|
118 |
|
|
|
119 |
|
|
} // namespace ustl
|
120 |
|
|
|
121 |
|
|
#endif
|