tpmv.hpp
Go to the documentation of this file.
1//===========================================================================
2/*!
3 *
4 * \brief Implements the triangular packed matrix-vector multiplication
5 *
6 * \author O. Krause
7 * \date 2010
8 *
9 *
10 * \par Copyright 1995-2015 Shark Development Team
11 *
12 * <BR><HR>
13 * This file is part of Shark.
14 * <http://image.diku.dk/shark/>
15 *
16 * Shark is free software: you can redistribute it and/or modify
17 * it under the terms of the GNU Lesser General Public License as published
18 * by the Free Software Foundation, either version 3 of the License, or
19 * (at your option) any later version.
20 *
21 * Shark is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU Lesser General Public License for more details.
25 *
26 * You should have received a copy of the GNU Lesser General Public License
27 * along with Shark. If not, see <http://www.gnu.org/licenses/>.
28 *
29 */
30//===========================================================================
31#ifndef REMORA_KERNELS_DEFAULT_tpmv_HPP
32#define REMORA_KERNELS_DEFAULT_tpmv_HPP
33
34#include "../../expression_types.hpp" //matrix/vector_expression
35#include "../../detail/traits.hpp" //orientations and triangular types
36#include <type_traits> //std::false_type marker for unoptimized
37
38
39namespace remora{ namespace bindings{
40
41//Lower triangular(row-major) - vector product
42// computes the row-wise inner product of the matrix
43// starting with row 0 and stores the result in b(i)
44//this does not interfere with the next products as
45// the element b(i) is not needed for iterations j > i
46template<class MatA, class V>
47void tpmv_impl(
48 matrix_expression<MatA, cpu_tag> const& A,
49 vector_expression<V, cpu_tag>& b,
50 row_major,
51 upper
52){
53 typedef typename V::value_type value_type;
54 typedef typename V::size_type size_type;
55 size_type size = A().size1();
56
57 for(size_type i = 0; i != size; ++i){
58 value_type sum(0);
59 auto end = A().major_end(i);
60 for(auto pos = A().major_begin(i); pos != end; ++pos){
61 sum += *pos * b()(pos.index());
62 }
63 b()(i) = sum;
64 }
65}
66
67//Upper triangular(row-major) - vector product
68// computes the row-wise inner product of the matrix
69// starting with the last row and stores the result in b(i)
70// this does not interfere with the next products as
71// the element b(i) is not needed for row products j < i
72template<class MatA, class V>
73void tpmv_impl(
74 matrix_expression<MatA, cpu_tag> const& A,
75 vector_expression<V, cpu_tag>& b,
76 row_major,
77 lower
78){
79 typedef typename V::value_type value_type;
80 typedef typename V::size_type size_type;
81 size_type size = A().size1();
82
83 for(size_type irev = size; irev != 0; --irev){
84 size_type i= irev-1;
85 value_type sum(0);
86 auto end = A().major_end(i);
87 for(auto pos = A().major_begin(i); pos != end; ++pos){
88 sum += *pos * b()(pos.index());
89 }
90 b()(i) = sum;
91 }
92}
93
94//Upper triangular(column-major) - vector product
95//computes the product as a series of vector-additions
96//on b starting with the last column of A.
97template<class MatA, class V>
98void tpmv_impl(
99 matrix_expression<MatA, cpu_tag> const& A,
100 vector_expression<V, cpu_tag>& b,
101 column_major,
102 upper
103){
104 typedef typename V::size_type size_type;
105 typedef typename V::value_type value_type;
106 size_type size = A().size1();
107 for(size_type i = 0; i != size; ++i){
108 value_type bi = b()(i);
109 b()(i)= value_type/*zero*/();
110 auto end = A().major_end(i);
111 for(auto pos = A().major_begin(i); pos != end; ++pos){
112 b()(pos.index()) += *pos*bi;
113 }
114 }
115
116}
117
118//Lower triangular(column-major) - vector product
119// computes the product as a series of vector-additions
120// on b starting with the first column of A.
121template<class MatA, class V>
122void tpmv_impl(
123 matrix_expression<MatA, cpu_tag> const& A,
124 vector_expression<V, cpu_tag>& b,
125 column_major,
126 lower
127){
128 typedef typename V::size_type size_type;
129 typedef typename V::value_type value_type;
130 size_type size = A().size1();
131
132 for(size_type irev = size; irev != 0; --irev){
133 size_type i= irev-1;
134 value_type bi = b()(i);
135 b()(i)= value_type/*zero*/();
136 auto end = A().major_end(i);
137 for(auto pos = A().major_begin(i); pos != end; ++pos){
138 b()(pos.index()) += *pos*bi;
139 }
140 }
141}
142
143//dispatcher
144template <typename MatA, typename V>
145void tpmv(
146 matrix_expression<MatA, cpu_tag> const& A,
147 vector_expression<V, cpu_tag>& b,
148 std::false_type//unoptimized
149){
150 REMORA_SIZE_CHECK(A().size1() == A().size2());
151 REMORA_SIZE_CHECK(A().size2() == b().size());
152 tpmv_impl(
153 A, b,
154 typename MatA::orientation::orientation(),
155 typename MatA::orientation::triangular_type()
156 );
157}
158
159}}
160#endif