38 #ifndef GMM_TRI_SOLVE_H__
39 #define GMM_TRI_SOLVE_H__
45 template <
typename TriMatrix,
typename VecX>
46 void upper_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
47 col_major, abstract_sparse,
bool is_unit) {
48 typename linalg_traits<TriMatrix>::value_type x_j;
49 for (
int j =
int(k) - 1; j >= 0; --j) {
50 typedef typename linalg_traits<TriMatrix>::const_sub_col_type COL;
51 COL c = mat_const_col(T, j);
52 typename linalg_traits<typename org_type<COL>::t>::const_iterator
53 it = vect_const_begin(c), ite = vect_const_end(c);
54 if (!is_unit) x[j] /= c[j];
55 for (x_j = x[j]; it != ite ; ++it)
56 if (
int(it.index()) < j) x[it.index()] -= x_j * (*it);
60 template <
typename TriMatrix,
typename VecX>
61 void upper_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
62 col_major, abstract_dense,
bool is_unit) {
63 typename linalg_traits<TriMatrix>::value_type x_j;
64 for (
int j =
int(k) - 1; j >= 0; --j) {
65 typedef typename linalg_traits<TriMatrix>::const_sub_col_type COL;
66 COL c = mat_const_col(T, j);
67 typename linalg_traits<typename org_type<COL>::t>::const_iterator
68 it = vect_const_begin(c), ite = it + j;
69 typename linalg_traits<VecX>::iterator itx = vect_begin(x);
70 if (!is_unit) x[j] /= c[j];
71 for (x_j = x[j]; it != ite ; ++it, ++itx) *itx -= x_j * (*it);
75 template <
typename TriMatrix,
typename VecX>
76 void lower_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
77 col_major, abstract_sparse,
bool is_unit) {
78 typename linalg_traits<TriMatrix>::value_type x_j;
81 for (
int j = 0; j < int(k); ++j) {
82 typedef typename linalg_traits<TriMatrix>::const_sub_col_type COL;
83 COL c = mat_const_col(T, j);
84 typename linalg_traits<typename org_type<COL>::t>::const_iterator
85 it = vect_const_begin(c), ite = vect_const_end(c);
86 if (!is_unit) x[j] /= c[j];
87 for (x_j = x[j]; it != ite ; ++it)
88 if (
int(it.index()) > j && it.index() < k) x[it.index()] -= x_j*(*it);
92 template <
typename TriMatrix,
typename VecX>
93 void lower_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
94 col_major, abstract_dense,
bool is_unit) {
95 typename linalg_traits<TriMatrix>::value_type x_j;
96 for (
int j = 0; j < int(k); ++j) {
97 typedef typename linalg_traits<TriMatrix>::const_sub_col_type COL;
98 COL c = mat_const_col(T, j);
99 typename linalg_traits<typename org_type<COL>::t>::const_iterator
100 it = vect_const_begin(c) + (j+1), ite = vect_const_begin(c) + k;
101 typename linalg_traits<VecX>::iterator itx = vect_begin(x) + (j+1);
102 if (!is_unit) x[j] /= c[j];
103 for (x_j = x[j]; it != ite ; ++it, ++itx) *itx -= x_j * (*it);
108 template <
typename TriMatrix,
typename VecX>
109 void upper_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
110 row_major, abstract_sparse,
bool is_unit) {
111 typedef typename linalg_traits<TriMatrix>::const_sub_row_type ROW;
112 typename linalg_traits<TriMatrix>::value_type t;
113 typename linalg_traits<TriMatrix>::const_row_iterator
114 itr = mat_row_const_end(T);
115 for (
int i =
int(k) - 1; i >= 0; --i) {
117 ROW c = linalg_traits<TriMatrix>::row(itr);
118 typename linalg_traits<typename org_type<ROW>::t>::const_iterator
119 it = vect_const_begin(c), ite = vect_const_end(c);
120 for (t = x[i]; it != ite; ++it)
121 if (
int(it.index()) > i && it.index() < k) t -= (*it) * x[it.index()];
122 if (!is_unit) x[i] = t / c[i];
else x[i] = t;
126 template <
typename TriMatrix,
typename VecX>
127 void upper_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
128 row_major, abstract_dense,
bool is_unit) {
129 typename linalg_traits<TriMatrix>::value_type t;
131 for (
int i =
int(k) - 1; i >= 0; --i) {
132 typedef typename linalg_traits<TriMatrix>::const_sub_row_type ROW;
133 ROW c = mat_const_row(T, i);
134 typename linalg_traits<typename org_type<ROW>::t>::const_iterator
135 it = vect_const_begin(c) + (i + 1), ite = vect_const_begin(c) + k;
136 typename linalg_traits<VecX>::iterator itx = vect_begin(x) + (i+1);
138 for (t = x[i]; it != ite; ++it, ++itx) t -= (*it) * (*itx);
139 if (!is_unit) x[i] = t / c[i];
else x[i] = t;
143 template <
typename TriMatrix,
typename VecX>
144 void lower_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
145 row_major, abstract_sparse,
bool is_unit) {
146 typename linalg_traits<TriMatrix>::value_type t;
148 for (
int i = 0; i < int(k); ++i) {
149 typedef typename linalg_traits<TriMatrix>::const_sub_row_type ROW;
150 ROW c = mat_const_row(T, i);
151 typename linalg_traits<typename org_type<ROW>::t>::const_iterator
152 it = vect_const_begin(c), ite = vect_const_end(c);
154 for (t = x[i]; it != ite; ++it)
155 if (
int(it.index()) < i) t -= (*it) * x[it.index()];
156 if (!is_unit) x[i] = t / c[i];
else x[i] = t;
160 template <
typename TriMatrix,
typename VecX>
161 void lower_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
162 row_major, abstract_dense,
bool is_unit) {
163 typename linalg_traits<TriMatrix>::value_type t;
165 for (
int i = 0; i < int(k); ++i) {
166 typedef typename linalg_traits<TriMatrix>::const_sub_row_type ROW;
167 ROW c = mat_const_row(T, i);
168 typename linalg_traits<typename org_type<ROW>::t>::const_iterator
169 it = vect_const_begin(c), ite = it + i;
170 typename linalg_traits<VecX>::iterator itx = vect_begin(x);
172 for (t = x[i]; it != ite; ++it, ++itx) t -= (*it) * (*itx);
173 if (!is_unit) x[i] = t / c[i];
else x[i] = t;
180 template <
typename TriMatrix,
typename VecX>
inline
181 void upper_tri_solve(
const TriMatrix& T, VecX &x_,
bool is_unit =
false)
182 { upper_tri_solve(T, x_, mat_nrows(T), is_unit); }
184 template <
typename TriMatrix,
typename VecX>
inline
185 void lower_tri_solve(
const TriMatrix& T, VecX &x_,
bool is_unit =
false)
186 { lower_tri_solve(T, x_, mat_nrows(T), is_unit); }
188 template <
typename TriMatrix,
typename VecX>
inline
189 void upper_tri_solve(
const TriMatrix& T, VecX &x_,
size_t k,
191 VecX& x =
const_cast<VecX&
>(x_);
192 GMM_ASSERT2(mat_nrows(T) >= k && vect_size(x) >= k
193 && mat_ncols(T) >= k && !is_sparse(x_),
"dimensions mismatch");
194 upper_tri_solve__(T, x, k,
195 typename principal_orientation_type<
typename
196 linalg_traits<TriMatrix>::sub_orientation>::potype(),
197 typename linalg_traits<TriMatrix>::storage_type(),
201 template <
typename TriMatrix,
typename VecX>
inline
202 void lower_tri_solve(
const TriMatrix& T, VecX &x_,
size_t k,
204 VecX& x =
const_cast<VecX&
>(x_);
205 GMM_ASSERT2(mat_nrows(T) >= k && vect_size(x) >= k
206 && mat_ncols(T) >= k && !is_sparse(x_),
"dimensions mismatch");
207 lower_tri_solve__(T, x, k,
208 typename principal_orientation_type<
typename
209 linalg_traits<TriMatrix>::sub_orientation>::potype(),
210 typename linalg_traits<TriMatrix>::storage_type(),
222 #endif // GMM_TRI_SOLVE_H__