add allow_approx option to inv() and inv_sympd()
This commit is contained in:
@@ -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" );
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user