1 /* -*- C++ -*- ------------------------------------------------------------
3 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
5 The Configurable Math Library (CML) is distributed under the terms of the
6 Boost Software License, v1.0 (see cml/LICENSE for details).
8 *-----------------------------------------------------------------------*/
10 * @brief Specializations for external-memory vectors.
12 * @note Copy-constructing one external<> vector from another is not
13 * supported, since an external<> vector is essentially a wrapper for a
14 * pointer and has no allocated storage of its own.
17 #ifndef external_vector_h
18 #define external_vector_h
20 #include <cml/core/external_1D.h>
21 #include <cml/vector/vector_expr.h>
22 #include <cml/vector/class_ops.h>
23 #include <cml/vector/vector_unroller.h>
24 #include <cml/vector/dynamic.h>
28 /** Fixed-size, fixed-memory vector. */
29 template<typename Element
, int Size
>
30 class vector
< Element
, external
<Size
> >
31 : public external_1D
<Element
,Size
>
35 /* Shorthand for the generator: */
36 typedef external
<> storage_type
;
37 typedef external
<Size
> generator_type
;
39 /* Shorthand for the array type: */
40 typedef external_1D
<Element
,Size
> array_type
;
42 /* Shorthand for the type of this vector: */
43 typedef vector
<Element
,generator_type
> vector_type
;
45 /* The vector coordinate type: */
46 typedef Element coordinate_type
;
48 /* For integration into the expression template code: */
49 typedef vector_type expr_type
;
51 /* For integration into the expression template code: */
52 typedef vector
<typename
cml::remove_const
<Element
>::type
,
53 fixed
<Size
> > temporary_type
;
54 typedef typename
temporary_type::subvector_type subvector_type
;
55 /* Note: this ensures that an external vector is copied into the proper
56 * temporary; external<> temporaries are not allowed.
60 typedef typename
array_type::value_type value_type
;
61 typedef typename
array_type::reference reference
;
62 typedef typename
array_type::const_reference const_reference
;
64 /* For integration into the expression templates code: */
65 typedef vector_type
& expr_reference
;
66 typedef const vector_type
& expr_const_reference
;
68 /* For matching by storage type: */
69 typedef typename
array_type::memory_tag memory_tag
;
71 /* For matching by size type: */
72 typedef typename
array_type::size_tag size_tag
;
74 /* For matching by result-type: */
75 typedef cml::et::vector_result_tag result_tag
;
77 /* For matching by assignability: */
78 typedef cml::et::assignable_tag assignable_tag
;
83 /** Static constant containing the vector's space dimension. */
84 enum { dimension
= Size
};
89 /** Return square of the length. */
90 value_type
length_squared() const {
91 return cml::dot(*this,*this);
94 /** Return the length. */
95 value_type
length() const {
96 return std::sqrt(length_squared());
99 /** Normalize the vector. */
100 vector_type
& normalize() {
101 return (*this /= length());
104 /** Set this vector to [0]. */
105 vector_type
& zero() {
106 typedef cml::et::OpAssign
<Element
,Element
> OpT
;
107 cml::et::UnrollAssignment
<OpT
>(*this,Element(0));
111 /** Set this vector to a cardinal vector. */
112 vector_type
& cardinal(size_t i
) {
114 (*this)[i
] = Element(1);
118 /** Pairwise minimum of this vector with another. */
119 template<typename E
, class AT
>
120 void minimize(const vector
<E
,AT
>& v
) {
121 /* XXX This should probably use ScalarPromote: */
122 for (size_t i
= 0; i
< this->size(); ++i
) {
123 (*this)[i
] = std::min((*this)[i
],v
[i
]);
127 /** Pairwise maximum of this vector with another. */
128 template<typename E
, class AT
>
129 void maximize(const vector
<E
,AT
>& v
) {
130 /* XXX This should probably use ScalarPromote: */
131 for (size_t i
= 0; i
< this->size(); ++i
) {
132 (*this)[i
] = std::max((*this)[i
],v
[i
]);
136 /** Fill vector with random elements. */
137 void random(value_type min
, value_type max
) {
138 for (size_t i
= 0; i
< this->size(); ++i
) {
139 (*this)[i
] = cml::random_real(min
,max
);
146 /** Construct from an array of values. */
147 vector(Element
* const array
) : array_type(array
) {}
156 CML_VEC_ASSIGN_FROM_VECTYPE
158 /* Only assignment operators can be used to copy from other types: */
159 CML_VEC_ASSIGN_FROM_VEC(=, cml::et::OpAssign
)
160 CML_VEC_ASSIGN_FROM_VEC(+=, cml::et::OpAddAssign
)
161 CML_VEC_ASSIGN_FROM_VEC(-=, cml::et::OpSubAssign
)
163 CML_VEC_ASSIGN_FROM_VECXPR(=, cml::et::OpAssign
)
164 CML_VEC_ASSIGN_FROM_VECXPR(+=, cml::et::OpAddAssign
)
165 CML_VEC_ASSIGN_FROM_VECXPR(-=, cml::et::OpSubAssign
)
167 CML_VEC_ASSIGN_FROM_SCALAR(*=, cml::et::OpMulAssign
)
168 CML_VEC_ASSIGN_FROM_SCALAR(/=, cml::et::OpDivAssign
)
171 /** Run-time sized vector. */
172 template<typename Element
>
173 class vector
< Element
, external
<> >
174 : public external_1D
<Element
>
178 /* Shorthand for the generator: */
179 typedef external
<> storage_type
;
180 typedef external
<> generator_type
;
182 /* Shorthand for the array type: */
183 typedef external_1D
<Element
> array_type
;
185 /* Shorthand for the type of this vector: */
186 typedef vector
<Element
,generator_type
> vector_type
;
188 /* For integration into the expression template code: */
189 typedef vector_type expr_type
;
191 /* For integration into the expression template code: */
192 typedef vector
<typename
cml::remove_const
<Element
>::type
,
193 dynamic
<> > temporary_type
;
194 /* Note: this ensures that an external vector is copied into the proper
195 * temporary; external<> temporaries are not allowed.
199 typedef typename
array_type::value_type value_type
;
200 typedef typename
array_type::reference reference
;
201 typedef typename
array_type::const_reference const_reference
;
203 /* For integration into the expression templates code: */
204 typedef vector_type
& expr_reference
;
205 typedef const vector_type
& expr_const_reference
;
207 /* For matching by storage type: */
208 typedef typename
array_type::memory_tag memory_tag
;
210 /* For matching by size type: */
211 typedef typename
array_type::size_tag size_tag
;
213 /* For matching by resizability: */
214 typedef typename
array_type::resizing_tag resizing_tag
;
216 /* For matching by result-type: */
217 typedef cml::et::vector_result_tag result_tag
;
219 /* For matching by assignability: */
220 typedef cml::et::assignable_tag assignable_tag
;
225 /** Return square of the length. */
226 value_type
length_squared() const {
227 return dot(*this,*this);
230 /** Return the length. */
231 value_type
length() const {
232 return std::sqrt(length_squared());
235 /** Normalize the vector. */
236 vector_type
& normalize() {
237 return (*this /= length());
240 /** Set this vector to [0]. */
241 vector_type
& zero() {
242 typedef cml::et::OpAssign
<Element
,Element
> OpT
;
243 cml::et::UnrollAssignment
<OpT
>(*this,Element(0));
247 /** Set this vector to a cardinal vector. */
248 vector_type
& cardinal(size_t i
) {
250 (*this)[i
] = Element(1);
254 /** Pairwise minimum of this vector with another. */
255 template<typename E
, class AT
>
256 void minimize(const vector
<E
,AT
>& v
) {
257 /* XXX This should probably use ScalarPromote: */
258 for (size_t i
= 0; i
< this->size(); ++i
) {
259 (*this)[i
] = std::min((*this)[i
],v
[i
]);
263 /** Pairwise maximum of this vector with another. */
264 template<typename E
, class AT
>
265 void maximize(const vector
<E
,AT
>& v
) {
266 /* XXX This should probably use ScalarPromote: */
267 for (size_t i
= 0; i
< this->size(); ++i
) {
268 (*this)[i
] = std::max((*this)[i
],v
[i
]);
272 /** Fill vector with random elements. */
273 void random(value_type min
, value_type max
) {
274 for (size_t i
= 0; i
< this->size(); ++i
) {
275 (*this)[i
] = random_real(min
,max
);
282 /** Construct from an array of values and the size. */
283 vector(Element
* const array
, size_t size
)
284 : array_type(array
, size
) {}
289 /* Define class operators for external vectors. Note: external vectors
290 * cannot be copy-constructed, but they can be assigned to:
296 CML_VEC_ASSIGN_FROM_VECTYPE
298 /* Only assignment operators can be used to copy from other types: */
299 CML_VEC_ASSIGN_FROM_VEC(=, cml::et::OpAssign
)
300 CML_VEC_ASSIGN_FROM_VEC(+=, cml::et::OpAddAssign
)
301 CML_VEC_ASSIGN_FROM_VEC(-=, cml::et::OpSubAssign
)
303 CML_VEC_ASSIGN_FROM_VECXPR(=, cml::et::OpAssign
)
304 CML_VEC_ASSIGN_FROM_VECXPR(+=, cml::et::OpAddAssign
)
305 CML_VEC_ASSIGN_FROM_VECXPR(-=, cml::et::OpSubAssign
)
307 CML_VEC_ASSIGN_FROM_SCALAR(*=, cml::et::OpMulAssign
)
308 CML_VEC_ASSIGN_FROM_SCALAR(/=, cml::et::OpDivAssign
)
315 // -------------------------------------------------------------------------