lu.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00024 #ifndef lu_h
00025 #define lu_h
00026
00027 #include <cml/et/size_checking.h>
00028 #include <cml/matrix/matrix_expr.h>
00029 #include <cml/matvec/matvec_promotions.h>
00030
00031
00032
00033
00034 struct lu_expects_a_matrix_arg_error;
00035
00036
00037
00038
00039 struct lu_inplace_expects_an_assignable_matrix_arg_error;
00040
00041 namespace cml {
00042 namespace detail {
00043
00044
00045 template<class MatT> inline
00046 void lu_inplace(MatT& A)
00047 {
00048
00049 typedef et::ExprTraits<MatT> arg_traits;
00050 typedef typename arg_traits::result_tag arg_result;
00051 typedef typename arg_traits::assignable_tag arg_assignment;
00052 typedef typename arg_traits::size_tag size_tag;
00053 typedef typename arg_traits::value_type value_type;
00054
00055
00056 CML_STATIC_REQUIRE_M(
00057 (same_type<arg_result, et::matrix_result_tag>::is_true
00058 && same_type<arg_assignment, et::assignable_tag>::is_true),
00059 lu_inplace_expects_an_assignable_matrix_arg_error);
00060
00061
00062
00063
00064
00065 ssize_t N = (ssize_t) cml::et::CheckedSquare(A, size_tag());
00066
00067
00068 for(ssize_t k = 0; k < N-1; ++k) {
00069
00070 for(ssize_t i = k+1; i < N; ++i) {
00071 value_type n = (A(i,k) /= A(k,k));
00072 for(ssize_t j = k+1; j < N; ++ j) {
00073 A(i,j) -= n*A(k,j);
00074 }
00075 }
00076 }
00077 }
00078
00079
00080 template<class MatT>
00081 inline typename MatT::temporary_type
00082 lu_copy(const MatT& M)
00083 {
00084
00085 typedef et::ExprTraits<MatT> arg_traits;
00086 typedef typename arg_traits::result_tag arg_result;
00087
00088
00089 CML_STATIC_REQUIRE_M(
00090 (same_type<arg_result, et::matrix_result_tag>::is_true),
00091 lu_expects_a_matrix_arg_error);
00092
00093
00094
00095
00096
00097 typename MatT::temporary_type A;
00098 cml::et::detail::Resize(A,M.rows(),M.cols());
00099 A = M;
00100 lu_inplace(A);
00101 return A;
00102 }
00103
00104 }
00105
00107 template<typename E, class AT, typename BO, class L>
00108 inline typename matrix<E,AT,BO,L>::temporary_type
00109 lu(const matrix<E,AT,BO,L>& m)
00110 {
00111 return detail::lu_copy(m);
00112 }
00113
00115 template<typename XprT>
00116 inline typename et::MatrixXpr<XprT>::temporary_type
00117 lu(const et::MatrixXpr<XprT>& e)
00118 {
00119 return detail::lu_copy(e);
00120 }
00121
00127 template<typename MatT, typename VecT> inline
00128 typename et::MatVecPromote<MatT,VecT>::temporary_type
00129 lu_solve(const MatT& LU, const VecT& b)
00130 {
00131
00132 typedef et::ExprTraits<MatT> lu_traits;
00133 typedef typename et::MatVecPromote<MatT,VecT>::temporary_type vector_type;
00134 typedef typename vector_type::value_type value_type;
00135
00136
00137 ssize_t N = (ssize_t) cml::et::CheckedSquare(
00138 LU, typename lu_traits::size_tag());
00139
00140
00141 et::CheckedSize(LU, b, typename vector_type::size_tag());
00142
00143
00144
00145
00146
00147 vector_type y; cml::et::detail::Resize(y,N);
00148 for(ssize_t i = 0; i < N; ++i) {
00149 y[i] = b[i];
00150 for(ssize_t j = 0; j < i; ++j) {
00151 y[i] -= LU(i,j)*y[j];
00152 }
00153 }
00154
00155
00156
00157
00158 vector_type x; cml::et::detail::Resize(x,N);
00159 for(ssize_t i = N-1; i >= 0; --i) {
00160 x[i] = y[i];
00161 for(ssize_t j = i+1; j < N; ++j) {
00162 x[i] -= LU(i,j)*x[j];
00163 }
00164 x[i] /= LU(i,i);
00165 }
00166
00167
00168 return x;
00169 }
00170
00171 }
00172
00173 #endif
00174
00175
00176