30#ifndef REMORA_KERNELS_DEFAULT_TRSV_HPP
31#define REMORA_KERNELS_DEFAULT_TRSV_HPP
33#include "../../detail/traits.hpp"
34#include "../../assignment.hpp"
36#include "../../proxy_expressions.hpp"
41namespace remora {
namespace bindings {
44template<
bool Unit,
class MatA,
class V>
46 matrix_expression<MatA, cpu_tag>
const& A,
47 vector_expression<V, cpu_tag> &b,
48 lower, column_major, left
50 REMORA_SIZE_CHECK(A().size1() == A().size2());
51 REMORA_SIZE_CHECK(A().size2() == b().size());
53 typedef typename MatA::value_type value_type;
54 typedef device_traits<cpu_tag>::multiply_and_add<value_type> MultAdd;
55 std::size_t size = b().size();
56 for (std::size_t n = 0; n != size; ++ n) {
58 if(A()(n, n) == value_type()){
59 throw std::invalid_argument(
"[TRSV] Matrix is singular!");
63 if (b()(n) != value_type()){
64 auto blower = subrange(b,n+1,size);
65 auto colAlower = subrange(column(A,n),n+1,size);
66 kernels::assign(blower, colAlower, MultAdd(-b()(n)));
71template<
bool Unit,
class MatA,
class V>
73 matrix_expression<MatA, cpu_tag>
const& A,
74 vector_expression<V, cpu_tag> &b,
75 lower, row_major, left
77 REMORA_SIZE_CHECK(A().size1() == A().size2());
78 REMORA_SIZE_CHECK(A().size2() == b().size());
80 typedef typename V::value_type value_type;
82 std::size_t size = b().size();
83 for (std::size_t n = 0; n < size; ++ n) {
85 kernels::dot(subrange(b,0,n),subrange(row(A,n),0,n),value);
88 if(A()(n, n) == value_type()){
89 throw std::invalid_argument(
"[TRSV] Matrix is singular!");
97template<
bool Unit,
class MatA,
class V>
99 matrix_expression<MatA, cpu_tag>
const& A,
100 vector_expression<V, cpu_tag> &b,
101 upper, column_major, left
103 REMORA_SIZE_CHECK(A().size1() == A().size2());
104 REMORA_SIZE_CHECK(A().size2() == b().size());
106 typedef typename MatA::value_type value_type;
107 typedef device_traits<cpu_tag>::multiply_and_add<value_type> MultAdd;
108 std::size_t size = b().size();
109 for (std::size_t i = 0; i < size; ++ i) {
110 std::size_t n = size-i-1;
112 if(A()(n, n) == value_type()){
113 throw std::invalid_argument(
"[TRSV] Matrix is singular!");
117 if (b()(n) != value_type()) {
118 auto blower = subrange(b(),0,n);
119 auto colAlower = subrange(column(A,n),0,n);
120 kernels::assign(blower, colAlower, MultAdd(-b()(n)));
125template<
bool Unit,
class MatA,
class V>
127 matrix_expression<MatA, cpu_tag>
const& A,
128 vector_expression<V, cpu_tag> &b,
129 upper, row_major, left
131 REMORA_SIZE_CHECK(A().size1() == A().size2());
132 REMORA_SIZE_CHECK(A().size2() == b().size());
134 typedef typename MatA::value_type value_type;
136 std::size_t size = A().size1();
137 for (std::size_t i = 0; i < size; ++ i) {
138 std::size_t n = size-i-1;
140 kernels::dot(subrange(b(),n+1,size),subrange(row(A,n),n+1,size),value);
143 if(A()(n, n) == value_type()){
144 throw std::invalid_argument(
"[TRSV] Matrix is singular!");
153template<
bool Unit,
class Triangular,
class Orientation,
class MatA,
class V>
155 matrix_expression<MatA, cpu_tag>
const& A,
156 vector_expression<V, cpu_tag> &b,
157 Triangular, Orientation, right
161 typename Triangular::transposed_orientation(),
162 typename Orientation::transposed_orientation(),
168template <
class Triangular,
class S
ide,
typename MatA,
typename V>
170 matrix_expression<MatA, cpu_tag>
const& A,
171 vector_expression<V, cpu_tag> & b,
174 trsv_impl<Triangular::is_unit>(
176 triangular_tag<Triangular::is_upper,false>(),
177 typename MatA::orientation(), Side()