1 /*
2 * Copyright (c) 2007, Michael Lehn
3 *
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1) Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2) Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 * 3) Neither the name of the FLENS development group nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #ifndef FLENS_STORAGE_FULLSTORAGE_FULLSTORAGEVIEW_TCC
34 #define FLENS_STORAGE_FULLSTORAGE_FULLSTORAGEVIEW_TCC 1
35
36 #include <flens/storage/fullstorage/trapezoidalfill.h>
37 #include <flens/typedefs.h>
38
39 namespace flens {
40
41 template <typename T, StorageOrder Order, typename I, typename A>
42 FullStorageView<T, Order, I, A>::FullStorageView(IndexType numRows,
43 IndexType numCols,
44 ElementType *data,
45 IndexType leadingDimension,
46 IndexType firstRow,
47 IndexType firstCol,
48 const Allocator &allocator)
49 : _data(data),
50 _allocator(allocator),
51 _numRows(numRows), _numCols(numCols),
52 _leadingDimension(leadingDimension),
53 _firstRow(0), _firstCol(0)
54 {
55 ASSERT(_numRows>=0);
56 ASSERT(_numCols>=0);
57
58 changeIndexBase(firstRow, firstCol);
59 }
60
61 template <typename T, StorageOrder Order, typename I, typename A>
62 template <typename ARRAY>
63 FullStorageView<T, Order, I, A>::FullStorageView(IndexType numRows,
64 IndexType numCols,
65 ARRAY &array,
66 IndexType leadingDimension,
67 IndexType firstRow,
68 IndexType firstCol,
69 const Allocator &allocator)
70 : _data(array.data()),
71 _allocator(allocator),
72 _numRows(numRows), _numCols(numCols),
73 _leadingDimension(leadingDimension),
74 _firstRow(0), _firstCol(0)
75 {
76 ASSERT(numRows*numCols<=array.length());
77 ASSERT(_numRows>=0);
78 ASSERT(_numCols>=0);
79
80 changeIndexBase(firstRow, firstCol);
81 }
82
83 template <typename T, StorageOrder Order, typename I, typename A>
84 FullStorageView<T, Order, I, A>::FullStorageView(const FullStorageView &rhs)
85 : _data(rhs._data),
86 _allocator(rhs._allocator),
87 _numRows(rhs._numRows), _numCols(rhs._numCols),
88 _leadingDimension(rhs._leadingDimension),
89 _firstRow(rhs._firstRow), _firstCol(rhs._firstCol)
90 {
91 }
92
93 template <typename T, StorageOrder Order, typename I, typename A>
94 template <typename RHS>
95 FullStorageView<T, Order, I, A>::FullStorageView(RHS &rhs)
96 : _data(rhs.data()),
97 _allocator(rhs.allocator()),
98 _numRows(rhs.numRows()), _numCols(rhs.numCols()),
99 _leadingDimension(rhs.leadingDimension()),
100 _firstRow(0), _firstCol(0)
101 {
102 changeIndexBase(rhs.firstRow(), rhs.firstCol());
103 }
104
105 template <typename T, StorageOrder Order, typename I, typename A>
106 FullStorageView<T, Order, I, A>::~FullStorageView()
107 {
108 }
109
110 //-- operators -----------------------------------------------------------------
111
112 template <typename T, StorageOrder Order, typename I, typename A>
113 const typename FullStorageView<T, Order, I, A>::ElementType &
114 FullStorageView<T, Order, I, A>::operator()(IndexType row, IndexType col) const
115 {
116 ASSERT(row>=_firstRow);
117 ASSERT(row<_firstRow+_numRows);
118 ASSERT(col>=_firstCol);
119 ASSERT(col<_firstCol+_numCols);
120
121 if (Order==ColMajor) {
122 return _data[col*_leadingDimension+row];
123 }
124 return _data[row*_leadingDimension+col];
125 }
126
127 template <typename T, StorageOrder Order, typename I, typename A>
128 typename FullStorageView<T, Order, I, A>::ElementType &
129 FullStorageView<T, Order, I, A>::operator()(IndexType row, IndexType col)
130 {
131 ASSERT(row>=_firstRow);
132 ASSERT(row<_firstRow+_numRows);
133 ASSERT(col>=_firstCol);
134 ASSERT(col<_firstCol+_numCols);
135
136 if (Order==ColMajor) {
137 return _data[col*_leadingDimension+row];
138 }
139 return _data[row*_leadingDimension+col];
140 }
141
142 //-- methods -------------------------------------------------------------------
143
144 template <typename T, StorageOrder Order, typename I, typename A>
145 typename FullStorageView<T, Order, I, A>::IndexType
146 FullStorageView<T, Order, I, A>::firstRow() const
147 {
148 return _firstRow;
149 }
150
151 template <typename T, StorageOrder Order, typename I, typename A>
152 typename FullStorageView<T, Order, I, A>::IndexType
153 FullStorageView<T, Order, I, A>::lastRow() const
154 {
155 return _firstRow+_numRows-1;
156 }
157
158 template <typename T, StorageOrder Order, typename I, typename A>
159 typename FullStorageView<T, Order, I, A>::IndexType
160 FullStorageView<T, Order, I, A>::firstCol() const
161 {
162 return _firstCol;
163 }
164
165 template <typename T, StorageOrder Order, typename I, typename A>
166 typename FullStorageView<T, Order, I, A>::IndexType
167 FullStorageView<T, Order, I, A>::lastCol() const
168 {
169 return _firstCol+_numCols-1;
170 }
171
172 template <typename T, StorageOrder Order, typename I, typename A>
173 typename FullStorageView<T, Order, I, A>::IndexType
174 FullStorageView<T, Order, I, A>::numRows() const
175 {
176 return _numRows;
177 }
178
179 template <typename T, StorageOrder Order, typename I, typename A>
180 typename FullStorageView<T, Order, I, A>::IndexType
181 FullStorageView<T, Order, I, A>::numCols() const
182 {
183 return _numCols;
184 }
185
186 template <typename T, StorageOrder Order, typename I, typename A>
187 typename FullStorageView<T, Order, I, A>::IndexType
188 FullStorageView<T, Order, I, A>::leadingDimension() const
189 {
190 return _leadingDimension;
191 }
192
193 template <typename T, StorageOrder Order, typename I, typename A>
194 typename FullStorageView<T, Order, I, A>::IndexType
195 FullStorageView<T, Order, I, A>::strideRow() const
196 {
197 return (Order==ColMajor) ? 1
198 : leadingDimension();
199 }
200
201 template <typename T, StorageOrder Order, typename I, typename A>
202 typename FullStorageView<T, Order, I, A>::IndexType
203 FullStorageView<T, Order, I, A>::strideCol() const
204 {
205 return (Order==ColMajor) ? leadingDimension()
206 : 1;
207 }
208
209 template <typename T, StorageOrder Order, typename I, typename A>
210 const typename FullStorageView<T, Order, I, A>::ElementType *
211 FullStorageView<T, Order, I, A>::data() const
212 {
213 # ifndef NDEBUG
214 if ((numRows()==0) || numCols()==0) {
215 return 0;
216 }
217 # endif
218 return &(this->operator()(_firstRow, _firstCol));
219 }
220
221 template <typename T, StorageOrder Order, typename I, typename A>
222 typename FullStorageView<T, Order, I, A>::ElementType *
223 FullStorageView<T, Order, I, A>::data()
224 {
225 # ifndef NDEBUG
226 if ((numRows()==0) || numCols()==0) {
227 return 0;
228 }
229 # endif
230
231 return &(this->operator()(_firstRow, _firstCol));
232 }
233
234 template <typename T, StorageOrder Order, typename I, typename A>
235 const typename FullStorageView<T, Order, I, A>::Allocator &
236 FullStorageView<T, Order, I, A>::allocator() const
237 {
238 return _allocator;
239 }
240
241 template <typename T, StorageOrder Order, typename I, typename A>
242 bool
243 FullStorageView<T, Order, I, A>::resize(IndexType DEBUG_VAR(_numRows),
244 IndexType DEBUG_VAR(_numCols),
245 IndexType firstRow,
246 IndexType firstCol,
247 const ElementType &)
248 {
249 ASSERT(_numRows==numRows());
250 ASSERT(_numCols==numCols());
251 changeIndexBase(firstRow, firstCol);
252 return false;
253 }
254
255 template <typename T, StorageOrder Order, typename I, typename A>
256 template <typename FS>
257 bool
258 FullStorageView<T, Order, I, A>::resize(const FS &rhs, const ElementType &value)
259 {
260 return resize(rhs.numRows(), rhs.numCols(),
261 rhs.firstRow(), rhs.firstCol(),
262 value);
263 }
264
265 template <typename T, StorageOrder Order, typename I, typename A>
266 bool
267 FullStorageView<T, Order, I, A>::fill(const ElementType &value)
268 {
269 if (Order==RowMajor) {
270 ElementType *p = data();
271 for (IndexType i=0; i<numRows(); ++i, p+=leadingDimension()) {
272 std::fill_n(p, numCols(), value);
273 }
274 return true;
275 }
276 if (Order==ColMajor) {
277 ElementType *p = data();
278 for (IndexType j=0; j<numCols(); ++j, p+=leadingDimension()) {
279 std::fill_n(p, numRows(), value);
280 }
281 return true;
282 }
283 ASSERT(0);
284 return false;
285 }
286
287 template <typename T, StorageOrder Order, typename I, typename A>
288 bool
289 FullStorageView<T, Order, I, A>::fill(StorageUpLo upLo,
290 const ElementType &value)
291 {
292 trapezoidalFill(order, upLo, value,
293 numRows(), numCols(),
294 data(), leadingDimension());
295 return true;
296 }
297
298 template <typename T, StorageOrder Order, typename I, typename A>
299 void
300 FullStorageView<T, Order, I, A>::changeIndexBase(IndexType firstRow,
301 IndexType firstCol)
302 {
303 # ifndef NDEBUG
304 // prevent an out-of-bound assertion in case a view is empty anyway
305 if ((numRows()==0) || (numCols()==0)) {
306 _firstRow = firstRow;
307 _firstCol = firstCol;
308 return;
309 }
310 # endif
311
312 if (Order==RowMajor) {
313 _data = data() - (firstRow*leadingDimension() + firstCol);
314 }
315 if (Order==ColMajor) {
316 _data = data() - (firstCol*leadingDimension() + firstRow);
317 }
318 _firstRow = firstRow;
319 _firstCol = firstCol;
320 }
321
322 // view of fullstorage scheme as an array
323 template <typename T, StorageOrder Order, typename I, typename A>
324 const typename FullStorageView<T, Order, I, A>::ConstArrayView
325 FullStorageView<T, Order, I, A>::arrayView(IndexType firstViewIndex) const
326 {
327 # ifndef NDEBUG
328 if (order==ColMajor) {
329 ASSERT(numRows()==leadingDimension());
330 } else {
331 ASSERT(numCols()==leadingDimension());
332 }
333 # endif
334
335 return ConstArrayView(numCols()*numRows(),
336 data(),
337 IndexType(1),
338 firstViewIndex,
339 allocator());
340 }
341
342 template <typename T, StorageOrder Order, typename I, typename A>
343 typename FullStorageView<T, Order, I, A>::ArrayView
344 FullStorageView<T, Order, I, A>::arrayView(IndexType firstViewIndex)
345 {
346 # ifndef NDEBUG
347 if (order==ColMajor) {
348 ASSERT(numRows()==leadingDimension());
349 } else {
350 ASSERT(numCols()==leadingDimension());
351 }
352 # endif
353
354 return ArrayView(numCols()*numRows(),
355 data(),
356 IndexType(1),
357 firstViewIndex,
358 allocator());
359 }
360
361 // view of rectangular part
362 template <typename T, StorageOrder Order, typename I, typename A>
363 const typename FullStorageView<T, Order, I, A>::ConstView
364 FullStorageView<T, Order, I, A>::view(IndexType fromRow, IndexType fromCol,
365 IndexType toRow, IndexType toCol,
366 IndexType firstViewRow,
367 IndexType firstViewCol) const
368 {
369 const IndexType numRows = toRow-fromRow+1;
370 const IndexType numCols = toCol-fromCol+1;
371
372 # ifndef NDEBUG
373 // prevent an out-of-bound assertion in case a view is empty anyway
374 if ((numRows==0) || (numCols==0)) {
375 return ConstView(numRows, numCols, 0, leadingDimension(),
376 firstViewRow, firstViewCol, allocator());
377 }
378 # endif
379
380 ASSERT(fromRow>=firstRow());
381 ASSERT(fromRow<=toRow);
382 ASSERT(toRow<=lastRow());
383
384 ASSERT(fromCol>=firstCol());
385 ASSERT(fromCol<=toCol);
386 ASSERT(toCol<=lastCol());
387
388 return ConstView(numRows, // # rows
389 numCols, // # cols
390 &(operator()(fromRow, fromCol)), // data
391 leadingDimension(), // leading dimension
392 firstViewRow, // firstRow
393 firstViewCol, // firstCol
394 allocator()); // allocator
395 }
396
397 template <typename T, StorageOrder Order, typename I, typename A>
398 FullStorageView<T, Order, I, A>
399 FullStorageView<T, Order, I, A>::view(IndexType fromRow, IndexType fromCol,
400 IndexType toRow, IndexType toCol,
401 IndexType firstViewRow,
402 IndexType firstViewCol)
403 {
404 const IndexType numRows = toRow-fromRow+1;
405 const IndexType numCols = toCol-fromCol+1;
406
407 # ifndef NDEBUG
408 // prevent an out-of-bound assertion in case a view is empty anyway
409 if ((numRows==0) || (numCols==0)) {
410 return View(numRows, numCols, 0, leadingDimension(),
411 firstViewRow, firstViewCol, allocator());
412 }
413 # endif
414
415 ASSERT(fromRow>=firstRow());
416 ASSERT(fromRow<=toRow);
417 ASSERT(toRow<=lastRow());
418
419 ASSERT(fromCol>=firstCol());
420 ASSERT(fromCol<=toCol);
421 ASSERT(toCol<=lastCol());
422
423 return View(numRows, // # rows
424 numCols, // # cols
425 &(operator()(fromRow, fromCol)), // data
426 leadingDimension(), // leading dimension
427 firstViewRow, // firstRow
428 firstViewCol, // firstCol
429 allocator()); // allocator
430 }
431
432 // view of single row
433 template <typename T, StorageOrder Order, typename I, typename A>
434 const typename FullStorageView<T, Order, I, A>::ConstArrayView
435 FullStorageView<T, Order, I, A>::viewRow(IndexType row,
436 IndexType firstViewIndex) const
437 {
438 # ifndef NDEBUG
439 // prevent an out-of-bound assertion in case a view is empty anyway
440 if (numCols()==0) {
441 return ConstArrayView(numCols(), 0, strideCol(),
442 firstViewIndex, allocator());
443 }
444 # endif
445
446 ASSERT(row>=firstRow());
447 ASSERT(row<=lastRow());
448
449 return ConstArrayView(numCols(),
450 &(operator()(row, _firstCol)),
451 strideCol(),
452 firstViewIndex,
453 allocator());
454 }
455
456 template <typename T, StorageOrder Order, typename I, typename A>
457 typename FullStorageView<T, Order, I, A>::ArrayView
458 FullStorageView<T, Order, I, A>::viewRow(IndexType row,
459 IndexType firstViewIndex)
460 {
461 # ifndef NDEBUG
462 // prevent an out-of-bound assertion in case a view is empty anyway
463 if (numCols()==0) {
464 return ArrayView(numCols(), 0, strideCol(),
465 firstViewIndex, allocator());
466 }
467 # endif
468
469 ASSERT(row>=firstRow());
470 ASSERT(row<=lastRow());
471
472 return ArrayView(numCols(),
473 &(operator()(row, _firstCol)),
474 strideCol(),
475 firstViewIndex,
476 allocator());
477 }
478
479 template <typename T, StorageOrder Order, typename I, typename A>
480 const typename FullStorageView<T, Order, I, A>::ConstArrayView
481 FullStorageView<T, Order, I, A>::viewRow(IndexType row,
482 IndexType firstCol, IndexType lastCol,
483 IndexType firstViewIndex) const
484 {
485 const IndexType length = lastCol-firstCol+1;
486
487 # ifndef NDEBUG
488 // prevent an out-of-bound assertion in case a view is empty anyway
489 if (length==0) {
490 return ConstArrayView(length, 0, strideCol(),
491 firstViewIndex, allocator());
492 }
493 # endif
494
495 ASSERT(row>=firstRow());
496 ASSERT(row<=lastRow());
497
498 return ConstArrayView(length,
499 &(operator()(row, firstCol)),
500 strideCol(),
501 firstViewIndex,
502 allocator());
503 }
504
505 template <typename T, StorageOrder Order, typename I, typename A>
506 typename FullStorageView<T, Order, I, A>::ArrayView
507 FullStorageView<T, Order, I, A>::viewRow(IndexType row,
508 IndexType firstCol, IndexType lastCol,
509 IndexType firstViewIndex)
510 {
511 const IndexType length = lastCol-firstCol+1;
512
513 # ifndef NDEBUG
514 // prevent an out-of-bound assertion in case a view is empty anyway
515 if (length==0) {
516 return ArrayView(length, 0, strideCol(),
517 firstViewIndex, allocator());
518 }
519 # endif
520
521 ASSERT(row>=firstRow());
522 ASSERT(row<=lastRow());
523
524 return ArrayView(length,
525 &(operator()(row, firstCol)),
526 strideCol(),
527 firstViewIndex,
528 allocator());
529 }
530
531 // view of single column
532 template <typename T, StorageOrder Order, typename I, typename A>
533 const typename FullStorageView<T, Order, I, A>::ConstArrayView
534 FullStorageView<T, Order, I, A>::viewCol(IndexType col,
535 IndexType firstViewIndex) const
536 {
537 # ifndef NDEBUG
538 // prevent an out-of-bound assertion in case a view is empty anyway
539 if (numRows()==0) {
540 return ConstArrayView(numRows(), 0, strideRow(),
541 firstViewIndex, allocator());
542 }
543 # endif
544
545 ASSERT(col>=firstCol());
546 ASSERT(col<=lastCol());
547
548 return ConstArrayView(numRows(),
549 &(operator()(_firstRow, col)),
550 strideRow(),
551 firstViewIndex,
552 allocator());
553 }
554
555 template <typename T, StorageOrder Order, typename I, typename A>
556 typename FullStorageView<T, Order, I, A>::ArrayView
557 FullStorageView<T, Order, I, A>::viewCol(IndexType col,
558 IndexType firstViewIndex)
559 {
560 # ifndef NDEBUG
561 // prevent an out-of-bound assertion in case a view is empty anyway
562 if (numRows()==0) {
563 return ArrayView(numRows(), 0, strideRow(),
564 firstViewIndex, allocator());
565 }
566 # endif
567
568 ASSERT(col>=firstCol());
569 ASSERT(col<=lastCol());
570
571 return ArrayView(numRows(),
572 &(operator()(_firstRow, col)),
573 strideRow(),
574 firstViewIndex,
575 allocator());
576 }
577
578 template <typename T, StorageOrder Order, typename I, typename A>
579 const typename FullStorageView<T, Order, I, A>::ConstArrayView
580 FullStorageView<T, Order, I, A>::viewCol(IndexType firstRow, IndexType lastRow,
581 IndexType col,
582 IndexType firstViewIndex) const
583 {
584 const IndexType length = lastRow-firstRow+1;
585
586 # ifndef NDEBUG
587 // prevent an out-of-bound assertion in case a view is empty anyway
588 if (length==0) {
589 return ConstArrayView(length, 0, strideRow(),
590 firstViewIndex, allocator());
591 }
592 # endif
593
594 ASSERT(col>=firstCol());
595 ASSERT(col<=lastCol());
596
597 return ConstArrayView(length,
598 &(operator()(firstRow, col)),
599 strideRow(),
600 firstViewIndex,
601 allocator());
602 }
603
604 template <typename T, StorageOrder Order, typename I, typename A>
605 typename FullStorageView<T, Order, I, A>::ArrayView
606 FullStorageView<T, Order, I, A>::viewCol(IndexType firstRow, IndexType lastRow,
607 IndexType col,
608 IndexType firstViewIndex)
609 {
610 const IndexType length = lastRow-firstRow+1;
611
612 # ifndef NDEBUG
613 // prevent an out-of-bound assertion in case a view is empty anyway
614 if (length==0) {
615 return ArrayView(length, 0, strideRow(),
616 firstViewIndex, allocator());
617 }
618 # endif
619
620 ASSERT(col>=firstCol());
621 ASSERT(col<=lastCol());
622
623 return ArrayView(length,
624 &(operator()(firstRow, col)),
625 strideRow(),
626 firstViewIndex,
627 allocator());
628 }
629
630 // view of d-th diagonal
631 template <typename T, StorageOrder Order, typename I, typename A>
632 const typename FullStorageView<T, Order, I, A>::ConstArrayView
633 FullStorageView<T, Order, I, A>::viewDiag(IndexType d,
634 IndexType firstViewIndex) const
635 {
636 IndexType _row = (d>0) ? 0 : -d;
637 IndexType _col = (d>0) ? d : 0;
638
639 IndexType row = firstRow() + _row;
640 IndexType col = firstCol() + _col;
641
642 return ConstArrayView(std::min(numRows()-_row, numCols()-_col),
643 &(operator()(row,col)),
644 leadingDimension()+1,
645 firstViewIndex,
646 allocator());
647 }
648
649 template <typename T, StorageOrder Order, typename I, typename A>
650 typename FullStorageView<T, Order, I, A>::ArrayView
651 FullStorageView<T, Order, I, A>::viewDiag(IndexType d,
652 IndexType firstViewIndex)
653 {
654 IndexType _row = (d>0) ? 0 : -d;
655 IndexType _col = (d>0) ? d : 0;
656
657 IndexType row = firstRow() + _row;
658 IndexType col = firstCol() + _col;
659
660 return ArrayView(std::min(numRows()-_row,numCols()-_col),
661 &(operator()(row,col)),
662 leadingDimension()+1,
663 firstViewIndex,
664 allocator());
665 }
666
667 } // namespace flens
668
669 #endif // FLENS_STORAGE_FULLSTORAGE_FULLSTORAGEVIEW_TCC
2 * Copyright (c) 2007, Michael Lehn
3 *
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1) Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2) Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 * 3) Neither the name of the FLENS development group nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #ifndef FLENS_STORAGE_FULLSTORAGE_FULLSTORAGEVIEW_TCC
34 #define FLENS_STORAGE_FULLSTORAGE_FULLSTORAGEVIEW_TCC 1
35
36 #include <flens/storage/fullstorage/trapezoidalfill.h>
37 #include <flens/typedefs.h>
38
39 namespace flens {
40
41 template <typename T, StorageOrder Order, typename I, typename A>
42 FullStorageView<T, Order, I, A>::FullStorageView(IndexType numRows,
43 IndexType numCols,
44 ElementType *data,
45 IndexType leadingDimension,
46 IndexType firstRow,
47 IndexType firstCol,
48 const Allocator &allocator)
49 : _data(data),
50 _allocator(allocator),
51 _numRows(numRows), _numCols(numCols),
52 _leadingDimension(leadingDimension),
53 _firstRow(0), _firstCol(0)
54 {
55 ASSERT(_numRows>=0);
56 ASSERT(_numCols>=0);
57
58 changeIndexBase(firstRow, firstCol);
59 }
60
61 template <typename T, StorageOrder Order, typename I, typename A>
62 template <typename ARRAY>
63 FullStorageView<T, Order, I, A>::FullStorageView(IndexType numRows,
64 IndexType numCols,
65 ARRAY &array,
66 IndexType leadingDimension,
67 IndexType firstRow,
68 IndexType firstCol,
69 const Allocator &allocator)
70 : _data(array.data()),
71 _allocator(allocator),
72 _numRows(numRows), _numCols(numCols),
73 _leadingDimension(leadingDimension),
74 _firstRow(0), _firstCol(0)
75 {
76 ASSERT(numRows*numCols<=array.length());
77 ASSERT(_numRows>=0);
78 ASSERT(_numCols>=0);
79
80 changeIndexBase(firstRow, firstCol);
81 }
82
83 template <typename T, StorageOrder Order, typename I, typename A>
84 FullStorageView<T, Order, I, A>::FullStorageView(const FullStorageView &rhs)
85 : _data(rhs._data),
86 _allocator(rhs._allocator),
87 _numRows(rhs._numRows), _numCols(rhs._numCols),
88 _leadingDimension(rhs._leadingDimension),
89 _firstRow(rhs._firstRow), _firstCol(rhs._firstCol)
90 {
91 }
92
93 template <typename T, StorageOrder Order, typename I, typename A>
94 template <typename RHS>
95 FullStorageView<T, Order, I, A>::FullStorageView(RHS &rhs)
96 : _data(rhs.data()),
97 _allocator(rhs.allocator()),
98 _numRows(rhs.numRows()), _numCols(rhs.numCols()),
99 _leadingDimension(rhs.leadingDimension()),
100 _firstRow(0), _firstCol(0)
101 {
102 changeIndexBase(rhs.firstRow(), rhs.firstCol());
103 }
104
105 template <typename T, StorageOrder Order, typename I, typename A>
106 FullStorageView<T, Order, I, A>::~FullStorageView()
107 {
108 }
109
110 //-- operators -----------------------------------------------------------------
111
112 template <typename T, StorageOrder Order, typename I, typename A>
113 const typename FullStorageView<T, Order, I, A>::ElementType &
114 FullStorageView<T, Order, I, A>::operator()(IndexType row, IndexType col) const
115 {
116 ASSERT(row>=_firstRow);
117 ASSERT(row<_firstRow+_numRows);
118 ASSERT(col>=_firstCol);
119 ASSERT(col<_firstCol+_numCols);
120
121 if (Order==ColMajor) {
122 return _data[col*_leadingDimension+row];
123 }
124 return _data[row*_leadingDimension+col];
125 }
126
127 template <typename T, StorageOrder Order, typename I, typename A>
128 typename FullStorageView<T, Order, I, A>::ElementType &
129 FullStorageView<T, Order, I, A>::operator()(IndexType row, IndexType col)
130 {
131 ASSERT(row>=_firstRow);
132 ASSERT(row<_firstRow+_numRows);
133 ASSERT(col>=_firstCol);
134 ASSERT(col<_firstCol+_numCols);
135
136 if (Order==ColMajor) {
137 return _data[col*_leadingDimension+row];
138 }
139 return _data[row*_leadingDimension+col];
140 }
141
142 //-- methods -------------------------------------------------------------------
143
144 template <typename T, StorageOrder Order, typename I, typename A>
145 typename FullStorageView<T, Order, I, A>::IndexType
146 FullStorageView<T, Order, I, A>::firstRow() const
147 {
148 return _firstRow;
149 }
150
151 template <typename T, StorageOrder Order, typename I, typename A>
152 typename FullStorageView<T, Order, I, A>::IndexType
153 FullStorageView<T, Order, I, A>::lastRow() const
154 {
155 return _firstRow+_numRows-1;
156 }
157
158 template <typename T, StorageOrder Order, typename I, typename A>
159 typename FullStorageView<T, Order, I, A>::IndexType
160 FullStorageView<T, Order, I, A>::firstCol() const
161 {
162 return _firstCol;
163 }
164
165 template <typename T, StorageOrder Order, typename I, typename A>
166 typename FullStorageView<T, Order, I, A>::IndexType
167 FullStorageView<T, Order, I, A>::lastCol() const
168 {
169 return _firstCol+_numCols-1;
170 }
171
172 template <typename T, StorageOrder Order, typename I, typename A>
173 typename FullStorageView<T, Order, I, A>::IndexType
174 FullStorageView<T, Order, I, A>::numRows() const
175 {
176 return _numRows;
177 }
178
179 template <typename T, StorageOrder Order, typename I, typename A>
180 typename FullStorageView<T, Order, I, A>::IndexType
181 FullStorageView<T, Order, I, A>::numCols() const
182 {
183 return _numCols;
184 }
185
186 template <typename T, StorageOrder Order, typename I, typename A>
187 typename FullStorageView<T, Order, I, A>::IndexType
188 FullStorageView<T, Order, I, A>::leadingDimension() const
189 {
190 return _leadingDimension;
191 }
192
193 template <typename T, StorageOrder Order, typename I, typename A>
194 typename FullStorageView<T, Order, I, A>::IndexType
195 FullStorageView<T, Order, I, A>::strideRow() const
196 {
197 return (Order==ColMajor) ? 1
198 : leadingDimension();
199 }
200
201 template <typename T, StorageOrder Order, typename I, typename A>
202 typename FullStorageView<T, Order, I, A>::IndexType
203 FullStorageView<T, Order, I, A>::strideCol() const
204 {
205 return (Order==ColMajor) ? leadingDimension()
206 : 1;
207 }
208
209 template <typename T, StorageOrder Order, typename I, typename A>
210 const typename FullStorageView<T, Order, I, A>::ElementType *
211 FullStorageView<T, Order, I, A>::data() const
212 {
213 # ifndef NDEBUG
214 if ((numRows()==0) || numCols()==0) {
215 return 0;
216 }
217 # endif
218 return &(this->operator()(_firstRow, _firstCol));
219 }
220
221 template <typename T, StorageOrder Order, typename I, typename A>
222 typename FullStorageView<T, Order, I, A>::ElementType *
223 FullStorageView<T, Order, I, A>::data()
224 {
225 # ifndef NDEBUG
226 if ((numRows()==0) || numCols()==0) {
227 return 0;
228 }
229 # endif
230
231 return &(this->operator()(_firstRow, _firstCol));
232 }
233
234 template <typename T, StorageOrder Order, typename I, typename A>
235 const typename FullStorageView<T, Order, I, A>::Allocator &
236 FullStorageView<T, Order, I, A>::allocator() const
237 {
238 return _allocator;
239 }
240
241 template <typename T, StorageOrder Order, typename I, typename A>
242 bool
243 FullStorageView<T, Order, I, A>::resize(IndexType DEBUG_VAR(_numRows),
244 IndexType DEBUG_VAR(_numCols),
245 IndexType firstRow,
246 IndexType firstCol,
247 const ElementType &)
248 {
249 ASSERT(_numRows==numRows());
250 ASSERT(_numCols==numCols());
251 changeIndexBase(firstRow, firstCol);
252 return false;
253 }
254
255 template <typename T, StorageOrder Order, typename I, typename A>
256 template <typename FS>
257 bool
258 FullStorageView<T, Order, I, A>::resize(const FS &rhs, const ElementType &value)
259 {
260 return resize(rhs.numRows(), rhs.numCols(),
261 rhs.firstRow(), rhs.firstCol(),
262 value);
263 }
264
265 template <typename T, StorageOrder Order, typename I, typename A>
266 bool
267 FullStorageView<T, Order, I, A>::fill(const ElementType &value)
268 {
269 if (Order==RowMajor) {
270 ElementType *p = data();
271 for (IndexType i=0; i<numRows(); ++i, p+=leadingDimension()) {
272 std::fill_n(p, numCols(), value);
273 }
274 return true;
275 }
276 if (Order==ColMajor) {
277 ElementType *p = data();
278 for (IndexType j=0; j<numCols(); ++j, p+=leadingDimension()) {
279 std::fill_n(p, numRows(), value);
280 }
281 return true;
282 }
283 ASSERT(0);
284 return false;
285 }
286
287 template <typename T, StorageOrder Order, typename I, typename A>
288 bool
289 FullStorageView<T, Order, I, A>::fill(StorageUpLo upLo,
290 const ElementType &value)
291 {
292 trapezoidalFill(order, upLo, value,
293 numRows(), numCols(),
294 data(), leadingDimension());
295 return true;
296 }
297
298 template <typename T, StorageOrder Order, typename I, typename A>
299 void
300 FullStorageView<T, Order, I, A>::changeIndexBase(IndexType firstRow,
301 IndexType firstCol)
302 {
303 # ifndef NDEBUG
304 // prevent an out-of-bound assertion in case a view is empty anyway
305 if ((numRows()==0) || (numCols()==0)) {
306 _firstRow = firstRow;
307 _firstCol = firstCol;
308 return;
309 }
310 # endif
311
312 if (Order==RowMajor) {
313 _data = data() - (firstRow*leadingDimension() + firstCol);
314 }
315 if (Order==ColMajor) {
316 _data = data() - (firstCol*leadingDimension() + firstRow);
317 }
318 _firstRow = firstRow;
319 _firstCol = firstCol;
320 }
321
322 // view of fullstorage scheme as an array
323 template <typename T, StorageOrder Order, typename I, typename A>
324 const typename FullStorageView<T, Order, I, A>::ConstArrayView
325 FullStorageView<T, Order, I, A>::arrayView(IndexType firstViewIndex) const
326 {
327 # ifndef NDEBUG
328 if (order==ColMajor) {
329 ASSERT(numRows()==leadingDimension());
330 } else {
331 ASSERT(numCols()==leadingDimension());
332 }
333 # endif
334
335 return ConstArrayView(numCols()*numRows(),
336 data(),
337 IndexType(1),
338 firstViewIndex,
339 allocator());
340 }
341
342 template <typename T, StorageOrder Order, typename I, typename A>
343 typename FullStorageView<T, Order, I, A>::ArrayView
344 FullStorageView<T, Order, I, A>::arrayView(IndexType firstViewIndex)
345 {
346 # ifndef NDEBUG
347 if (order==ColMajor) {
348 ASSERT(numRows()==leadingDimension());
349 } else {
350 ASSERT(numCols()==leadingDimension());
351 }
352 # endif
353
354 return ArrayView(numCols()*numRows(),
355 data(),
356 IndexType(1),
357 firstViewIndex,
358 allocator());
359 }
360
361 // view of rectangular part
362 template <typename T, StorageOrder Order, typename I, typename A>
363 const typename FullStorageView<T, Order, I, A>::ConstView
364 FullStorageView<T, Order, I, A>::view(IndexType fromRow, IndexType fromCol,
365 IndexType toRow, IndexType toCol,
366 IndexType firstViewRow,
367 IndexType firstViewCol) const
368 {
369 const IndexType numRows = toRow-fromRow+1;
370 const IndexType numCols = toCol-fromCol+1;
371
372 # ifndef NDEBUG
373 // prevent an out-of-bound assertion in case a view is empty anyway
374 if ((numRows==0) || (numCols==0)) {
375 return ConstView(numRows, numCols, 0, leadingDimension(),
376 firstViewRow, firstViewCol, allocator());
377 }
378 # endif
379
380 ASSERT(fromRow>=firstRow());
381 ASSERT(fromRow<=toRow);
382 ASSERT(toRow<=lastRow());
383
384 ASSERT(fromCol>=firstCol());
385 ASSERT(fromCol<=toCol);
386 ASSERT(toCol<=lastCol());
387
388 return ConstView(numRows, // # rows
389 numCols, // # cols
390 &(operator()(fromRow, fromCol)), // data
391 leadingDimension(), // leading dimension
392 firstViewRow, // firstRow
393 firstViewCol, // firstCol
394 allocator()); // allocator
395 }
396
397 template <typename T, StorageOrder Order, typename I, typename A>
398 FullStorageView<T, Order, I, A>
399 FullStorageView<T, Order, I, A>::view(IndexType fromRow, IndexType fromCol,
400 IndexType toRow, IndexType toCol,
401 IndexType firstViewRow,
402 IndexType firstViewCol)
403 {
404 const IndexType numRows = toRow-fromRow+1;
405 const IndexType numCols = toCol-fromCol+1;
406
407 # ifndef NDEBUG
408 // prevent an out-of-bound assertion in case a view is empty anyway
409 if ((numRows==0) || (numCols==0)) {
410 return View(numRows, numCols, 0, leadingDimension(),
411 firstViewRow, firstViewCol, allocator());
412 }
413 # endif
414
415 ASSERT(fromRow>=firstRow());
416 ASSERT(fromRow<=toRow);
417 ASSERT(toRow<=lastRow());
418
419 ASSERT(fromCol>=firstCol());
420 ASSERT(fromCol<=toCol);
421 ASSERT(toCol<=lastCol());
422
423 return View(numRows, // # rows
424 numCols, // # cols
425 &(operator()(fromRow, fromCol)), // data
426 leadingDimension(), // leading dimension
427 firstViewRow, // firstRow
428 firstViewCol, // firstCol
429 allocator()); // allocator
430 }
431
432 // view of single row
433 template <typename T, StorageOrder Order, typename I, typename A>
434 const typename FullStorageView<T, Order, I, A>::ConstArrayView
435 FullStorageView<T, Order, I, A>::viewRow(IndexType row,
436 IndexType firstViewIndex) const
437 {
438 # ifndef NDEBUG
439 // prevent an out-of-bound assertion in case a view is empty anyway
440 if (numCols()==0) {
441 return ConstArrayView(numCols(), 0, strideCol(),
442 firstViewIndex, allocator());
443 }
444 # endif
445
446 ASSERT(row>=firstRow());
447 ASSERT(row<=lastRow());
448
449 return ConstArrayView(numCols(),
450 &(operator()(row, _firstCol)),
451 strideCol(),
452 firstViewIndex,
453 allocator());
454 }
455
456 template <typename T, StorageOrder Order, typename I, typename A>
457 typename FullStorageView<T, Order, I, A>::ArrayView
458 FullStorageView<T, Order, I, A>::viewRow(IndexType row,
459 IndexType firstViewIndex)
460 {
461 # ifndef NDEBUG
462 // prevent an out-of-bound assertion in case a view is empty anyway
463 if (numCols()==0) {
464 return ArrayView(numCols(), 0, strideCol(),
465 firstViewIndex, allocator());
466 }
467 # endif
468
469 ASSERT(row>=firstRow());
470 ASSERT(row<=lastRow());
471
472 return ArrayView(numCols(),
473 &(operator()(row, _firstCol)),
474 strideCol(),
475 firstViewIndex,
476 allocator());
477 }
478
479 template <typename T, StorageOrder Order, typename I, typename A>
480 const typename FullStorageView<T, Order, I, A>::ConstArrayView
481 FullStorageView<T, Order, I, A>::viewRow(IndexType row,
482 IndexType firstCol, IndexType lastCol,
483 IndexType firstViewIndex) const
484 {
485 const IndexType length = lastCol-firstCol+1;
486
487 # ifndef NDEBUG
488 // prevent an out-of-bound assertion in case a view is empty anyway
489 if (length==0) {
490 return ConstArrayView(length, 0, strideCol(),
491 firstViewIndex, allocator());
492 }
493 # endif
494
495 ASSERT(row>=firstRow());
496 ASSERT(row<=lastRow());
497
498 return ConstArrayView(length,
499 &(operator()(row, firstCol)),
500 strideCol(),
501 firstViewIndex,
502 allocator());
503 }
504
505 template <typename T, StorageOrder Order, typename I, typename A>
506 typename FullStorageView<T, Order, I, A>::ArrayView
507 FullStorageView<T, Order, I, A>::viewRow(IndexType row,
508 IndexType firstCol, IndexType lastCol,
509 IndexType firstViewIndex)
510 {
511 const IndexType length = lastCol-firstCol+1;
512
513 # ifndef NDEBUG
514 // prevent an out-of-bound assertion in case a view is empty anyway
515 if (length==0) {
516 return ArrayView(length, 0, strideCol(),
517 firstViewIndex, allocator());
518 }
519 # endif
520
521 ASSERT(row>=firstRow());
522 ASSERT(row<=lastRow());
523
524 return ArrayView(length,
525 &(operator()(row, firstCol)),
526 strideCol(),
527 firstViewIndex,
528 allocator());
529 }
530
531 // view of single column
532 template <typename T, StorageOrder Order, typename I, typename A>
533 const typename FullStorageView<T, Order, I, A>::ConstArrayView
534 FullStorageView<T, Order, I, A>::viewCol(IndexType col,
535 IndexType firstViewIndex) const
536 {
537 # ifndef NDEBUG
538 // prevent an out-of-bound assertion in case a view is empty anyway
539 if (numRows()==0) {
540 return ConstArrayView(numRows(), 0, strideRow(),
541 firstViewIndex, allocator());
542 }
543 # endif
544
545 ASSERT(col>=firstCol());
546 ASSERT(col<=lastCol());
547
548 return ConstArrayView(numRows(),
549 &(operator()(_firstRow, col)),
550 strideRow(),
551 firstViewIndex,
552 allocator());
553 }
554
555 template <typename T, StorageOrder Order, typename I, typename A>
556 typename FullStorageView<T, Order, I, A>::ArrayView
557 FullStorageView<T, Order, I, A>::viewCol(IndexType col,
558 IndexType firstViewIndex)
559 {
560 # ifndef NDEBUG
561 // prevent an out-of-bound assertion in case a view is empty anyway
562 if (numRows()==0) {
563 return ArrayView(numRows(), 0, strideRow(),
564 firstViewIndex, allocator());
565 }
566 # endif
567
568 ASSERT(col>=firstCol());
569 ASSERT(col<=lastCol());
570
571 return ArrayView(numRows(),
572 &(operator()(_firstRow, col)),
573 strideRow(),
574 firstViewIndex,
575 allocator());
576 }
577
578 template <typename T, StorageOrder Order, typename I, typename A>
579 const typename FullStorageView<T, Order, I, A>::ConstArrayView
580 FullStorageView<T, Order, I, A>::viewCol(IndexType firstRow, IndexType lastRow,
581 IndexType col,
582 IndexType firstViewIndex) const
583 {
584 const IndexType length = lastRow-firstRow+1;
585
586 # ifndef NDEBUG
587 // prevent an out-of-bound assertion in case a view is empty anyway
588 if (length==0) {
589 return ConstArrayView(length, 0, strideRow(),
590 firstViewIndex, allocator());
591 }
592 # endif
593
594 ASSERT(col>=firstCol());
595 ASSERT(col<=lastCol());
596
597 return ConstArrayView(length,
598 &(operator()(firstRow, col)),
599 strideRow(),
600 firstViewIndex,
601 allocator());
602 }
603
604 template <typename T, StorageOrder Order, typename I, typename A>
605 typename FullStorageView<T, Order, I, A>::ArrayView
606 FullStorageView<T, Order, I, A>::viewCol(IndexType firstRow, IndexType lastRow,
607 IndexType col,
608 IndexType firstViewIndex)
609 {
610 const IndexType length = lastRow-firstRow+1;
611
612 # ifndef NDEBUG
613 // prevent an out-of-bound assertion in case a view is empty anyway
614 if (length==0) {
615 return ArrayView(length, 0, strideRow(),
616 firstViewIndex, allocator());
617 }
618 # endif
619
620 ASSERT(col>=firstCol());
621 ASSERT(col<=lastCol());
622
623 return ArrayView(length,
624 &(operator()(firstRow, col)),
625 strideRow(),
626 firstViewIndex,
627 allocator());
628 }
629
630 // view of d-th diagonal
631 template <typename T, StorageOrder Order, typename I, typename A>
632 const typename FullStorageView<T, Order, I, A>::ConstArrayView
633 FullStorageView<T, Order, I, A>::viewDiag(IndexType d,
634 IndexType firstViewIndex) const
635 {
636 IndexType _row = (d>0) ? 0 : -d;
637 IndexType _col = (d>0) ? d : 0;
638
639 IndexType row = firstRow() + _row;
640 IndexType col = firstCol() + _col;
641
642 return ConstArrayView(std::min(numRows()-_row, numCols()-_col),
643 &(operator()(row,col)),
644 leadingDimension()+1,
645 firstViewIndex,
646 allocator());
647 }
648
649 template <typename T, StorageOrder Order, typename I, typename A>
650 typename FullStorageView<T, Order, I, A>::ArrayView
651 FullStorageView<T, Order, I, A>::viewDiag(IndexType d,
652 IndexType firstViewIndex)
653 {
654 IndexType _row = (d>0) ? 0 : -d;
655 IndexType _col = (d>0) ? d : 0;
656
657 IndexType row = firstRow() + _row;
658 IndexType col = firstCol() + _col;
659
660 return ArrayView(std::min(numRows()-_row,numCols()-_col),
661 &(operator()(row,col)),
662 leadingDimension()+1,
663 firstViewIndex,
664 allocator());
665 }
666
667 } // namespace flens
668
669 #endif // FLENS_STORAGE_FULLSTORAGE_FULLSTORAGEVIEW_TCC