inline var<AutodiffOrder, StrictSmoothness, ValidateIO> inv_logit(const var<AutodiffOrder, StrictSmoothness, ValidateIO>& input) { if (ValidateIO) validate_input(input.first_val(), "inv_logit"); const short partials_order = 3; const unsigned int n_inputs = 1; create_node<unary_var_node<AutodiffOrder, partials_order>>(n_inputs); double s = inv_logit(input.first_val()); try { push_dual_numbers<AutodiffOrder, ValidateIO>(s); } catch (nomad_error) { throw nomad_output_value_error("inv_logit"); } push_inputs(input.dual_numbers()); double ds = s * (1 - s); try { if (AutodiffOrder >= 1) push_partials<ValidateIO>(ds); if (AutodiffOrder >= 2) push_partials<ValidateIO>(ds * (1 - 2 * s) ); if (AutodiffOrder >= 3) push_partials<ValidateIO>(ds * (1 - 6 * s * (1 - s)) ); } catch (nomad_error) { throw nomad_output_partial_error("inv_logit"); } return var<AutodiffOrder, StrictSmoothness, ValidateIO>(next_node_idx_ - 1); }
TEST(AgradRev,inv_logit) { AVAR a = 2.0; AVAR f = inv_logit(a); EXPECT_FLOAT_EQ(1.0 / (1.0 + exp(-2.0)),f.val()); AVEC x = createAVEC(a); VEC grad_f; f.grad(x,grad_f); EXPECT_FLOAT_EQ(exp(-2.0)/pow(1 + exp(-2.0),2.0), grad_f[0]); }
inline typename boost::math::tools::promote_args<T>::type Phi_approx(T x) { return inv_logit(0.07056 * std::pow(x,3.0) + 1.5976 * x); }