1 /*
  2  *   Copyright (c) 2007, Michael Lehn
  3  *   Copyright (c) 2011, Michael Lehn
  4  *
  5  *   All rights reserved.
  6  *
  7  *   Redistribution and use in source and binary forms, with or without
  8  *   modification, are permitted provided that the following conditions
  9  *   are met:
 10  *
 11  *   1) Redistributions of source code must retain the above copyright
 12  *      notice, this list of conditions and the following disclaimer.
 13  *   2) Redistributions in binary form must reproduce the above copyright
 14  *      notice, this list of conditions and the following disclaimer in
 15  *      the documentation and/or other materials provided with the
 16  *      distribution.
 17  *   3) Neither the name of the FLENS development group nor the names of
 18  *      its contributors may be used to endorse or promote products derived
 19  *      from this software without specific prior written permission.
 20  *
 21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 32  */
 33 
 34 #ifndef FLENS_VECTORTYPES_IMPL_DENSEVECTOR_TCC
 35 #define FLENS_VECTORTYPES_IMPL_DENSEVECTOR_TCC 1
 36 
 37 #include <flens/vectortypes/impl/dv/constelementclosure.tcc>
 38 #include <flens/vectortypes/impl/dv/elementclosure.tcc>
 39 #include <flens/vectortypes/impl/dv/initializer.tcc>
 40 
 41 namespace flens {
 42 
 43 template <typename A>
 44 DenseVector<A>::DenseVector()
 45     : _reverse(false)
 46 {
 47 }
 48 
 49 template <typename A>
 50 DenseVector<A>::DenseVector(IndexType length)
 51     : _array(length), _reverse(false)
 52 {
 53     ASSERT(length>=0);
 54 }
 55 
 56 template <typename A>
 57 DenseVector<A>::DenseVector(IndexType length, IndexType firstIndex)
 58     : _array(length, firstIndex), _reverse(false)
 59 {
 60     ASSERT(length>=0);
 61 }
 62 
 63 template <typename A>
 64 DenseVector<A>::DenseVector(const Range<IndexType> &range)
 65     : _array(range.numTicks(), range.firstIndex()), _reverse(false)
 66 {
 67     ASSERT(range.stride()>0);
 68 }
 69 
 70 template <typename A>
 71 DenseVector<A>::DenseVector(const Engine &engine, bool reverse)
 72     : _array(engine), _reverse(reverse)
 73 {
 74 }
 75 
 76 template <typename A>
 77 DenseVector<A>::DenseVector(const DenseVector &rhs)
 78     : Vector<DenseVector>(), _array(rhs._array), _reverse(false)
 79 {
 80 }
 81 
 82 template <typename A>
 83 template <typename RHS>
 84 DenseVector<A>::DenseVector(const DenseVector<RHS> &rhs)
 85     : _array(rhs.engine()), _reverse(false)
 86 {
 87 }
 88 
 89 template <typename A>
 90 template <typename RHS>
 91 DenseVector<A>::DenseVector(DenseVector<RHS> &rhs)
 92     : _array(rhs.engine()), _reverse(false)
 93 {
 94 }
 95 
 96 template <typename A>
 97 template <typename RHS>
 98 DenseVector<A>::DenseVector(const Vector<RHS> &rhs)
 99     : _reverse(false)
100 {
101     assign(rhs, *this);
102 }
103 
104 // -- operators --------------------------------------------------------
105 template <typename A>
106 typename DenseVector<A>::Initializer
107 DenseVector<A>::operator=(const ElementType &value)
108 {
109     _array.fill(value);
110     return Initializer(*this, firstIndex());
111 }
112 
113 template <typename A>
114 DenseVector<A> &
115 DenseVector<A>::operator=(const DenseVector &rhs)
116 {
117     if (this!=&rhs) {
118         assign(rhs, *this);
119     }
120     return *this;
121 }
122 
123 template <typename A>
124 template <typename E>
125 DenseVector<A> &
126 DenseVector<A>::operator=(const Vector<E> &rhs)
127 {
128     assign(rhs, *this);
129     return *this;
130 }
131 
132 template <typename A>
133 template <typename E>
134 DenseVector<A> &
135 DenseVector<A>::operator+=(const Vector<E> &rhs)
136 {
137     plusAssign(rhs, *this);
138     return *this;
139 }
140 
141 template <typename A>
142 template <typename E>
143 DenseVector<A> &
144 DenseVector<A>::operator-=(const Vector<E> &rhs)
145 {
146     minusAssign(rhs, *this);
147     return *this;
148 }
149 
150 template <typename A>
151 DenseVector<A> &
152 DenseVector<A>::operator+=(const ElementType &alpha)
153 {
154     for (int i=firstIndex(); i<=lastIndex(); ++i) {
155         (*this)(i) += alpha;
156     }
157     return *this;
158 }
159 
160 template <typename A>
161 DenseVector<A> &
162 DenseVector<A>::operator-=(const ElementType &alpha)
163 {
164     for (int i=firstIndex(); i<=lastIndex(); ++i) {
165         (*this)(i) -= alpha;
166     }
167     return *this;
168 }
169 
170 template <typename A>
171 DenseVector<A> &
172 DenseVector<A>::operator*=(const ElementType &alpha)
173 {
174     blas::scal(alpha, *this);
175     return *this;
176 }
177 
178 template <typename A>
179 DenseVector<A> &
180 DenseVector<A>::operator/=(const ElementType &alpha)
181 {
182     blas::rscal(alpha, *this);
183     return *this;
184 }
185 
186 template <typename A>
187 const typename DenseVector<A>::ElementType &
188 DenseVector<A>::operator()(IndexType index) const
189 {
190     return _array(index);
191 }
192 
193 template <typename A>
194 typename DenseVector<A>::ElementType &
195 DenseVector<A>::operator()(IndexType index)
196 {
197     return _array(index);
198 }
199 
200 template <typename A>
201 template <typename S>
202 const densevector::ConstElementClosure<DenseVector<A>, typename Scalar<S>::Impl>
203 DenseVector<A>::operator()(const Scalar<S> &index) const
204 {
205     typedef typename Scalar<S>::Impl ScalarImpl;
206     typedef densevector::ConstElementClosure<DenseVector, ScalarImpl>  CEC;
207     return CEC(*this, index.impl());
208 }
209 
210 template <typename A>
211 const typename DenseVector<A>::ConstElementClosure
212 DenseVector<A>::operator()(const IndexVariable &index) const
213 {
214     return ConstElementClosure(*this, index);
215 }
216 
217 template <typename A>
218 typename DenseVector<A>::ElementClosure
219 DenseVector<A>::operator()(IndexVariable &index)
220 {
221     return ElementClosure(*this, index);
222 }
223 
224 //-- views ---------------------------------------------------------------------
225 
226 template <typename A>
227 const typename DenseVector<A>::ConstView
228 DenseVector<A>::operator()(const Range<IndexType> &range) const
229 {
230     ASSERT(range.firstIndex()>=firstIndex());
231     ASSERT(range.lastIndex()<=lastIndex());
232     return _array.view(range.firstIndex(), range.lastIndex(), range.stride(),
233                        firstIndex());
234 }
235 
236 template <typename A>
237 typename DenseVector<A>::View
238 DenseVector<A>::operator()(const Range<IndexType> &range)
239 {
240     ASSERT(range.firstIndex()>=firstIndex());
241     ASSERT(range.lastIndex()<=lastIndex());
242     return _array.view(range.firstIndex(), range.lastIndex(), range.stride(),
243                        firstIndex());
244 }
245 
246 template <typename A>
247 const typename DenseVector<A>::ConstView
248 DenseVector<A>::operator()(const Range<IndexType> &range,
249                            IndexType _firstViewIndex) const
250 {
251     ASSERT(range.firstIndex()>=firstIndex());
252     ASSERT(range.lastIndex()<=lastIndex());
253     return _array.view(range.firstIndex(), range.lastIndex(), range.stride(),
254                        _firstViewIndex);
255 }
256 
257 template <typename A>
258 typename DenseVector<A>::View
259 DenseVector<A>::operator()(const Range<IndexType> &range,
260                            IndexType _firstViewIndex)
261 {
262     ASSERT(range.firstIndex()>=firstIndex());
263     ASSERT(range.lastIndex()<=lastIndex());
264     return _array.view(range.firstIndex(), range.lastIndex(), range.stride(),
265                        _firstViewIndex);
266 }
267 
268 template <typename A>
269 const typename DenseVector<A>::ConstView
270 DenseVector<A>::operator()(const Underscore<IndexType> &/*all*/,
271                            IndexType _firstViewIndex) const
272 {
273     return _array.view(_array.firstIndex(), _array.lastIndex(), _array.stride(),
274                        _firstViewIndex);
275 }
276 
277 template <typename A>
278 typename DenseVector<A>::View
279 DenseVector<A>::operator()(const Underscore<IndexType> &/*all*/,
280                            IndexType _firstViewIndex)
281 {
282     return _array.view(_array.firstIndex(), _array.lastIndex(), _array.stride(),
283                        _firstViewIndex);
284 }
285 
286 template <typename A>
287 const typename DenseVector<A>::ConstView
288 DenseVector<A>::reverse() const
289 {
290     return ConstView(_array, !_reverse);
291 }
292 
293 template <typename A>
294 typename DenseVector<A>::View
295 DenseVector<A>::reverse()
296 {
297     return View(_array, !_reverse);
298 }
299 
300 // -- methods ------------------------------------------------------------------
301 
302 template <typename A>
303 Range<typename DenseVector<A>::IndexType>
304 DenseVector<A>::range() const
305 {
306     return Range<IndexType>(_array.firstIndex(),_array.lastIndex());
307 }
308 
309 template <typename A>
310 typename DenseVector<A>::IndexType
311 DenseVector<A>::firstIndex() const
312 {
313     if (_reverse) {
314         return _array.lastIndex();
315     }
316     return _array.firstIndex();
317 }
318 
319 template <typename A>
320 typename DenseVector<A>::IndexType
321 DenseVector<A>::lastIndex() const
322 {
323     if (_reverse) {
324         return _array.firstIndex();
325     }
326     return _array.lastIndex();
327 }
328 
329 template <typename A>
330 typename DenseVector<A>::IndexType
331 DenseVector<A>::length() const
332 {
333     return _array.length();
334 }
335 
336 template <typename A>
337 typename DenseVector<A>::IndexType
338 DenseVector<A>::inc() const
339 {
340     if (_reverse) {
341         return -1;
342     }
343     return 1;
344 }
345 
346 template <typename A>
347 typename DenseVector<A>::IndexType
348 DenseVector<A>::endIndex() const
349 {
350     return lastIndex() + inc();
351 }
352 
353 template <typename A>
354 const typename DenseVector<A>::ElementType *
355 DenseVector<A>::data() const
356 {
357     return _array.data();
358 }
359 
360 template <typename A>
361 typename DenseVector<A>::ElementType *
362 DenseVector<A>::data()
363 {
364     return _array.data();
365 }
366 
367 template <typename A>
368 typename DenseVector<A>::IndexType
369 DenseVector<A>::stride() const
370 {
371     if (_reverse) {
372         return -_array.stride();
373     }
374     return _array.stride();
375 }
376 
377 template <typename A>
378 typename DenseVector<A>::IndexType
379 DenseVector<A>::indexBase() const
380 {
381     return _array.firstIndex();
382 }
383 
384 template <typename A>
385 template <typename RHS>
386 bool
387 DenseVector<A>::resize(const DenseVector<RHS> &rhs, const ElementType &value)
388 {
389     bool resized = _array.resize(rhs.engine(), value);
390     if (_reverse != rhs.reversed()) {
391         _reverse = rhs.reversed();
392         return true;
393     }
394     return resized;
395 }
396 
397 template <typename A>
398 bool
399 DenseVector<A>::resize(IndexType length, IndexType firstIndex,
400                        const ElementType &value)
401 {
402     return _array.resize(length, firstIndex, value);
403 }
404 
405 template <typename A>
406 void
407 DenseVector<A>::changeIndexBase(IndexType firstIndex)
408 {
409     _array.changeIndexBase(firstIndex);
410 }
411 
412 // -- implementation -----------------------------------------------------------
413 template <typename A>
414 const A &
415 DenseVector<A>::engine() const
416 {
417     return _array;
418 }
419 
420 template <typename A>
421 A &
422 DenseVector<A>::engine()
423 {
424     return _array;
425 }
426 
427 template <typename A>
428 bool
429 DenseVector<A>::reversed() const
430 {
431     return _reverse;
432 }
433 
434 // namespace flens
435 
436 #endif // FLENS_VECTORTYPES_IMPL_DENSEVECTOR_TCC