28 #ifndef REMORA_SOLVE_HPP 29 #define REMORA_SOLVE_HPP 40 template<
class MatA,
class VecV,
class SystemType,
class S
ide>
41 class matrix_vector_solve:
public vector_expression<
42 matrix_vector_solve<MatA, VecV,SystemType, Side>,
43 typename MatA::device_type
46 typedef typename MatA::const_closure_type matrix_closure_type;
47 typedef typename VecV::const_closure_type vector_closure_type;
49 typename MatA::value_type() *
typename VecV::value_type()
51 typedef typename MatA::size_type size_type;
52 typedef value_type const_reference;
53 typedef const_reference reference;
55 typedef matrix_vector_solve const_closure_type;
56 typedef const_closure_type closure_type;
57 typedef unknown_storage storage_type;
58 typedef unknown_storage const_storage_type;
59 typedef blockwise<dense_tag> evaluation_category;
60 typedef typename MatA::device_type device_type;
62 size_type size()
const {
65 typename device_traits<device_type>::queue_type& queue()
const{
66 return m_matrix.queue();
69 matrix_closure_type
const& matrix, vector_closure_type
const&rhs,
70 SystemType system_type = SystemType()
71 ):m_matrix(matrix), m_rhs(rhs), m_system_type(system_type){}
73 matrix_closure_type
const& lhs()
const{
77 vector_closure_type
const& rhs()
const{
81 SystemType
const& system_type()
const{
85 typedef typename MatA::const_row_iterator iterator;
86 typedef iterator const_iterator;
90 void assign_to(vector_expression<VecX, device_type>& x, value_type alpha)
const{
91 assign(x,m_rhs,alpha);
92 solver<MatA,SystemType> alg(m_matrix, m_system_type);
96 void plus_assign_to(vector_expression<VecX, device_type>& x, value_type alpha)
const{
97 typename vector_temporary<VecX>::type temp(m_rhs);
98 solver<MatA,SystemType> alg(m_matrix, m_system_type);
99 alg.solve(temp,Side());
100 plus_assign(x,temp,alpha);
103 matrix_closure_type m_matrix;
104 vector_closure_type m_rhs;
105 SystemType m_system_type;
109 template<
class MatA,
class MatB,
class SystemType,
class S
ide>
110 class matrix_matrix_solve:
public matrix_expression<
111 matrix_matrix_solve<MatA, MatB, SystemType, Side>,
112 typename MatA::device_type
115 typedef typename MatA::const_closure_type matrixA_closure_type;
116 typedef typename MatB::const_closure_type matrixB_closure_type;
118 typename MatA::value_type() *
typename MatB::value_type()
120 typedef typename MatA::size_type size_type;
121 typedef value_type const_reference;
122 typedef const_reference reference;
124 typedef matrix_matrix_solve const_closure_type;
125 typedef const_closure_type closure_type;
126 typedef unknown_storage storage_type;
127 typedef unknown_storage const_storage_type;
128 typedef blockwise<dense_tag> evaluation_category;
129 typedef typename MatA::device_type device_type;
130 typedef unknown_orientation orientation;
133 matrixA_closure_type const& matrix, matrixB_closure_type const& rhs,
134 SystemType const& system_type =SystemType()
135 ):m_matrix(matrix), m_rhs(rhs), m_system_type(system_type){}
137 size_type size1()
const {
138 return m_rhs.size1();
140 size_type size2()
const {
141 return m_rhs.size2();
143 typename device_traits<device_type>::queue_type& queue()
const{
144 return m_matrix.queue();
147 matrixA_closure_type
const& lhs()
const{
151 matrixB_closure_type
const& rhs()
const{
155 SystemType
const& system_type()
const{
156 return m_system_type;
159 typedef typename MatA::const_row_iterator row_iterator;
160 typedef row_iterator const_row_iterator;
161 typedef typename MatA::const_column_iterator column_iterator;
162 typedef column_iterator const_column_iterator;
166 void assign_to(matrix_expression<MatX, device_type>& X, value_type alpha)
const{
167 assign(X,m_rhs,alpha);
168 solver<MatA,SystemType> alg(m_matrix,m_system_type);
172 void plus_assign_to(matrix_expression<MatX, device_type>& X, value_type alpha)
const{
173 typename matrix_temporary<MatX>::type temp(m_rhs);
174 solver<MatA,SystemType> alg(m_matrix,m_system_type);
175 alg.solve(temp,Side());
176 plus_assign(X,temp,alpha);
179 matrixA_closure_type m_matrix;
180 matrixB_closure_type m_rhs;
181 SystemType m_system_type;
184 template<
class MatA,
class SystemType>
185 class matrix_inverse:
public matrix_expression<
186 matrix_inverse<MatA, SystemType>,
187 typename MatA::device_type
190 typedef typename MatA::const_closure_type matrix_closure_type;
191 typedef typename MatA::value_type value_type;
192 typedef typename MatA::size_type size_type;
193 typedef value_type const_reference;
194 typedef const_reference reference;
196 typedef matrix_inverse const_closure_type;
197 typedef const_closure_type closure_type;
198 typedef unknown_storage storage_type;
199 typedef unknown_storage const_storage_type;
200 typedef blockwise<dense_tag> evaluation_category;
201 typedef typename MatA::device_type device_type;
202 typedef typename MatA::orientation orientation;
204 matrix_inverse(matrix_closure_type
const& matrix, SystemType system_type)
205 :m_matrix(matrix), m_system_type(system_type){}
207 size_type size1()
const {
208 return m_matrix.size1();
210 size_type size2()
const {
211 return m_matrix.size1();
214 typename device_traits<device_type>::queue_type& queue()
const{
215 return m_matrix.queue();
218 matrix_closure_type
const& matrix()
const{
222 SystemType
const& system_type()
const{
223 return m_system_type;
226 typedef typename MatA::const_row_iterator row_iterator;
227 typedef row_iterator const_row_iterator;
228 typedef typename MatA::const_column_iterator column_iterator;
229 typedef column_iterator const_column_iterator;
233 void assign_to(matrix_expression<MatX, device_type>& X, value_type alpha)
const{
234 typedef scalar_vector<value_type, device_type> diag_vec;
235 assign(X,diagonal_matrix<diag_vec>(diag_vec(size1(),value_type(1))),alpha);
236 solver<MatA,SystemType> alg(m_matrix,m_system_type);
240 void plus_assign_to(matrix_expression<MatX, device_type>& X, value_type alpha)
const{
241 typedef scalar_vector<value_type, device_type> diag_vec;
242 typename matrix_temporary<MatX>::type temp = diagonal_matrix<diag_vec>(diag_vec(size1(),value_type(1)),alpha);
243 solver<MatA,SystemType> alg(m_matrix,m_system_type);
244 alg.solve(temp,left());
245 plus_assign(X,temp,alpha);
248 matrix_closure_type m_matrix;
249 SystemType m_system_type;
261 template<
class M,
class V,
class Tag,
class S
ide>
262 struct matrix_vector_solve_optimizer{
263 typedef matrix_vector_solve<M,V, Tag, Side> type;
266 typename M::const_closure_type
const& m,
267 typename V::const_closure_type
const& v,
277 template<
class M1,
class M2,
class Tag,
class S
ide>
278 struct matrix_matrix_solve_optimizer{
279 typedef matrix_matrix_solve<M1,M2, Tag, Side> type;
282 typename M1::const_closure_type
const& lhs,
283 typename M2::const_closure_type
const& rhs,
286 return type(lhs,rhs,t);
293 template<
class M,
class Tag>
294 struct matrix_inverse_optimizer{
295 typedef matrix_inverse<M, Tag> type;
297 static type create(
typename M::const_closure_type
const& m, Tag t){
308 struct solve_tag_transpose_helper{
309 static T transpose(T t){
return t;}
311 template<
bool Upper,
bool Unit>
312 struct solve_tag_transpose_helper<triangular_tag<Upper,Unit> >{
313 static triangular_tag<!Upper,Unit> transpose(triangular_tag<Upper,Unit>){
return triangular_tag<!Upper,Unit>();}
318 template<
class M1,
class M2,
bool Left,
class Tag>
319 struct matrix_transpose_optimizer<matrix_matrix_solve<M1,M2, Tag, system_tag<Left> > >{
320 typedef matrix_transpose_optimizer<typename const_expression<M2>::type> lhs_opt;
321 typedef matrix_transpose_optimizer<typename const_expression<M1>::type> rhs_opt;
322 typedef matrix_matrix_solve_optimizer<
323 typename lhs_opt::type,
typename rhs_opt::type,
324 typename Tag::transposed_tag, system_tag<!Left>
326 typedef typename opt::type type;
328 static type create(matrix_matrix_solve<M1,M2, Tag, system_tag<Left> >
const& m){
330 lhs_opt::create(m.rhs()),rhs_opt::create(m.lhs()),
331 solve_tag_transpose_helper<Tag>::transpose(m.system_type())
337 template<
class M,
class Tag>
338 struct matrix_transpose_optimizer<matrix_inverse<M, Tag> >{
339 typedef matrix_transpose_optimizer<typename const_expression<M>::type> mat_opt;
340 typedef matrix_inverse_optimizer<
341 typename mat_opt::type,
typename Tag::transposed_orientation
343 typedef typename opt::type type;
345 static type create(matrix_inverse<M, Tag>
const& m){
347 mat_opt::create(m.matrix()),
348 solve_tag_transpose_helper<Tag>::transpose(m.system_type())
356 template<
class M,
class V,
class Tag>
357 struct matrix_vector_prod_optimizer<matrix_inverse<M,Tag>, V>{
358 typedef matrix_vector_solve_optimizer<M,V, Tag, left> opt;
359 typedef typename opt::type type;
361 static type create(matrix_inverse<M,Tag>
const& inv,
typename V::const_closure_type
const& v){
362 return opt::create(inv.matrix(),v,inv.system_type());
367 template<
class M1,
class M2,
class V,
class Tag>
368 struct matrix_vector_prod_optimizer<matrix_matrix_solve<M1,M2, Tag, left >, V >{
369 typedef matrix_vector_prod_optimizer<M2,V> prod_opt;
370 typedef matrix_vector_solve_optimizer<M1, typename prod_opt::type, Tag, left> opt;
371 typedef typename opt::type type;
373 static type create(matrix_matrix_solve<M1,M2, Tag, left>
const& m,
typename V::const_closure_type
const& v){
375 m.lhs(), prod_opt::create(m.rhs(),v), m.system_type()
381 template<
class M1,
class M2,
class V,
class Tag>
382 struct matrix_vector_prod_optimizer<matrix_matrix_solve<M1,M2, Tag, right >, V >{
383 typedef matrix_vector_solve_optimizer<M1, V, Tag, left> solve_opt;
384 typedef matrix_vector_prod_optimizer<M2,typename solve_opt::type> opt;
385 typedef typename opt::type type;
386 static type create(matrix_matrix_solve<M1,M2, Tag, right>
const& m,
typename V::const_closure_type
const& v){
388 m.rhs(), solve_opt::create(m.lhs(),v,m.system_type())
394 template<
class M1,
class M2,
class Tag>
395 struct matrix_row_optimizer<matrix_matrix_solve<M1,M2, Tag, left > >{
396 typedef matrix_transpose_optimizer<typename const_expression<M2>::type> rhs_opt;
397 typedef unit_vector<typename M1::value_type, typename M1::device_type> unit;
398 typedef matrix_vector_solve_optimizer<M1, unit, Tag, right> solve_opt;
399 typedef matrix_vector_prod_optimizer<typename rhs_opt::type,typename solve_opt::type> opt;
400 typedef typename opt::type type;
402 static type create(matrix_matrix_solve<M1,M2, Tag, left>
const& m, std::size_t i){
404 rhs_opt::create(m.rhs()),
405 solve_opt::create(m.lhs(),unit(m.lhs().size2(),i), m.system_type())
411 template<
class M1,
class M2,
class Tag>
412 struct matrix_row_optimizer<matrix_matrix_solve<M1,M2, Tag, right > >{
413 typedef matrix_row_optimizer<typename const_expression<M2>::type> rhs_opt;
414 typedef matrix_vector_solve_optimizer<M1, typename rhs_opt::type, Tag, right> opt;
415 typedef typename opt::type type;
417 static type create(matrix_matrix_solve<M1,M2, Tag, right>
const& m, std::size_t i){
418 return opt::create(m.lhs(),rhs_opt::create(m.rhs(),i), m.system_type());
423 template<
class M,
class Tag>
424 struct matrix_row_optimizer<matrix_inverse<M, Tag > >{
425 typedef unit_vector<typename M::value_type, typename M::device_type> unit;
426 typedef matrix_vector_solve_optimizer<M, unit, Tag, right> opt;
427 typedef typename opt::type type;
429 static type create(matrix_inverse<M, Tag >
const& m, std::size_t i){
430 return opt::create(m.matrix(), unit(m.lhs().size2(),i), m.system_type());
435 template<
class M1,
class M2,
class Tag>
436 struct matrix_matrix_prod_optimizer<matrix_inverse<M1,Tag>, M2>{
437 typedef matrix_matrix_solve_optimizer<M1,M2, Tag, left> opt;
438 typedef typename opt::type type;
440 static type create(matrix_inverse<M1,Tag>
const& inv,
typename M2::const_closure_type
const& m){
441 return opt::create(inv.matrix(),m,inv.system_type());
446 template<
class M1,
class M2,
class Tag>
447 struct matrix_matrix_prod_optimizer<M1, matrix_inverse<M2,Tag> >{
448 typedef matrix_matrix_solve_optimizer<M2,M1, Tag, right> opt;
449 typedef typename opt::type type;
451 static type create(
typename M1::const_closure_type
const& m, matrix_inverse<M2,Tag>
const& inv){
452 return opt::create(inv.matrix(),m,inv.system_type());
461 template<
class MatA,
class VecB,
bool Left,
class Device,
class SystemType>
462 typename detail::matrix_vector_solve_optimizer<MatA,VecB, SystemType, system_tag<Left> >::type
464 matrix_expression<MatA, Device>
const& A,
465 vector_expression<VecB, Device>
const& b,
466 SystemType t, system_tag<Left>
468 REMORA_SIZE_CHECK(A().size1() == A().size2());
469 REMORA_SIZE_CHECK(A().size1() == b().size());
470 typedef detail::matrix_vector_solve_optimizer<MatA,VecB, SystemType, system_tag<Left> > opt;
471 return opt::create(A(),b(), t);
474 template<
class MatA,
class MatB,
bool Left,
class Device,
class SystemType>
475 typename detail::matrix_matrix_solve_optimizer<MatA,MatB, SystemType, system_tag<Left> >::type
477 matrix_expression<MatA, Device>
const& A,
478 matrix_expression<MatB, Device>
const& B,
479 SystemType t, system_tag<Left>
481 REMORA_SIZE_CHECK(A().size1() == A().size2());
482 typedef detail::matrix_matrix_solve_optimizer<MatA,MatB, SystemType, system_tag<Left> > opt;
483 return opt::create(A(),B(), t);
487 template<
class MatA,
class Device,
class SystemType>
488 typename detail::matrix_inverse_optimizer<MatA, SystemType>::type
490 matrix_expression<MatA, Device>
const& A, SystemType t
492 REMORA_SIZE_CHECK(A().size1() == A().size2());
493 typedef detail::matrix_inverse_optimizer<MatA,SystemType> opt;
494 return opt::create(A(), t);