diff --git a/include/armadillo_bits/fn_pinv.hpp b/include/armadillo_bits/fn_pinv.hpp index 6757bb37..96f20eca 100644 --- a/include/armadillo_bits/fn_pinv.hpp +++ b/include/armadillo_bits/fn_pinv.hpp @@ -27,18 +27,26 @@ pinv ( const Base& X, const typename T1::pod_type tol = 0.0, - const char* method = "dc" + const char* method = nullptr ) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; - const char sig = (method != nullptr) ? method[0] : char(0); + uword method_id = 0; // default setting - arma_debug_check( ((sig != 's') && (sig != 'd')), "pinv(): unknown method specified" ); + if(method != nullptr) + { + const char sig = method[0]; + + arma_debug_check( ((sig != 's') && (sig != 'd')), "pinv(): unknown method specified" ); + + if(sig == 's') { method_id = 1; } + if(sig == 'd') { method_id = 2; } + } - return (sig == 'd') ? Op(X.get_ref(), eT(tol), 1, 0) : Op(X.get_ref(), eT(tol), 0, 0); + return Op(X.get_ref(), eT(tol), method_id, uword(0)); } @@ -51,18 +59,24 @@ pinv Mat& out, const Base& X, const typename T1::pod_type tol = 0.0, - const char* method = "dc" + const char* method = nullptr ) { arma_extra_debug_sigprint(); - const char sig = (method != nullptr) ? method[0] : char(0); + uword method_id = 0; // default setting - arma_debug_check( ((sig != 's') && (sig != 'd')), "pinv(): unknown method specified" ); + if(method != nullptr) + { + const char sig = method[0]; + + arma_debug_check( ((sig != 's') && (sig != 'd')), "pinv(): unknown method specified" ); + + if(sig == 's') { method_id = 1; } + if(sig == 'd') { method_id = 2; } + } - const bool use_divide_and_conquer = (sig == 'd'); - - const bool status = op_pinv::apply_direct(out, X.get_ref(), tol, use_divide_and_conquer); + const bool status = op_pinv::apply_direct(out, X.get_ref(), tol, method_id); if(status == false) { diff --git a/include/armadillo_bits/op_pinv_bones.hpp b/include/armadillo_bits/op_pinv_bones.hpp index 9f7b59ac..4b7bbcdc 100644 --- a/include/armadillo_bits/op_pinv_bones.hpp +++ b/include/armadillo_bits/op_pinv_bones.hpp @@ -26,8 +26,8 @@ class op_pinv public: template inline static void apply(Mat& out, const Op& in); - - template inline static bool apply_direct(Mat& out, const Base& expr, typename T1::pod_type tol, const bool use_divide_and_conquer); + + template inline static bool apply_direct(Mat& out, const Base& expr, typename T1::pod_type tol, const uword method_id); }; diff --git a/include/armadillo_bits/op_pinv_meat.hpp b/include/armadillo_bits/op_pinv_meat.hpp index d7664896..c0503546 100644 --- a/include/armadillo_bits/op_pinv_meat.hpp +++ b/include/armadillo_bits/op_pinv_meat.hpp @@ -29,11 +29,10 @@ op_pinv::apply(Mat& out, const Op& in) typedef typename T1::pod_type T; - const T tol = access::tmp_real(in.aux); + const T tol = access::tmp_real(in.aux); + const uword method_id = in.aux_uword_a; - const bool use_divide_and_conquer = (in.aux_uword_a == 1); - - const bool status = op_pinv::apply_direct(out, in.m, tol, use_divide_and_conquer); + const bool status = op_pinv::apply_direct(out, in.m, tol, method_id); if(status == false) { @@ -46,7 +45,7 @@ op_pinv::apply(Mat& out, const Op& in) template inline bool -op_pinv::apply_direct(Mat& out, const Base& expr, typename T1::pod_type tol, const bool use_divide_and_conquer) +op_pinv::apply_direct(Mat& out, const Base& expr, typename T1::pod_type tol, const uword method_id) { arma_extra_debug_sigprint(); @@ -55,6 +54,10 @@ op_pinv::apply_direct(Mat& out, const Base= 0"); + // method_id = 0 -> default setting + // method_id = 1 -> use standard algorithm + // method_id = 2 -> use divide and conquer algorithm + Mat A(expr.get_ref()); const uword n_rows = A.n_rows; @@ -63,7 +66,7 @@ op_pinv::apply_direct(Mat& out, const Base& out, const Base s; Mat V; - bool status = false; - if(n_cols > n_rows) { A = trans(A); } - status = (use_divide_and_conquer) ? auxlib::svd_dc_econ(U, s, V, A) : auxlib::svd_econ(U, s, V, A, 'b'); + const bool status = (method_id == uword(2)) ? auxlib::svd_dc_econ(U, s, V, A) : auxlib::svd_econ(U, s, V, A, 'b'); if(status == false) { out.soft_reset(); return false; }