37 #ifndef GMM_TRI_SOLVE_H__
38 #define GMM_TRI_SOLVE_H__
44 template <
typename TriMatrix,
typename VecX>
45 void upper_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
46 col_major, abstract_sparse,
bool is_unit) {
47 typename linalg_traits<TriMatrix>::value_type x_j;
48 for (
int j =
int(k) - 1; j >= 0; --j) {
49 typedef typename linalg_traits<TriMatrix>::const_sub_col_type COL;
50 COL c = mat_const_col(T, j);
51 typename linalg_traits<typename org_type<COL>::t>::const_iterator
52 it = vect_const_begin(c), ite = vect_const_end(c);
53 if (!is_unit) x[j] /= c[j];
54 for (x_j = x[j]; it != ite ; ++it)
55 if (
int(it.index()) < j) x[it.index()] -= x_j * (*it);
59 template <
typename TriMatrix,
typename VecX>
60 void upper_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
61 col_major, abstract_dense,
bool is_unit) {
62 typename linalg_traits<TriMatrix>::value_type x_j;
63 for (
int j =
int(k) - 1; j >= 0; --j) {
64 typedef typename linalg_traits<TriMatrix>::const_sub_col_type COL;
65 COL c = mat_const_col(T, j);
66 typename linalg_traits<typename org_type<COL>::t>::const_iterator
67 it = vect_const_begin(c), ite = it + j;
68 typename linalg_traits<VecX>::iterator itx = vect_begin(x);
69 if (!is_unit) x[j] /= c[j];
70 for (x_j = x[j]; it != ite ; ++it, ++itx) *itx -= x_j * (*it);
74 template <
typename TriMatrix,
typename VecX>
75 void lower_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
76 col_major, abstract_sparse,
bool is_unit) {
77 typename linalg_traits<TriMatrix>::value_type x_j;
80 for (
int j = 0; j < int(k); ++j) {
81 typedef typename linalg_traits<TriMatrix>::const_sub_col_type COL;
82 COL c = mat_const_col(T, j);
83 typename linalg_traits<typename org_type<COL>::t>::const_iterator
84 it = vect_const_begin(c), ite = vect_const_end(c);
85 if (!is_unit) x[j] /= c[j];
86 for (x_j = x[j]; it != ite ; ++it)
87 if (
int(it.index()) > j && it.index() < k) x[it.index()] -= x_j*(*it);
91 template <
typename TriMatrix,
typename VecX>
92 void lower_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
93 col_major, abstract_dense,
bool is_unit) {
94 typename linalg_traits<TriMatrix>::value_type x_j;
95 for (
int j = 0; j < int(k); ++j) {
96 typedef typename linalg_traits<TriMatrix>::const_sub_col_type COL;
97 COL c = mat_const_col(T, j);
98 typename linalg_traits<typename org_type<COL>::t>::const_iterator
99 it = vect_const_begin(c) + (j+1), ite = vect_const_begin(c) + k;
100 typename linalg_traits<VecX>::iterator itx = vect_begin(x) + (j+1);
101 if (!is_unit) x[j] /= c[j];
102 for (x_j = x[j]; it != ite ; ++it, ++itx) *itx -= x_j * (*it);
107 template <
typename TriMatrix,
typename VecX>
108 void upper_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
109 row_major, abstract_sparse,
bool is_unit) {
110 typedef typename linalg_traits<TriMatrix>::const_sub_row_type ROW;
111 typename linalg_traits<TriMatrix>::value_type t;
112 typename linalg_traits<TriMatrix>::const_row_iterator
113 itr = mat_row_const_end(T);
114 for (
int i =
int(k) - 1; i >= 0; --i) {
116 ROW c = linalg_traits<TriMatrix>::row(itr);
117 typename linalg_traits<typename org_type<ROW>::t>::const_iterator
118 it = vect_const_begin(c), ite = vect_const_end(c);
119 for (t = x[i]; it != ite; ++it)
120 if (
int(it.index()) > i && it.index() < k) t -= (*it) * x[it.index()];
121 if (!is_unit) x[i] = t / c[i];
else x[i] = t;
125 template <
typename TriMatrix,
typename VecX>
126 void upper_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
127 row_major, abstract_dense,
bool is_unit) {
128 typename linalg_traits<TriMatrix>::value_type t;
130 for (
int i =
int(k) - 1; i >= 0; --i) {
131 typedef typename linalg_traits<TriMatrix>::const_sub_row_type ROW;
132 ROW c = mat_const_row(T, i);
133 typename linalg_traits<typename org_type<ROW>::t>::const_iterator
134 it = vect_const_begin(c) + (i + 1), ite = vect_const_begin(c) + k;
135 typename linalg_traits<VecX>::iterator itx = vect_begin(x) + (i+1);
137 for (t = x[i]; it != ite; ++it, ++itx) t -= (*it) * (*itx);
138 if (!is_unit) x[i] = t / c[i];
else x[i] = t;
142 template <
typename TriMatrix,
typename VecX>
143 void lower_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
144 row_major, abstract_sparse,
bool is_unit) {
145 typename linalg_traits<TriMatrix>::value_type t;
147 for (
int i = 0; i < int(k); ++i) {
148 typedef typename linalg_traits<TriMatrix>::const_sub_row_type ROW;
149 ROW c = mat_const_row(T, i);
150 typename linalg_traits<typename org_type<ROW>::t>::const_iterator
151 it = vect_const_begin(c), ite = vect_const_end(c);
153 for (t = x[i]; it != ite; ++it)
154 if (
int(it.index()) < i) t -= (*it) * x[it.index()];
155 if (!is_unit) x[i] = t / c[i];
else x[i] = t;
159 template <
typename TriMatrix,
typename VecX>
160 void lower_tri_solve__(
const TriMatrix& T, VecX& x,
size_t k,
161 row_major, abstract_dense,
bool is_unit) {
162 typename linalg_traits<TriMatrix>::value_type t;
164 for (
int i = 0; i < int(k); ++i) {
165 typedef typename linalg_traits<TriMatrix>::const_sub_row_type ROW;
166 ROW c = mat_const_row(T, i);
167 typename linalg_traits<typename org_type<ROW>::t>::const_iterator
168 it = vect_const_begin(c), ite = it + i;
169 typename linalg_traits<VecX>::iterator itx = vect_begin(x);
171 for (t = x[i]; it != ite; ++it, ++itx) t -= (*it) * (*itx);
172 if (!is_unit) x[i] = t / c[i];
else x[i] = t;
179 template <
typename TriMatrix,
typename VecX>
inline
180 void upper_tri_solve(
const TriMatrix& T, VecX &x_,
bool is_unit =
false)
181 { upper_tri_solve(T, x_, mat_nrows(T), is_unit); }
183 template <
typename TriMatrix,
typename VecX>
inline
184 void lower_tri_solve(
const TriMatrix& T, VecX &x_,
bool is_unit =
false)
185 { lower_tri_solve(T, x_, mat_nrows(T), is_unit); }
187 template <
typename TriMatrix,
typename VecX>
inline
188 void upper_tri_solve(
const TriMatrix& T, VecX &x_,
size_t k,
190 VecX& x =
const_cast<VecX&
>(x_);
191 GMM_ASSERT2(mat_nrows(T) >= k && vect_size(x) >= k
192 && mat_ncols(T) >= k && !is_sparse(x_),
"dimensions mismatch");
193 upper_tri_solve__(T, x, k,
194 typename principal_orientation_type<
typename
195 linalg_traits<TriMatrix>::sub_orientation>::potype(),
196 typename linalg_traits<TriMatrix>::storage_type(),
200 template <
typename TriMatrix,
typename VecX>
inline
201 void lower_tri_solve(
const TriMatrix& T, VecX &x_,
size_t k,
203 VecX& x =
const_cast<VecX&
>(x_);
204 GMM_ASSERT2(mat_nrows(T) >= k && vect_size(x) >= k
205 && mat_ncols(T) >= k && !is_sparse(x_),
"dimensions mismatch");
206 lower_tri_solve__(T, x, k,
207 typename principal_orientation_type<
typename
208 linalg_traits<TriMatrix>::sub_orientation>::potype(),
209 typename linalg_traits<TriMatrix>::storage_type(),
gmm interface for STL vectors.