add allow_approx option to inv() and inv_sympd()

This commit is contained in:
conrad
2022-03-23 14:03:51 +10:00
parent 09051d02d8
commit bc988fac4e
4 changed files with 39 additions and 3 deletions
+5 -2
View File
@@ -107,16 +107,19 @@ namespace inv_opts
static constexpr uword flag_none = uword(0 );
static constexpr uword flag_tiny = uword(1u << 0);
static constexpr uword flag_likely_sympd = uword(1u << 1);
static constexpr uword flag_no_sympd = uword(1u << 2);
static constexpr uword flag_allow_approx = uword(1u << 1);
static constexpr uword flag_likely_sympd = uword(1u << 2);
static constexpr uword flag_no_sympd = uword(1u << 3);
struct opts_none : public opts { inline opts_none() : opts(flag_none ) {} };
struct opts_tiny : public opts { inline opts_tiny() : opts(flag_tiny ) {} };
struct opts_allow_approx : public opts { inline opts_allow_approx() : opts(flag_allow_approx) {} };
struct opts_likely_sympd : public opts { inline opts_likely_sympd() : opts(flag_likely_sympd) {} };
struct opts_no_sympd : public opts { inline opts_no_sympd() : opts(flag_no_sympd ) {} };
static const opts_none none;
static const opts_tiny tiny;
static const opts_allow_approx allow_approx;
static const opts_likely_sympd likely_sympd;
static const opts_no_sympd no_sympd;
}
@@ -83,22 +83,39 @@ op_inv_gen_full::apply_direct(Mat<typename T1::elem_type>& out, const Base<typen
arma_extra_debug_sigprint();
typedef typename T1::elem_type eT;
typedef typename T1::pod_type T;
if(has_user_flags == true ) { arma_extra_debug_print("op_inv_gen_full: has_user_flags = true"); }
if(has_user_flags == false) { arma_extra_debug_print("op_inv_gen_full: has_user_flags = false"); }
const bool tiny = has_user_flags && bool(flags & inv_opts::flag_tiny );
const bool allow_approx = has_user_flags && bool(flags & inv_opts::flag_allow_approx);
const bool likely_sympd = has_user_flags && bool(flags & inv_opts::flag_likely_sympd);
const bool no_sympd = has_user_flags && bool(flags & inv_opts::flag_no_sympd );
arma_extra_debug_print("op_inv_gen_full: enabled flags:");
if(tiny ) { arma_extra_debug_print("tiny"); }
if(allow_approx) { arma_extra_debug_print("allow_approx"); }
if(likely_sympd) { arma_extra_debug_print("likely_sympd"); }
if(no_sympd ) { arma_extra_debug_print("no_sympd"); }
arma_debug_check( (no_sympd && likely_sympd), "inv(): options 'no_sympd' and 'likely_sympd' are mutually exclusive" );
if(allow_approx)
{
T rcond = T(0);
const bool status = op_inv_gen_rcond::apply_direct(out, rcond, expr);
if((status == false) || (rcond < auxlib::epsilon_lapack(out)))
{
Mat<eT> A = expr.get_ref();
return op_pinv::apply_gen(out, A, T(0), uword(0));
}
}
out = expr.get_ref();
arma_debug_check( (out.is_square() == false), caller_sig, ": given matrix must be square sized" );
@@ -89,18 +89,34 @@ op_inv_spd_full::apply_direct(Mat<typename T1::elem_type>& out, const Base<typen
if(has_user_flags == false) { arma_extra_debug_print("op_inv_spd_full: has_user_flags = false"); }
const bool tiny = has_user_flags && bool(flags & inv_opts::flag_tiny );
const bool allow_approx = has_user_flags && bool(flags & inv_opts::flag_allow_approx);
const bool likely_sympd = has_user_flags && bool(flags & inv_opts::flag_likely_sympd);
const bool no_sympd = has_user_flags && bool(flags & inv_opts::flag_no_sympd );
arma_extra_debug_print("op_inv_spd_full: enabled flags:");
if(tiny ) { arma_extra_debug_print("tiny"); }
if(allow_approx) { arma_extra_debug_print("allow_approx"); }
if(likely_sympd) { arma_extra_debug_print("likely_sympd"); }
if(no_sympd ) { arma_extra_debug_print("no_sympd"); }
if(likely_sympd) { arma_debug_warn_level(1, "inv_sympd(): option 'likely_sympd' ignored" ); }
if(no_sympd) { arma_debug_warn_level(1, "inv_sympd(): option 'no_sympd' ignored" ); }
if(allow_approx)
{
T rcond = T(0);
const bool status = op_inv_spd_rcond::apply_direct(out, rcond, expr);
if((status == false) || (rcond < auxlib::epsilon_lapack(out)))
{
const Mat<eT> A = expr.get_ref();
return op_pinv::apply_sym(out, A, T(0), uword(0));
}
}
out = expr.get_ref();
arma_debug_check( (out.is_square() == false), "inv_sympd(): given matrix must be square sized" );
+1 -1
View File
@@ -224,7 +224,7 @@ op_pinv::apply_sym(Mat<eT>& out, const Mat<eT>& A, typename get_pod_type<eT>::re
template<typename eT>
inline
bool