示例#1
0
TEST(AgradFwdLog1pExp,Fvar) {
    using stan::agrad::fvar;
    using stan::math::log1p_exp;
    using std::exp;

    fvar<double> x(0.5,1.0);
    fvar<double> y(1.0,2.0);
    fvar<double> z(2.0,3.0);

    fvar<double> a = log1p_exp(x);
    EXPECT_FLOAT_EQ(log1p_exp(0.5), a.val_);
    EXPECT_FLOAT_EQ(exp(0.5) / (1 + exp(0.5)), a.d_);

    fvar<double> b = log1p_exp(y);
    EXPECT_FLOAT_EQ(log1p_exp(1.0), b.val_);
    EXPECT_FLOAT_EQ(2.0 * exp(1.0) / (1 + exp(1.0)), b.d_);

    fvar<double> a2 = log(1+exp(x));
    EXPECT_FLOAT_EQ(a.d_, a2.d_);

    fvar<double> b2 = log(1+exp(y));
    EXPECT_FLOAT_EQ(b.d_, b2.d_);
}
示例#2
0
TEST(AgradFwdLogDiffExp,Double_FvarFvarVar_1stDeriv) {
    using stan::agrad::fvar;
    using stan::agrad::var;
    using stan::math::log_diff_exp;
    using std::exp;

    double x(9.0);
    fvar<fvar<var> > y;
    y.val_.val_ = 6.0;
    y.d_.val_ = 1.0;

    fvar<fvar<var> > a = log_diff_exp(x,y);

    EXPECT_FLOAT_EQ(log_diff_exp(9.0,6.0), a.val_.val_.val());
    EXPECT_FLOAT_EQ(0, a.val_.d_.val());
    EXPECT_FLOAT_EQ(-exp(6.0) / (exp(9.0) - exp(6.0)), a.d_.val_.val());
    EXPECT_FLOAT_EQ(0, a.d_.d_.val());

    AVEC p = createAVEC(y.val_.val_);
    VEC g;
    a.val_.val_.grad(p,g);
    EXPECT_FLOAT_EQ(-exp(6.0) / (exp(9.0) - exp(6.0)), g[0]);
}
示例#3
0
TEST(AgradFvar, log1m_inv_logit){
  using stan::agrad::fvar;
  using stan::math::log1m_inv_logit;
  using std::exp;

  fvar<double> x(0.5);
  fvar<double> y(-1.0);
  fvar<double> z(0.0);
  x.d_ = 1.0;
  y.d_ = 2.0;
  z.d_ = 3.0;

  fvar<double> a = log1m_inv_logit(x);
  EXPECT_FLOAT_EQ(log1m_inv_logit(0.5), a.val_);
  EXPECT_FLOAT_EQ(-1.0 * exp(0.5) / (1 + exp(0.5)), a.d_);

  fvar<double> b = log1m_inv_logit(y);
  EXPECT_FLOAT_EQ(log1m_inv_logit(-1.0), b.val_);
  EXPECT_FLOAT_EQ(-2.0 * exp(-1.0) / (1 + exp(-1.0)), b.d_);

  fvar<double> c = log1m_inv_logit(z);
  EXPECT_FLOAT_EQ(log1m_inv_logit(0.0), c.val_);
  EXPECT_FLOAT_EQ(-3.0 * exp(0.0) / (1 + exp(0.0)), c.d_);
}
  void test_exp(const int fuzzy_bits)
  {
    // Use at least 8 resolution bits.
    // Use at least 7 range bits.

    BOOST_STATIC_ASSERT(-FixedPointType::resolution >= 8);
    BOOST_STATIC_ASSERT( FixedPointType::range      >= 7);

    const FixedPointType a1(+1L    );                                       const FloatPointType b1(+1L    );
    const FixedPointType a2(+2L    );                                       const FloatPointType b2(+2L    );
    const FixedPointType a3(+4.375L);                                       const FloatPointType b3(+4.375L);
    const FixedPointType a4(+1.125L);                                       const FloatPointType b4(+1.125L);
    const FixedPointType a5(-1.125L);                                       const FloatPointType b5(-1.125L);
    const FixedPointType a6(+0.875L);                                       const FloatPointType b6(+0.875L);
    const FixedPointType a7(FixedPointType( 1) /  3);                       const FloatPointType b7(FloatPointType( 1) /  3);
    const FixedPointType a8(FixedPointType(11) / 10);                       const FloatPointType b8(FloatPointType(11) / 10);
    const FixedPointType a9(boost::math::constants::phi<FixedPointType>()); const FloatPointType b9(boost::math::constants::phi<FloatPointType>());

    using std::exp;

    BOOST_CHECK_CLOSE_FRACTION(exp(a1), FixedPointType(exp(b1)), tolerance_maker<FixedPointType>(fuzzy_bits));
    BOOST_CHECK_CLOSE_FRACTION(exp(a2), FixedPointType(exp(b2)), tolerance_maker<FixedPointType>(fuzzy_bits));
    BOOST_CHECK_CLOSE_FRACTION(exp(a3), FixedPointType(exp(b3)), tolerance_maker<FixedPointType>(fuzzy_bits));
    BOOST_CHECK_CLOSE_FRACTION(exp(a4), FixedPointType(exp(b4)), tolerance_maker<FixedPointType>(fuzzy_bits));
    BOOST_CHECK_CLOSE_FRACTION(exp(a5), FixedPointType(exp(b5)), tolerance_maker<FixedPointType>(fuzzy_bits));
    BOOST_CHECK_CLOSE_FRACTION(exp(a6), FixedPointType(exp(b6)), tolerance_maker<FixedPointType>(fuzzy_bits));
    BOOST_CHECK_CLOSE_FRACTION(exp(a7), FixedPointType(exp(b7)), tolerance_maker<FixedPointType>(fuzzy_bits));
    BOOST_CHECK_CLOSE_FRACTION(exp(a8), FixedPointType(exp(b8)), tolerance_maker<FixedPointType>(fuzzy_bits));
    BOOST_CHECK_CLOSE_FRACTION(exp(a9), FixedPointType(exp(b9)), tolerance_maker<FixedPointType>(fuzzy_bits));
  }
示例#5
0
文件: expm1.hpp 项目: stan-dev/math
inline fvar<T> expm1(const fvar<T>& x) {
    using std::exp;
    return fvar<T>(expm1(x.val_), x.d_ * exp(x.val_));
}
示例#6
0
int test_cv_vib()
{
  using std::exp;

  const Scalar Mm_N  = 14.008e-3;   //in SI kg/mol
  const Scalar Mm_O  = 16e-3;       //in SI kg/mol
  const Scalar Mm_N2 = 2.L * Mm_N;  //in SI kg/mol
  const Scalar Mm_O2 = 2.L * Mm_O;  //in SI kg/mol
  const Scalar Mm_NO = Mm_O + Mm_N; //in SI kg/mol

  std::vector<std::string> species_str_list;
  const unsigned int n_species = 5;
  species_str_list.reserve(n_species);
  species_str_list.push_back( "N2" );
  species_str_list.push_back( "O2" );
  species_str_list.push_back( "N" );
  species_str_list.push_back( "O" );
  species_str_list.push_back( "NO" );

  Antioch::ChemicalMixture<Scalar> chem_mixture( species_str_list );

  // Can we instantiate it?
  Antioch::StatMechThermodynamics<Scalar> sm_thermo( chem_mixture );

  // Mass fractions
  std::vector<Scalar> mass_fractions( 5, 0.2 );
  mass_fractions[0] = 0.5;
  mass_fractions[1] = 0.2;
  mass_fractions[2] = 0.1;
  mass_fractions[3] = 0.1;
  mass_fractions[4] = 0.1;

  const Scalar R_N2 = Antioch::Constants::R_universal<Scalar>() / Mm_N2;
  const Scalar R_O2 = Antioch::Constants::R_universal<Scalar>() / Mm_O2;
  const Scalar R_NO = Antioch::Constants::R_universal<Scalar>() / Mm_NO;

  const Scalar th0_N2 = 3.39500e+03; // degeneracy = 1
  const Scalar th0_O2 = 2.23900e+03; // degeneracy = 1
  const Scalar th0_NO = 2.81700e+03; // degeneracy = 1

  // Tv
  const Scalar Tv = 1000.0;

  const Scalar tol = std::numeric_limits<Scalar>::epsilon() * 2;
  const Scalar ztol = std::numeric_limits<Scalar>::epsilon();

  int return_flag = 0;

  Scalar cv_vib_mix = 0.0;

  // N2
  {
    Scalar cv_vib_N2 = sm_thermo.cv_vib (0, Tv);

    const Scalar expv   = exp(th0_N2/Tv);
    const Scalar expvmi = expv - Scalar(1.0);
    Scalar cv_vib_N2_true = R_N2*th0_N2*th0_N2*expv/expvmi/expvmi/Tv/Tv;

    if( !test_relative(cv_vib_N2, cv_vib_N2_true, tol) )
    {
      std::cerr << std::scientific << std::setprecision(20);
      std::cerr << "Error: Mismatch in cv_vib for N2."
                << "\n Expected = " << cv_vib_N2_true
                << "\n Computed = " << cv_vib_N2
                << "\n Diff     = " << cv_vib_N2_true - cv_vib_N2
                << std::endl;
      return_flag += 1;
    }

    cv_vib_mix += mass_fractions[0]*cv_vib_N2_true;
  }

  // O2
  {
    Scalar cv_vib_O2 = sm_thermo.cv_vib (1, Tv);

    const Scalar expv   = exp(th0_O2/Tv);
    const Scalar expvmi = expv - Scalar(1.0);
    Scalar cv_vib_O2_true = R_O2*th0_O2*th0_O2*expv/expvmi/expvmi/Tv/Tv;

    if( !test_relative(cv_vib_O2, cv_vib_O2_true, tol) )
    {
      std::cerr << std::scientific << std::setprecision(20);
      std::cerr << "Error: Mismatch in cv_vib for O2."
                << "\n Expected = " << cv_vib_O2_true
                << "\n Computed = " << cv_vib_O2
                << "\n Diff     = " << cv_vib_O2_true - cv_vib_O2
                << std::endl;
      return_flag += 1;
    }

    cv_vib_mix += mass_fractions[1]*cv_vib_O2_true;
  }

  // O
  {
    Scalar cv_vib_O = sm_thermo.cv_vib (2, Tv);

    if( !test_zero(cv_vib_O, ztol) )
    {
      std::cerr << std::scientific << std::setprecision(20);
      std::cerr << "Error: Mismatch in cv_vib for O."
                << "\n Expected = " << Scalar(0.0)
                << "\n Computed = " << cv_vib_O
                << "\n Diff     = " << cv_vib_O
                << std::endl;
      return_flag += 1;
    }

    // cv_vib_mix += 0.0;
  }

  // N
  {
    Scalar cv_vib_N = sm_thermo.cv_vib (3, Tv);

    if( !test_zero(cv_vib_N, ztol) )
    {
      std::cerr << std::scientific << std::setprecision(20);
      std::cerr << "Error: Mismatch in cv_vib for N."
                << "\n Expected = " << Scalar(0.0)
                << "\n Computed = " << cv_vib_N
                << "\n Diff     = " << cv_vib_N
                << std::endl;
      return_flag += 1;
    }

    // cv_vib_mix += 0.0;
  }

  // NO
  {
    Scalar cv_vib_NO = sm_thermo.cv_vib (4, Tv);

    const Scalar expv   = exp(th0_NO/Tv);
    const Scalar expvmi = expv - Scalar(1.0);
    Scalar cv_vib_NO_true = R_NO*th0_NO*th0_NO*expv/expvmi/expvmi/Tv/Tv;

    if( !test_relative(cv_vib_NO, cv_vib_NO_true, tol*4) )
    {
      std::cerr << std::scientific << std::setprecision(20);
      std::cerr << "Error: Mismatch in cv_vib for NO."
                << "\n Expected = " << cv_vib_NO_true
                << "\n Computed = " << cv_vib_NO
                << "\n Diff     = " << cv_vib_NO_true - cv_vib_NO
                << std::endl;
      return_flag += 1;
    }

    cv_vib_mix += mass_fractions[4]*cv_vib_NO_true;
  }

  // mixture
  {
    Scalar cv = sm_thermo.cv_vib(Tv, mass_fractions);
    
    if( !test_relative(cv, cv_vib_mix, tol) )
    {
      std::cerr << std::scientific << std::setprecision(20);
      std::cerr << "Error: Mismatch in mixture cv_vib."
                << "\n Expected = " << cv_vib_mix
                << "\n Computed = " << cv
                << "\n Diff     = " << cv - cv_vib_mix
                << std::endl;
      return_flag += 1;
    }
  }

  return return_flag;
}
示例#7
0
    typename return_type<T_y, T_loc, T_scale, T_shape>::type
    skew_normal_log(const T_y& y, const T_loc& mu, const T_scale& sigma,
                    const T_shape& alpha) {
      static const char* function("skew_normal_log");
      typedef typename stan::partials_return_type<T_y, T_loc,
                                                  T_scale, T_shape>::type
        T_partials_return;

      using std::log;
      using stan::is_constant_struct;
      using std::exp;

      if (!(stan::length(y)
            && stan::length(mu)
            && stan::length(sigma)
            && stan::length(alpha)))
        return 0.0;

      T_partials_return logp(0.0);

      check_not_nan(function, "Random variable", y);
      check_finite(function, "Location parameter", mu);
      check_finite(function, "Shape parameter", alpha);
      check_positive(function, "Scale parameter", sigma);
      check_consistent_sizes(function,
                             "Random variable", y,
                             "Location parameter", mu,
                             "Scale parameter", sigma,
                             "Shape paramter", alpha);

      if (!include_summand<propto, T_y, T_loc, T_scale, T_shape>::value)
        return 0.0;

      OperandsAndPartials<T_y, T_loc, T_scale, T_shape>
        operands_and_partials(y, mu, sigma, alpha);

      using std::log;

      VectorView<const T_y> y_vec(y);
      VectorView<const T_loc> mu_vec(mu);
      VectorView<const T_scale> sigma_vec(sigma);
      VectorView<const T_shape> alpha_vec(alpha);
      size_t N = max_size(y, mu, sigma, alpha);

      VectorBuilder<true, T_partials_return, T_scale> inv_sigma(length(sigma));
      VectorBuilder<include_summand<propto, T_scale>::value,
                    T_partials_return, T_scale> log_sigma(length(sigma));
      for (size_t i = 0; i < length(sigma); i++) {
        inv_sigma[i] = 1.0 / value_of(sigma_vec[i]);
        if (include_summand<propto, T_scale>::value)
          log_sigma[i] = log(value_of(sigma_vec[i]));
      }

      for (size_t n = 0; n < N; n++) {
        const T_partials_return y_dbl = value_of(y_vec[n]);
        const T_partials_return mu_dbl = value_of(mu_vec[n]);
        const T_partials_return sigma_dbl = value_of(sigma_vec[n]);
        const T_partials_return alpha_dbl = value_of(alpha_vec[n]);

        const T_partials_return y_minus_mu_over_sigma
          = (y_dbl - mu_dbl) * inv_sigma[n];
        const double pi_dbl = pi();

        if (include_summand<propto>::value)
          logp -=  0.5 * log(2.0 * pi_dbl);
        if (include_summand<propto, T_scale>::value)
          logp -= log(sigma_dbl);
        if (include_summand<propto, T_y, T_loc, T_scale>::value)
          logp -= y_minus_mu_over_sigma * y_minus_mu_over_sigma / 2.0;
        if (include_summand<propto, T_y, T_loc, T_scale, T_shape>::value)
          logp += log(erfc(-alpha_dbl * y_minus_mu_over_sigma
                           / std::sqrt(2.0)));

        T_partials_return deriv_logerf
          = 2.0 / std::sqrt(pi_dbl)
          * exp(-alpha_dbl * y_minus_mu_over_sigma / std::sqrt(2.0)
                * alpha_dbl * y_minus_mu_over_sigma / std::sqrt(2.0))
          / (1 + erf(alpha_dbl * y_minus_mu_over_sigma
                     / std::sqrt(2.0)));
        if (!is_constant_struct<T_y>::value)
          operands_and_partials.d_x1[n]
            += -y_minus_mu_over_sigma / sigma_dbl
            + deriv_logerf * alpha_dbl / (sigma_dbl * std::sqrt(2.0));
        if (!is_constant_struct<T_loc>::value)
          operands_and_partials.d_x2[n]
            += y_minus_mu_over_sigma / sigma_dbl
            + deriv_logerf * -alpha_dbl / (sigma_dbl * std::sqrt(2.0));
        if (!is_constant_struct<T_scale>::value)
          operands_and_partials.d_x3[n]
            += -1.0 / sigma_dbl
            + y_minus_mu_over_sigma * y_minus_mu_over_sigma / sigma_dbl
            - deriv_logerf * y_minus_mu_over_sigma * alpha_dbl
            / (sigma_dbl * std::sqrt(2.0));
        if (!is_constant_struct<T_shape>::value)
          operands_and_partials.d_x4[n]
            += deriv_logerf * y_minus_mu_over_sigma / std::sqrt(2.0);
      }
      return operands_and_partials.value(logp);
    }
示例#8
0
    typename return_type<T_y, T_scale_succ, T_scale_fail>::type
    beta_cdf_log(const T_y& y, const T_scale_succ& alpha,
                 const T_scale_fail& beta) {
      typedef typename stan::partials_return_type<T_y, T_scale_succ,
                                                  T_scale_fail>::type
        T_partials_return;

      // Size checks
      if ( !( stan::length(y) && stan::length(alpha)
              && stan::length(beta) ) )
        return 0.0;

      // Error checks
      static const char* function("stan::math::beta_cdf");

      using stan::math::check_positive_finite;
      using stan::math::check_not_nan;
      using stan::math::check_nonnegative;
      using stan::math::check_less_or_equal;
      using boost::math::tools::promote_args;
      using stan::math::check_consistent_sizes;
      using stan::math::value_of;

      T_partials_return cdf_log(0.0);

      check_positive_finite(function, "First shape parameter", alpha);
      check_positive_finite(function, "Second shape parameter", beta);
      check_not_nan(function, "Random variable", y);
      check_nonnegative(function, "Random variable", y);
      check_less_or_equal(function, "Random variable", y, 1);
      check_consistent_sizes(function,
                             "Random variable", y,
                             "First shape parameter", alpha,
                             "Second shape parameter", beta);

      // Wrap arguments in vectors
      VectorView<const T_y> y_vec(y);
      VectorView<const T_scale_succ> alpha_vec(alpha);
      VectorView<const T_scale_fail> beta_vec(beta);
      size_t N = max_size(y, alpha, beta);

      OperandsAndPartials<T_y, T_scale_succ, T_scale_fail>
        operands_and_partials(y, alpha, beta);

      // Compute CDF and its gradients
      using stan::math::inc_beta;
      using stan::math::digamma;
      using stan::math::lbeta;
      using std::pow;
      using std::exp;
      using std::log;
      using std::exp;

      // Cache a few expensive function calls if alpha or beta is a parameter
      VectorBuilder<contains_nonconstant_struct<T_scale_succ,
                                                T_scale_fail>::value,
                    T_partials_return, T_scale_succ, T_scale_fail>
        digamma_alpha_vec(max_size(alpha, beta));

      VectorBuilder<contains_nonconstant_struct<T_scale_succ,
                                                T_scale_fail>::value,
                    T_partials_return, T_scale_succ, T_scale_fail>
        digamma_beta_vec(max_size(alpha, beta));

      VectorBuilder<contains_nonconstant_struct<T_scale_succ,
                                                T_scale_fail>::value,
                    T_partials_return, T_scale_succ, T_scale_fail>
        digamma_sum_vec(max_size(alpha, beta));

      if (contains_nonconstant_struct<T_scale_succ, T_scale_fail>::value) {
        for (size_t i = 0; i < N; i++) {
          const T_partials_return alpha_dbl = value_of(alpha_vec[i]);
          const T_partials_return beta_dbl = value_of(beta_vec[i]);

          digamma_alpha_vec[i] = digamma(alpha_dbl);
          digamma_beta_vec[i] = digamma(beta_dbl);
          digamma_sum_vec[i] = digamma(alpha_dbl + beta_dbl);
        }
      }

      // Compute vectorized CDFLog and gradient
      for (size_t n = 0; n < N; n++) {
        // Pull out values
        const T_partials_return y_dbl = value_of(y_vec[n]);
        const T_partials_return alpha_dbl = value_of(alpha_vec[n]);
        const T_partials_return beta_dbl = value_of(beta_vec[n]);
        const T_partials_return betafunc_dbl = exp(lbeta(alpha_dbl, beta_dbl));
        // Compute
        const T_partials_return Pn = inc_beta(alpha_dbl, beta_dbl, y_dbl);

        cdf_log += log(Pn);

        if (!is_constant_struct<T_y>::value)
          operands_and_partials.d_x1[n] += pow(1-y_dbl, beta_dbl-1)
            * pow(y_dbl, alpha_dbl-1) / betafunc_dbl / Pn;

        T_partials_return g1 = 0;
        T_partials_return g2 = 0;

        if (contains_nonconstant_struct<T_scale_succ, T_scale_fail>::value) {
          stan::math::grad_reg_inc_beta(g1, g2, alpha_dbl, beta_dbl, y_dbl,
                                        digamma_alpha_vec[n],
                                        digamma_beta_vec[n], digamma_sum_vec[n],
                                        betafunc_dbl);
        }
        if (!is_constant_struct<T_scale_succ>::value)
          operands_and_partials.d_x2[n] += g1 / Pn;
        if (!is_constant_struct<T_scale_fail>::value)
          operands_and_partials.d_x3[n]  += g2 / Pn;
      }

      return operands_and_partials.to_var(cdf_log, y, alpha, beta);
    }
示例#9
0
DualNumber<T> exp(DualNumber<T> x)
{
    using std::exp;
    return DualNumber<T>(exp(x.first), x.second * exp(x.first));
}
示例#10
0
TEST(AgradFwdLogDiffExp,FvarVar_FvarVar_2ndDeriv) {
    using stan::agrad::fvar;
    using stan::agrad::var;
    using stan::math::log_diff_exp;
    using std::exp;

    fvar<var> x(9.0,1.3);
    fvar<var> z(6.0,1.0);
    fvar<var> a = log_diff_exp(x,z);

    AVEC y = createAVEC(x.val_,z.val_);
    VEC g;
    a.d_.grad(y,g);
    EXPECT_FLOAT_EQ((1.3 * exp(9.0) * (exp(9.0) - exp(6.0)) - exp(9.0)
                     * (1.3 * exp(9.0) - exp(6.0))) / (exp(9.0) - exp(6.0))
                    / (exp(9.0) - exp(6.0)) ,g[0]);
    EXPECT_FLOAT_EQ((-exp(6.0) * (exp(9.0) - exp(6.0)) + exp(6.0)
                     * (1.3 * exp(9.0) - exp(6.0))) / (exp(9.0) - exp(6.0))
                    / (exp(9.0) - exp(6.0)) ,g[1]);
}
示例#11
0
    typename return_type<T_prob>::type
    binomial_cdf(const T_n& n, const T_N& N, const T_prob& theta) {
      static const char* function("stan::prob::binomial_cdf");
      typedef typename stan::partials_return_type<T_n,T_N,T_prob>::type
        T_partials_return;
          
      using stan::math::check_finite;
      using stan::math::check_bounded;
      using stan::math::check_nonnegative;
      using stan::math::value_of;
      using stan::math::check_consistent_sizes;
      using stan::prob::include_summand;
          
      // Ensure non-zero arguments lenghts
      if (!(stan::length(n) && stan::length(N) && stan::length(theta)))
        return 1.0;
          
      T_partials_return P(1.0);
          
      // Validate arguments
      check_nonnegative(function, "Population size parameter", N);
      check_finite(function, "Probability parameter", theta);
      check_bounded(function, "Probability parameter", theta, 0.0, 1.0);
      check_consistent_sizes(function, 
                             "Successes variable", n,
                             "Population size parameter", N, 
                             "Probability parameter", theta);
                             
          
      // Wrap arguments in vector views
      VectorView<const T_n> n_vec(n);
      VectorView<const T_N> N_vec(N);
      VectorView<const T_prob> theta_vec(theta);
      size_t size = max_size(n, N, theta);
          
      // Compute vectorized CDF and gradient
      using stan::math::value_of;
      using stan::math::inc_beta;
      using stan::math::lbeta;
      using std::exp;
      using std::pow;
          
      agrad::OperandsAndPartials<T_prob> operands_and_partials(theta);
          
      // Explicit return for extreme values
      // The gradients are technically ill-defined, but treated as zero
      for (size_t i = 0; i < stan::length(n); i++) {
        if (value_of(n_vec[i]) < 0) 
          return operands_and_partials.to_var(0.0,theta);
      }
        
      for (size_t i = 0; i < size; i++) {
              
        // Explicit results for extreme values
        // The gradients are technically ill-defined, but treated as zero
        if (value_of(n_vec[i]) >= value_of(N_vec[i])) {
          continue;
        }
          
        const T_partials_return n_dbl = value_of(n_vec[i]);
        const T_partials_return N_dbl = value_of(N_vec[i]);
        const T_partials_return theta_dbl = value_of(theta_vec[i]);
        const T_partials_return betafunc = exp(lbeta(N_dbl-n_dbl,n_dbl+1));
        const T_partials_return Pi = inc_beta(N_dbl - n_dbl, n_dbl + 1, 
                                              1 - theta_dbl);
          
        P *= Pi;

        if (!is_constant_struct<T_prob>::value)
          operands_and_partials.d_x1[i] -= pow(theta_dbl,n_dbl)
            * pow(1-theta_dbl,N_dbl-n_dbl-1) / betafunc / Pi;
      }
          
      if (!is_constant_struct<T_prob>::value) {
        for(size_t i = 0; i < stan::length(theta); ++i)
          operands_and_partials.d_x1[i] *= P;
      }
          
      return operands_and_partials.to_var(P,theta);
        
    }
示例#12
0
    typename return_type<T_y, T_dof>::type
    inv_chi_square_cdf_log(const T_y& y, const T_dof& nu) {
      typedef typename stan::partials_return_type<T_y, T_dof>::type
        T_partials_return;

      // Size checks
      if ( !( stan::length(y) && stan::length(nu) ) ) return 0.0;

      // Error checks
      static const char* function("stan::math::inv_chi_square_cdf_log");

      using stan::math::check_positive_finite;
      using stan::math::check_not_nan;
      using stan::math::check_consistent_sizes;
      using stan::math::check_nonnegative;
      using boost::math::tools::promote_args;
      using stan::math::value_of;
      using std::exp;

      T_partials_return P(0.0);

      check_positive_finite(function, "Degrees of freedom parameter", nu);
      check_not_nan(function, "Random variable", y);
      check_nonnegative(function, "Random variable", y);
      check_consistent_sizes(function,
                             "Random variable", y,
                             "Degrees of freedom parameter", nu);

      // Wrap arguments in vectors
      VectorView<const T_y> y_vec(y);
      VectorView<const T_dof> nu_vec(nu);
      size_t N = max_size(y, nu);

      OperandsAndPartials<T_y, T_dof> operands_and_partials(y, nu);

      // Explicit return for extreme values
      // The gradients are technically ill-defined, but treated as zero

      for (size_t i = 0; i < stan::length(y); i++)
        if (value_of(y_vec[i]) == 0)
          return operands_and_partials.to_var(stan::math::negative_infinity(),
                                              y, nu);

      // Compute cdf_log and its gradients
      using stan::math::gamma_q;
      using stan::math::digamma;
      using boost::math::tgamma;
      using std::exp;
      using std::pow;
      using std::log;

      // Cache a few expensive function calls if nu is a parameter
      VectorBuilder<!is_constant_struct<T_dof>::value,
                    T_partials_return, T_dof> gamma_vec(stan::length(nu));
      VectorBuilder<!is_constant_struct<T_dof>::value,
                    T_partials_return, T_dof> digamma_vec(stan::length(nu));

      if (!is_constant_struct<T_dof>::value)  {
        for (size_t i = 0; i < stan::length(nu); i++) {
          const T_partials_return nu_dbl = value_of(nu_vec[i]);
          gamma_vec[i] = tgamma(0.5 * nu_dbl);
          digamma_vec[i] = digamma(0.5 * nu_dbl);
        }
      }

      // Compute vectorized cdf_log and gradient
      for (size_t n = 0; n < N; n++) {
        // Explicit results for extreme values
        // The gradients are technically ill-defined, but treated as zero
        if (value_of(y_vec[n]) == std::numeric_limits<double>::infinity()) {
          continue;
        }

        // Pull out values
        const T_partials_return y_dbl = value_of(y_vec[n]);
        const T_partials_return y_inv_dbl = 1.0 / y_dbl;
        const T_partials_return nu_dbl = value_of(nu_vec[n]);

        // Compute
        const T_partials_return Pn = gamma_q(0.5 * nu_dbl, 0.5 * y_inv_dbl);

        P += log(Pn);

        if (!is_constant_struct<T_y>::value)
          operands_and_partials.d_x1[n] += 0.5 * y_inv_dbl * y_inv_dbl
            * exp(-0.5*y_inv_dbl) * pow(0.5*y_inv_dbl, 0.5*nu_dbl-1)
            / tgamma(0.5*nu_dbl) / Pn;
        if (!is_constant_struct<T_dof>::value)
          operands_and_partials.d_x2[n]
            += 0.5 * stan::math::grad_reg_inc_gamma(0.5 * nu_dbl,
                                                    0.5 * y_inv_dbl,
                                                    gamma_vec[n],
                                                    digamma_vec[n]) / Pn;
      }

      return operands_and_partials.to_var(P, y, nu);
    }
    typename return_type<T_y, T_dof, T_scale>::type
    scaled_inv_chi_square_ccdf_log(const T_y& y, const T_dof& nu,
                                   const T_scale& s) {
      typedef typename stan::partials_return_type<T_y, T_dof, T_scale>::type
        T_partials_return;

      if (!(stan::length(y) && stan::length(nu) && stan::length(s)))
        return 0.0;

      static const char* function("scaled_inv_chi_square_ccdf_log");

      using std::exp;

      T_partials_return P(0.0);

      check_not_nan(function, "Random variable", y);
      check_nonnegative(function, "Random variable", y);
      check_positive_finite(function, "Degrees of freedom parameter", nu);
      check_positive_finite(function, "Scale parameter", s);
      check_consistent_sizes(function,
                             "Random variable", y,
                             "Degrees of freedom parameter", nu,
                             "Scale parameter", s);

      VectorView<const T_y> y_vec(y);
      VectorView<const T_dof> nu_vec(nu);
      VectorView<const T_scale> s_vec(s);
      size_t N = max_size(y, nu, s);

      OperandsAndPartials<T_y, T_dof, T_scale>
        operands_and_partials(y, nu, s);

      // Explicit return for extreme values
      // The gradients are technically ill-defined, but treated as zero
      for (size_t i = 0; i < stan::length(y); i++) {
        if (value_of(y_vec[i]) == 0)
          return operands_and_partials.value(0.0);
      }

      using std::exp;
      using std::pow;
      using std::log;

      VectorBuilder<!is_constant_struct<T_dof>::value,
                    T_partials_return, T_dof> gamma_vec(stan::length(nu));
      VectorBuilder<!is_constant_struct<T_dof>::value,
                    T_partials_return, T_dof> digamma_vec(stan::length(nu));

      if (!is_constant_struct<T_dof>::value) {
        for (size_t i = 0; i < stan::length(nu); i++) {
          const T_partials_return half_nu_dbl = 0.5 * value_of(nu_vec[i]);
          gamma_vec[i] = tgamma(half_nu_dbl);
          digamma_vec[i] = digamma(half_nu_dbl);
        }
      }

      for (size_t n = 0; n < N; n++) {
        // Explicit results for extreme values
        // The gradients are technically ill-defined, but treated as zero
        if (value_of(y_vec[n]) == std::numeric_limits<double>::infinity()) {
          return operands_and_partials.value(negative_infinity());
        }

        const T_partials_return y_dbl = value_of(y_vec[n]);
        const T_partials_return y_inv_dbl = 1.0 / y_dbl;
        const T_partials_return half_nu_dbl = 0.5 * value_of(nu_vec[n]);
        const T_partials_return s_dbl = value_of(s_vec[n]);
        const T_partials_return half_s2_overx_dbl = 0.5 * s_dbl * s_dbl
          * y_inv_dbl;
        const T_partials_return half_nu_s2_overx_dbl
          = 2.0 * half_nu_dbl * half_s2_overx_dbl;

        const T_partials_return Pn = gamma_p(half_nu_dbl,
                                             half_nu_s2_overx_dbl);
        const T_partials_return gamma_p_deriv = exp(-half_nu_s2_overx_dbl)
          * pow(half_nu_s2_overx_dbl, half_nu_dbl-1) / tgamma(half_nu_dbl);

        P += log(Pn);

        if (!is_constant_struct<T_y>::value)
          operands_and_partials.d_x1[n] -= half_nu_s2_overx_dbl * y_inv_dbl
            * gamma_p_deriv / Pn;
        if (!is_constant_struct<T_dof>::value)
          operands_and_partials.d_x2[n]
            -= (0.5 * grad_reg_inc_gamma(half_nu_dbl,
                                         half_nu_s2_overx_dbl,
                                         gamma_vec[n],
                                         digamma_vec[n])
                - half_s2_overx_dbl * gamma_p_deriv)
            / Pn;
        if (!is_constant_struct<T_scale>::value)
          operands_and_partials.d_x3[n] += 2.0 * half_nu_dbl * s_dbl * y_inv_dbl
            * gamma_p_deriv / Pn;
      }
      return operands_and_partials.value(P);
    }
示例#14
0
 inline T0
 operator()(const T0& arg1) const {
   return exp(arg1);
 }
示例#15
0
TEST(AgradFwdExp,Fvar) {
  using stan::math::fvar;
  using std::exp;

  fvar<double> x(0.5,1.0);
  
  fvar<double> a = exp(x);
  EXPECT_FLOAT_EQ(exp(0.5), a.val_);
  EXPECT_FLOAT_EQ(exp(0.5), a.d_);

  fvar<double> b = 2 * exp(x) + 4;
  EXPECT_FLOAT_EQ(2 * exp(0.5) + 4, b.val_);
  EXPECT_FLOAT_EQ(2 * exp(0.5), b.d_);

  fvar<double> c = -exp(x) + 5;
  EXPECT_FLOAT_EQ(-exp(0.5) + 5, c.val_);
  EXPECT_FLOAT_EQ(-exp(0.5), c.d_);

  fvar<double> d = -3 * exp(-x) + 5 * x;
  EXPECT_FLOAT_EQ(-3 * exp(-0.5) + 5 * 0.5, d.val_);
  EXPECT_FLOAT_EQ(3 * exp(-0.5) + 5, d.d_);

  fvar<double> y(-0.5,1.0);
  fvar<double> e = exp(y);
  EXPECT_FLOAT_EQ(exp(-0.5), e.val_);
  EXPECT_FLOAT_EQ(exp(-0.5), e.d_);

  fvar<double> z(0.0,1.0);
  fvar<double> f = exp(z);
  EXPECT_FLOAT_EQ(exp(0.0), f.val_);
  EXPECT_FLOAT_EQ(exp(0.0), f.d_);
}
示例#16
0
double exact_soln(double x){
    return 1.0 - (1.0-exp(-10.0))*x - exp(-10.0*x);
}
示例#17
0
double f(double x){
    // Source term or Inhomogeneous term
    return 100.0 * exp(-10.0 * x);
}
const float phi1 = degreeToRadian(44.f); // 1st automecoic parallel
const float phi2 = degreeToRadian(49.f); // 2nd automecoic parallel
const float phi0 = degreeToRadian(46.5f);// latitude of origin
const float X0 =  700000; // x coordinate at origin
const float Y0 = 6600000; // y coordinate at origin
// Normals
const float gN1 = a/sqrt(1-e*e*sin(phi1)*sin(phi1));
const float gN2 = a/sqrt(1-e*e*sin(phi2)*sin(phi2));
// Isometric latitudes
const float gl1=log(tan(M_PI/4+phi1/2)*pow((1-e*sin(phi1))/(1+e*sin(phi1)),e/2));
const float gl2=log(tan(M_PI/4+phi2/2)*pow((1-e*sin(phi2))/(1+e*sin(phi2)),e/2));
const float gl0=log(tan(M_PI/4+phi0/2)*pow((1-e*sin(phi0))/(1+e*sin(phi0)),e/2));
// Projection exponent
const float n = (log((gN2*cos(phi2))/(gN1*cos(phi1))))/(gl1-gl2);
// Projection constant
const float c = ((gN1*cos(phi1))/n)*exp(n*gl1);
// Coordinate
const float ys = Y0 + c*exp(-n*gl0);

// Convert geographic coordinates (latitude, longitude in degrees) into
// cartesian coordinates (in kilometers) using the Lambert 93 projection.
pair<float,float> geoToLambert93(float latitude,float longitude)
{
    float phi = degreeToRadian(latitude);
    float l   = degreeToRadian(longitude);
    float gl  = log(tan(M_PI/4+phi/2)*pow((1-e*sin(phi))/(1+e*sin(phi)),e/2));
    float x93 = X0 + c*exp(-n*gl)*sin(n*(l-lc));
    float y93 = ys - c*exp(-n*gl)*cos(n*(l-lc));
    return make_pair(x93/1000,y93/1000);
}
示例#19
0
void FunctionsTest::testWeightedModifiedBesselFunctions() {
    BOOST_TEST_MESSAGE("Testing weighted modified Bessel functions...");
    Real nu = -5.0;
    while (nu <= 5.0) {
        Real x = 0.1;
        while (x <= 15.0) {
            const Real calculated_i = 
                modifiedBesselFunction_i_exponentiallyWeighted(nu, x);
            const Real expected_i = 
                modifiedBesselFunction_i(nu, x) * exp(-x);
            const Real calculated_k = 
                modifiedBesselFunction_k_exponentiallyWeighted(nu, x);
            const Real expected_k = 
                M_PI_2 * (modifiedBesselFunction_i(-nu,x) -
                          modifiedBesselFunction_i(nu,x)) * exp(-x) / std::sin(M_PI*nu);
            const Real tol_i = 1e3 * QL_EPSILON *
                std::fabs(expected_i) * std::max(exp(x), 1.0);
            const Real tol_k = std::max(QL_EPSILON, 
                1e3 * QL_EPSILON *
                std::fabs(expected_k) * std::max(exp(x), 1.0));
            if (std::abs(expected_i - calculated_i) > tol_i) {
                BOOST_ERROR("failed to verify exponentially weighted"
                            << "modified Bessel function of first kind"
                            << "\n order      : " << nu << "\n argument   : "
                            << x << "\n calculated  : " << calculated_i
                            << "\n expected   : " << expected_i);
            }
            if (std::abs(expected_k - calculated_k) > tol_k) {
                BOOST_ERROR("failed to verify exponentially weighted"
                            << "modified Bessel function of second kind"
                            << "\n order      : " << nu << "\n argument   : "
                            << x << "\n calculated  : " << calculated_k
                            << "\n expected   : " << expected_k);
            }
            x += 0.5;
        }
        nu += 0.5;
    }
    nu = -5.0;
    while (nu <= 5.0) {
        Real x = -5.0;
        while (x <= 5.0) {
            Real y = -5.0;
            while (y <= 5.0) {
                const std::complex<Real> z(x, y);
                const std::complex<Real> calculated_i =
                    modifiedBesselFunction_i_exponentiallyWeighted(nu, z);
                const std::complex<Real> expected_i =
                    modifiedBesselFunction_i(nu, z) * exp(-z);
                const std::complex<Real> calculated_k =
                    modifiedBesselFunction_k_exponentiallyWeighted(nu, z);
                const std::complex<Real> expected_k =
                    M_PI_2 * (modifiedBesselFunction_i(-nu, z) * exp(-z) -
                              modifiedBesselFunction_i(nu, z) * exp(-z)) /
                    std::sin(M_PI * nu);
                const Real tol_i = 1e3 * QL_EPSILON*std::abs(calculated_i);
                const Real tol_k = 1e3 * QL_EPSILON*std::abs(calculated_k);
                if (std::abs(calculated_i - expected_i) > tol_i) {
                    BOOST_ERROR("failed to verify exponentially weighted"
                                << "modified Bessel function of first kind"
                                << "\n order      : " << nu
                                << "\n argument   : " << z <<
                                "\n calculated: "
                                << calculated_i << "\n expected   : " << expected_i);
                }
                if (std::abs(calculated_k - expected_k) > tol_k) {
                    BOOST_ERROR("failed to verify exponentially weighted"
                                << "modified Bessel function of second kind"
                                << "\n order      : " << nu
                                << "\n argument   : " << z <<
                                "\n calculated: "
                                << calculated_k << "\n expected   : " << expected_k);
                }
                y += 0.5;
            }
            x += 0.5;
        }
        nu += 0.5;
    }
}
int test_values(const Scalar & Cf, const Scalar & eta, const Scalar & Ea, const Scalar & D, const Scalar & Tref, const Scalar & R, const Antioch::KineticsType<Scalar> & rate_base)
{
  using std::abs;
  using std::exp;
  using std::pow;

  int return_flag = 0;

  const Scalar tol = std::numeric_limits<Scalar>::epsilon() * 100;

  for(Scalar T = 300.1L; T <= 2500.1L; T += 10.L)
  {

    const Scalar rate_exact = Cf*pow(T/Tref,eta)*exp(-Ea/(R*T) + D * T);
    const Scalar derive_exact = exp(-Ea/(R*T) + D * T) * pow(T/Tref,eta) * Cf * (Ea/(R*T*T) + eta/T + D );

    Antioch::KineticsConditions<Scalar> cond(T);

    Scalar rate1 = rate_base(cond);
    Scalar deriveRate1 = rate_base.derivative(cond);
    Scalar rate;
    Scalar deriveRate;

    rate_base.compute_rate_and_derivative(cond,rate,deriveRate);

    if( abs( (rate1 - rate_exact)/rate_exact ) > tol )
      {
          std::cerr << std::scientific << std::setprecision(16)
                    << "Error: Mismatch in rate values." << std::endl
                    << "T = " << T << " K" << std::endl
                    << "rate(T) = " << rate1 << std::endl
                    << "rate_exact = " << rate_exact << std::endl
                    << "relative difference = " << abs( (rate1 - rate_exact)/rate_exact ) << std::endl
                    << "tolerance = " << tol << std::endl
                    << "on rate " << rate_base << std::endl << std::endl;

          return_flag = 1;
      }
    if( abs( (rate - rate_exact)/rate_exact ) > tol )
      {
          std::cerr << std::scientific << std::setprecision(16)
                    << "Error: Mismatch in rate values." << std::endl
                    << "T = " << T << " K" << std::endl
                    << "rate(T) = " << rate << std::endl
                    << "rate_exact = " << rate_exact << std::endl
                    << "relative difference = " << abs( (rate - rate_exact)/rate_exact ) << std::endl
                    << "tolerance = " << tol << std::endl
                    << "on rate " << rate_base << std::endl << std::endl;

          return_flag = 1;
      }
    if( abs( (deriveRate1 - derive_exact)/derive_exact ) > tol )
      {
          std::cerr << std::scientific << std::setprecision(16)
                    << "Error: Mismatch in rate derivative values." << std::endl
                    << "T = " << T << " K" << std::endl
                    << "drate_dT(T) = " << deriveRate1 << std::endl
                    << "derive_exact = " << derive_exact << std::endl
                    << "relative difference = " << abs( (deriveRate1 - derive_exact)/derive_exact ) << std::endl
                    << "tolerance = " << tol << std::endl
                    << "on rate " << rate_base << std::endl << std::endl;

          return_flag = 1;
     }
    if( abs( (deriveRate - derive_exact)/derive_exact ) > tol )
      {
          std::cerr << std::scientific << std::setprecision(16)
                    << "Error: Mismatch in rate derivative values." << std::endl
                    << "T = " << T << " K" << std::endl
                    << "drate_dT(T) = " << deriveRate << std::endl
                    << "derive_exact = " << derive_exact << std::endl
                    << "relative difference = " << abs( (deriveRate - derive_exact)/derive_exact ) << std::endl
                    << "tolerance = " << tol << std::endl
                    << "on rate " << rate_base << std::endl << std::endl;

          return_flag = 1;
     }

     if(return_flag)break;
  }
  return return_flag;
}
示例#21
0
 typename return_type<T_y,T_dof>::type
 chi_square_cdf(const T_y& y, const T_dof& nu) {
   static const char* function("stan::prob::chi_square_cdf");
   typedef typename stan::partials_return_type<T_y,T_dof>::type 
     T_partials_return;
   
   using stan::math::check_positive_finite;
   using stan::math::check_nonnegative;
   using stan::math::check_not_nan;
   using stan::math::check_consistent_sizes;
   using stan::math::value_of;
   
   T_partials_return cdf(1.0);
   
   // Size checks
   if (!(stan::length(y) && stan::length(nu))) 
     return cdf;
   
   check_not_nan(function, "Random variable", y);
   check_nonnegative(function, "Random variable", y);
   check_positive_finite(function, "Degrees of freedom parameter", nu);
   check_consistent_sizes(function,
                          "Random variable", y,
                          "Degrees of freedom parameter", nu);
   
   // Wrap arguments in vectors
   VectorView<const T_y> y_vec(y);
   VectorView<const T_dof> nu_vec(nu);
   size_t N = max_size(y, nu);
   
   agrad::OperandsAndPartials<T_y, T_dof> 
     operands_and_partials(y, nu);
   
   // Explicit return for extreme values
   // The gradients are technically ill-defined, but treated as zero
   for (size_t i = 0; i < stan::length(y); i++) {
     if (value_of(y_vec[i]) == 0) 
       return operands_and_partials.to_var(0.0,y,nu);
   }
   
   // Compute CDF and its gradients
   using stan::math::gamma_p;
   using stan::math::digamma;
   using boost::math::tgamma;
   using std::exp;
   using std::pow;
   
   // Cache a few expensive function calls if nu is a parameter
   VectorBuilder<!is_constant_struct<T_dof>::value,
                 T_partials_return, T_dof> gamma_vec(stan::length(nu));
   VectorBuilder<!is_constant_struct<T_dof>::value,
                 T_partials_return,T_dof> digamma_vec(stan::length(nu));
   
   if (!is_constant_struct<T_dof>::value) {
     for (size_t i = 0; i < stan::length(nu); i++) {
       const T_partials_return alpha_dbl = value_of(nu_vec[i]) * 0.5;
       gamma_vec[i] = tgamma(alpha_dbl);
       digamma_vec[i] = digamma(alpha_dbl);
     }
   }
   
   // Compute vectorized CDF and gradient
   for (size_t n = 0; n < N; n++) {
     // Explicit results for extreme values
     // The gradients are technically ill-defined, but treated as zero
     if (value_of(y_vec[n]) == std::numeric_limits<double>::infinity())
       continue;
     
     // Pull out values
     const T_partials_return y_dbl = value_of(y_vec[n]);
     const T_partials_return alpha_dbl = value_of(nu_vec[n]) * 0.5;
     const T_partials_return beta_dbl = 0.5;
     
     // Compute
     const T_partials_return Pn = gamma_p(alpha_dbl, beta_dbl * y_dbl);
     
     cdf *= Pn;
     
     if (!is_constant_struct<T_y>::value)
       operands_and_partials.d_x1[n] += beta_dbl * exp(-beta_dbl * y_dbl) 
         * pow(beta_dbl * y_dbl,alpha_dbl-1) / tgamma(alpha_dbl) / Pn;
     if (!is_constant_struct<T_dof>::value)
       operands_and_partials.d_x2[n] 
         -= 0.5 * stan::math::grad_reg_inc_gamma(alpha_dbl, beta_dbl
                                                 * y_dbl, gamma_vec[n],
                                                 digamma_vec[n]) / Pn;
   }
   
   if (!is_constant_struct<T_y>::value)
     for (size_t n = 0; n < stan::length(y); ++n) 
       operands_and_partials.d_x1[n] *= cdf;
   if (!is_constant_struct<T_dof>::value)
     for (size_t n = 0; n < stan::length(nu); ++n) 
       operands_and_partials.d_x2[n] *= cdf;
   
   return operands_and_partials.to_var(cdf,y,nu);
 }
示例#22
0
    typename return_type<T_size1,T_size2>::type
    beta_binomial_ccdf_log(const T_n& n, const T_N& N, const T_size1& alpha, 
                           const T_size2& beta) {
      static const char* function("stan::prob::beta_binomial_ccdf_log");
      typedef typename stan::partials_return_type<T_n,T_N,T_size1,
                                                  T_size2>::type 
        T_partials_return;

      using stan::math::check_positive_finite;
      using stan::math::check_nonnegative;
      using stan::math::value_of;
      using stan::math::check_consistent_sizes;
      using stan::prob::include_summand;
          
      // Ensure non-zero argument lengths
      if (!(stan::length(n) && stan::length(N) && stan::length(alpha) 
            && stan::length(beta)))
        return 0.0;
          
      T_partials_return P(0.0);
          
      // Validate arguments
      check_nonnegative(function, "Population size parameter", N);
      check_positive_finite(function, "First prior sample size parameter", alpha);
      check_positive_finite(function, "Second prior sample size parameter", beta);
      check_consistent_sizes(function,
                             "Successes variable", n, 
                             "Population size parameter", N, 
                             "First prior sample size parameter", alpha, 
                             "Second prior sample size parameter", beta);

      // Wrap arguments in vector views
      VectorView<const T_n> n_vec(n);
      VectorView<const T_N> N_vec(N);
      VectorView<const T_size1> alpha_vec(alpha);
      VectorView<const T_size2> beta_vec(beta);
      size_t size = max_size(n, N, alpha, beta);
          
      // Compute vectorized cdf_log and gradient
      using stan::math::lgamma;
      using stan::math::lbeta;
      using stan::math::digamma;
      using std::exp;

      agrad::OperandsAndPartials<T_size1, T_size2> 
        operands_and_partials(alpha, beta);
          
      // Explicit return for extreme values
      // The gradients are technically ill-defined, but treated as neg infinity
      for (size_t i = 0; i < stan::length(n); i++) {
        if (value_of(n_vec[i]) <= 0) 
          return operands_and_partials.to_var(0.0,alpha,beta);
      }
          
      for (size_t i = 0; i < size; i++) {
        // Explicit results for extreme values
        // The gradients are technically ill-defined, but treated as zero
        if (value_of(n_vec[i]) >= value_of(N_vec[i])) {
          return operands_and_partials.to_var(stan::math::negative_infinity(),
                                              alpha,beta);
        }
              
        const T_partials_return n_dbl = value_of(n_vec[i]);
        const T_partials_return N_dbl = value_of(N_vec[i]);
        const T_partials_return alpha_dbl = value_of(alpha_vec[i]);
        const T_partials_return beta_dbl = value_of(beta_vec[i]);
              
        const T_partials_return mu = alpha_dbl + n_dbl + 1;
        const T_partials_return nu = beta_dbl + N_dbl - n_dbl - 1;
              
        const T_partials_return F = stan::math::F32((T_partials_return)1, mu, 
                                                    -N_dbl + n_dbl + 1, 
                                                    n_dbl + 2, 1 - nu, 
                                                    (T_partials_return)1);
              
        T_partials_return C = lgamma(nu) - lgamma(N_dbl - n_dbl);
        C += lgamma(mu) - lgamma(n_dbl + 2);
        C += lgamma(N_dbl + 2) - lgamma(N_dbl + alpha_dbl + beta_dbl);
        C = exp(C);
                
        C *= F / exp(lbeta(alpha_dbl, beta_dbl));
        C /= N_dbl + 1;
              
        const T_partials_return Pi = C;
              
        P += log(Pi);
              
        T_partials_return dF[6];
        T_partials_return digammaOne = 0;
        T_partials_return digammaTwo = 0;
              
        if (contains_nonconstant_struct<T_size1,T_size2>::value) {
          digammaOne = digamma(mu + nu);
          digammaTwo = digamma(alpha_dbl + beta_dbl);
          stan::math::grad_F32(dF, (T_partials_return)1, mu, -N_dbl + n_dbl + 1,
                               n_dbl + 2, 1 - nu, (T_partials_return)1);
        }
        if (!is_constant_struct<T_size1>::value) {
          const T_partials_return g 
            = - C * (digamma(mu) - digammaOne + dF[1] / F
                     - digamma(alpha_dbl) + digammaTwo);
          operands_and_partials.d_x1[i] -= g / Pi;
        }
        if (!is_constant_struct<T_size2>::value) {
          const T_partials_return g 
            = - C * (digamma(nu) - digammaOne - dF[4] / F - digamma(beta_dbl) 
                     + digammaTwo);
          operands_and_partials.d_x2[i] -= g / Pi;
        }
      }
          
      return operands_and_partials.to_var(P,alpha,beta);
    }
int vectester(const PairScalars& example)
{
  using std::abs;
  using std::exp;

  typedef typename Antioch::value_type<PairScalars>::type Scalar;

  const Scalar Cf = 1.4;
  const Scalar D = -2.5;

  Antioch::BerthelotRate<Scalar> berthelot_rate(Cf,D);

  // Construct from example to avoid resizing issues
  PairScalars T = example;
  T[0] = 1500.1;
  T[1] = 1600.1;
  
  const Scalar rate_exact0 = Cf*exp(D*1500.1);
  const Scalar rate_exact1 = Cf*exp(D*1600.1);
  const Scalar derive_exact0 = D * Cf * exp(D*Scalar(1500.1));
  const Scalar derive_exact1 = D * Cf * exp(D*Scalar(1600.1));

  int return_flag = 0;

  const PairScalars rate = berthelot_rate(T);
  const PairScalars deriveRate = berthelot_rate.derivative(T);

  const Scalar tol = std::numeric_limits<Scalar>::epsilon()*10;

  if( abs( (rate[0] - rate_exact0)/rate_exact0 ) > tol )
    {
      std::cout << "Error: Mismatch in rate values." << std::endl
		<< "rate(T0)   = " << rate[0] << std::endl
		<< "rate_exact = " << rate_exact0 << std::endl
		<< "difference = " << rate[0] - rate_exact0 << std::endl;

      return_flag = 1;
    }

  if( abs( (rate[1] - rate_exact1)/rate_exact1 ) > tol )
    {
      std::cout << "Error: Mismatch in rate values." << std::endl
		<< "rate(T1)   = " << rate[1] << std::endl
		<< "rate_exact = " << rate_exact1 << std::endl
		<< "difference = " << rate[1] - rate_exact1 << std::endl;

      return_flag = 1;
    }
  if( abs( (deriveRate[0] - derive_exact0)/derive_exact0 ) > tol )
    {
      std::cout << std::scientific << std::setprecision(16)
                << "Error: Mismatch in rate derivative values." << std::endl
		<< "drate_dT(T0) = " << deriveRate[0] << std::endl
		<< "derive_exact = " << derive_exact0 << std::endl;

      return_flag = 1;
    }
  if( abs( (deriveRate[1] - derive_exact1)/derive_exact1 ) > tol )
    {
      std::cout << std::scientific << std::setprecision(16)
                << "Error: Mismatch in rate derivative values." << std::endl
		<< "drate_dT(T1) = " << deriveRate[1] << std::endl
		<< "derive_exact = " << derive_exact1 << std::endl;

      return_flag = 1;
    }

  std::cout << "Berthelot rate: " << berthelot_rate << std::endl;

  return return_flag;
}
示例#24
0
    typename return_type<T_y, T_loc, T_scale>::type
    normal_ccdf_log(const T_y& y, const T_loc& mu, const T_scale& sigma) {
      static const char* function("stan::math::normal_ccdf_log");
      typedef typename stan::partials_return_type<T_y, T_loc, T_scale>::type
        T_partials_return;

      using stan::math::check_positive;
      using stan::math::check_finite;
      using stan::math::check_not_nan;
      using stan::math::check_consistent_sizes;
      using stan::math::value_of;
      using stan::math::INV_SQRT_2;
      using std::log;
      using std::exp;

      T_partials_return ccdf_log(0.0);
      // check if any vectors are zero length
      if (!(stan::length(y)
            && stan::length(mu)
            && stan::length(sigma)))
        return ccdf_log;

      check_not_nan(function, "Random variable", y);
      check_finite(function, "Location parameter", mu);
      check_not_nan(function, "Scale parameter", sigma);
      check_positive(function, "Scale parameter", sigma);
      check_consistent_sizes(function,
                             "Random variable", y,
                             "Location parameter", mu,
                             "Scale parameter", sigma);

      OperandsAndPartials<T_y, T_loc, T_scale>
        operands_and_partials(y, mu, sigma);

      VectorView<const T_y> y_vec(y);
      VectorView<const T_loc> mu_vec(mu);
      VectorView<const T_scale> sigma_vec(sigma);
      size_t N = max_size(y, mu, sigma);
      double log_half = std::log(0.5);

      const double SQRT_TWO_OVER_PI = std::sqrt(2.0 / stan::math::pi());
      for (size_t n = 0; n < N; n++) {
        const T_partials_return y_dbl = value_of(y_vec[n]);
        const T_partials_return mu_dbl = value_of(mu_vec[n]);
        const T_partials_return sigma_dbl = value_of(sigma_vec[n]);

        const T_partials_return scaled_diff = (y_dbl - mu_dbl)
          / (sigma_dbl * SQRT_2);

        T_partials_return one_m_erf;
        if (scaled_diff < -37.5 * INV_SQRT_2)
          one_m_erf = 2.0;
        else if (scaled_diff < -5.0 * INV_SQRT_2)
          one_m_erf =  2.0 - erfc(-scaled_diff);
        else if (scaled_diff > 8.25 * INV_SQRT_2)
          one_m_erf = 0.0;
        else
          one_m_erf = 1.0 - erf(scaled_diff);

        // log ccdf
        ccdf_log += log_half + log(one_m_erf);

        // gradients
        if (contains_nonconstant_struct<T_y, T_loc, T_scale>::value) {
          const T_partials_return rep_deriv_div_sigma
            = scaled_diff > 8.25 * INV_SQRT_2
            ? std::numeric_limits<double>::infinity()
            : SQRT_TWO_OVER_PI * exp(-scaled_diff * scaled_diff)
            / one_m_erf / sigma_dbl;
          if (!is_constant_struct<T_y>::value)
            operands_and_partials.d_x1[n] -= rep_deriv_div_sigma;
          if (!is_constant_struct<T_loc>::value)
            operands_and_partials.d_x2[n] += rep_deriv_div_sigma;
          if (!is_constant_struct<T_scale>::value)
            operands_and_partials.d_x3[n] += rep_deriv_div_sigma
              * scaled_diff * stan::math::SQRT_2;
        }
      }
      return operands_and_partials.value(ccdf_log);
    }
示例#25
0
    typename return_type<T_y, T_scale, T_shape>::type
    pareto_ccdf_log(const T_y& y, const T_scale& y_min,
                    const T_shape& alpha) {
      typedef typename stan::partials_return_type<T_y, T_scale, T_shape>::type
        T_partials_return;

      // Size checks
      if ( !( stan::length(y) && stan::length(y_min) && stan::length(alpha) ) )
        return 0.0;

      // Check errors
      static const char* function("stan::math::pareto_ccdf_log");

      using stan::math::check_positive_finite;
      using stan::math::check_not_nan;
      using stan::math::check_greater_or_equal;
      using stan::math::check_consistent_sizes;
      using stan::math::check_nonnegative;
      using stan::math::value_of;
      using std::log;
      using std::exp;

      T_partials_return P(0.0);

      check_not_nan(function, "Random variable", y);
      check_nonnegative(function, "Random variable", y);
      check_positive_finite(function, "Scale parameter", y_min);
      check_positive_finite(function, "Shape parameter", alpha);
      check_consistent_sizes(function,
                             "Random variable", y,
                             "Scale parameter", y_min,
                             "Shape parameter", alpha);

      // Wrap arguments in vectors
      VectorView<const T_y> y_vec(y);
      VectorView<const T_scale> y_min_vec(y_min);
      VectorView<const T_shape> alpha_vec(alpha);
      size_t N = max_size(y, y_min, alpha);

      OperandsAndPartials<T_y, T_scale, T_shape>
        operands_and_partials(y, y_min, alpha);

      // Explicit return for extreme values
      // The gradients are technically ill-defined, but treated as zero

      for (size_t i = 0; i < stan::length(y); i++) {
        if (value_of(y_vec[i]) < value_of(y_min_vec[i]))
          return operands_and_partials.to_var(0.0, y, y_min, alpha);
      }

      // Compute vectorized cdf_log and its gradients

      for (size_t n = 0; n < N; n++) {
        // Explicit results for extreme values
        // The gradients are technically ill-defined, but treated as zero
        if (value_of(y_vec[n]) == std::numeric_limits<double>::infinity()) {
          return operands_and_partials.to_var(stan::math::negative_infinity(),
                                              y, y_min, alpha);
        }

        // Pull out values
        const T_partials_return log_dbl = log(value_of(y_min_vec[n])
                                              / value_of(y_vec[n]));
        const T_partials_return y_min_inv_dbl = 1.0 / value_of(y_min_vec[n]);
        const T_partials_return alpha_dbl = value_of(alpha_vec[n]);

        P += alpha_dbl * log_dbl;

        if (!is_constant_struct<T_y>::value)
          operands_and_partials.d_x1[n] -= alpha_dbl * y_min_inv_dbl
            * exp(log_dbl);
        if (!is_constant_struct<T_scale>::value)
          operands_and_partials.d_x2[n] += alpha_dbl * y_min_inv_dbl;
        if (!is_constant_struct<T_shape>::value)
          operands_and_partials.d_x3[n] += log_dbl;
      }

      return operands_and_partials.to_var(P, y, y_min, alpha);
    }
示例#26
0
    typename return_type<T_y, T_loc, T_scale>::type
    double_exponential_cdf(const T_y& y,
                           const T_loc& mu, const T_scale& sigma) {
      static const char* function("stan::math::double_exponential_cdf");
      typedef typename stan::partials_return_type<T_y, T_loc, T_scale>::type
        T_partials_return;

      // Size checks
      if ( !( stan::length(y) && stan::length(mu)
              && stan::length(sigma) ) )
        return 1.0;

      using stan::math::value_of;
      using stan::math::check_finite;
      using stan::math::check_positive_finite;
      using stan::math::check_not_nan;
      using boost::math::tools::promote_args;
      using std::exp;

      T_partials_return cdf(1.0);

      check_not_nan(function, "Random variable", y);
      check_finite(function, "Location parameter", mu);
      check_positive_finite(function, "Scale parameter", sigma);

      OperandsAndPartials<T_y, T_loc, T_scale>
        operands_and_partials(y, mu, sigma);

      VectorView<const T_y> y_vec(y);
      VectorView<const T_loc> mu_vec(mu);
      VectorView<const T_scale> sigma_vec(sigma);
      size_t N = max_size(y, mu, sigma);

      // cdf
      for (size_t n = 0; n < N; n++) {
        const T_partials_return y_dbl = value_of(y_vec[n]);
        const T_partials_return mu_dbl = value_of(mu_vec[n]);
        const T_partials_return sigma_dbl = value_of(sigma_vec[n]);
        const T_partials_return scaled_diff = (y_dbl - mu_dbl) / (sigma_dbl);
        const T_partials_return exp_scaled_diff = exp(scaled_diff);

        if (y_dbl < mu_dbl)
          cdf *= exp_scaled_diff * 0.5;
        else
          cdf *= 1.0 - 0.5 / exp_scaled_diff;
      }

      // gradients
      for (size_t n = 0; n < N; n++) {
        const T_partials_return y_dbl = value_of(y_vec[n]);
        const T_partials_return mu_dbl = value_of(mu_vec[n]);
        const T_partials_return sigma_dbl = value_of(sigma_vec[n]);
        const T_partials_return scaled_diff = (y_dbl - mu_dbl) / sigma_dbl;
        const T_partials_return exp_scaled_diff = exp(scaled_diff);
        const T_partials_return inv_sigma = 1.0 / sigma_dbl;

        if (y_dbl < mu_dbl) {
          if (!is_constant_struct<T_y>::value)
            operands_and_partials.d_x1[n] += inv_sigma * cdf;
          if (!is_constant_struct<T_loc>::value)
            operands_and_partials.d_x2[n] -= inv_sigma * cdf;
          if (!is_constant_struct<T_scale>::value)
            operands_and_partials.d_x3[n] -= scaled_diff * inv_sigma  * cdf;
        } else {
          const T_partials_return rep_deriv = cdf * inv_sigma
            / (2.0 * exp_scaled_diff - 1.0);
          if (!is_constant_struct<T_y>::value)
            operands_and_partials.d_x1[n] += rep_deriv;
          if (!is_constant_struct<T_loc>::value)
            operands_and_partials.d_x2[n] -= rep_deriv;
          if (!is_constant_struct<T_scale>::value)
            operands_and_partials.d_x3[n] -= rep_deriv * scaled_diff;
        }
      }
      return operands_and_partials.value(cdf);
    }
示例#27
0
    typename return_type<T_y, T_shape, T_scale>::type
    weibull_cdf(const T_y& y, const T_shape& alpha, const T_scale& sigma) {
      typedef typename stan::partials_return_type<T_y, T_shape, T_scale>::type
        T_partials_return;

      static const char* function("stan::math::weibull_cdf");

      using stan::math::check_positive_finite;
      using stan::math::check_nonnegative;
      using boost::math::tools::promote_args;
      using stan::math::value_of;
      using std::log;
      using std::exp;

      // check if any vectors are zero length
      if (!(stan::length(y)
            && stan::length(alpha)
            && stan::length(sigma)))
        return 1.0;

      T_partials_return cdf(1.0);
      check_nonnegative(function, "Random variable", y);
      check_positive_finite(function, "Shape parameter", alpha);
      check_positive_finite(function, "Scale parameter", sigma);

      OperandsAndPartials<T_y, T_shape, T_scale>
        operands_and_partials(y, alpha, sigma);

      VectorView<const T_y> y_vec(y);
      VectorView<const T_scale> sigma_vec(sigma);
      VectorView<const T_shape> alpha_vec(alpha);
      size_t N = max_size(y, sigma, alpha);
      for (size_t n = 0; n < N; n++) {
        const T_partials_return y_dbl = value_of(y_vec[n]);
        const T_partials_return sigma_dbl = value_of(sigma_vec[n]);
        const T_partials_return alpha_dbl = value_of(alpha_vec[n]);
        const T_partials_return pow_ = pow(y_dbl / sigma_dbl, alpha_dbl);
        const T_partials_return exp_ = exp(-pow_);
        const T_partials_return cdf_ = 1.0 - exp_;

        // cdf
        cdf *= cdf_;

        // gradients
        const T_partials_return rep_deriv = exp_ * pow_ / cdf_;
        if (!is_constant_struct<T_y>::value)
          operands_and_partials.d_x1[n] += rep_deriv * alpha_dbl / y_dbl;
        if (!is_constant_struct<T_shape>::value)
          operands_and_partials.d_x2[n] += rep_deriv * log(y_dbl / sigma_dbl);
        if (!is_constant_struct<T_scale>::value)
          operands_and_partials.d_x3[n] -= rep_deriv * alpha_dbl / sigma_dbl;
      }

      if (!is_constant_struct<T_y>::value) {
        for (size_t n = 0; n < stan::length(y); ++n)
          operands_and_partials.d_x1[n] *= cdf;
      }
      if (!is_constant_struct<T_shape>::value) {
        for (size_t n = 0; n < stan::length(alpha); ++n)
          operands_and_partials.d_x2[n] *= cdf;
      }
      if (!is_constant_struct<T_scale>::value) {
        for (size_t n = 0; n < stan::length(sigma); ++n)
          operands_and_partials.d_x3[n] *= cdf;
      }

      return operands_and_partials.to_var(cdf, y, alpha, sigma);
    }
示例#28
0
    typename return_type<T_y, T_shape, T_inv_scale>::type
    gamma_ccdf_log(const T_y& y, const T_shape& alpha,
                   const T_inv_scale& beta) {
      if (!(stan::length(y) && stan::length(alpha) && stan::length(beta)))
        return 0.0;

      typedef typename stan::partials_return_type<T_y, T_shape,
                                                  T_inv_scale>::type
        T_partials_return;

      static const char* function("gamma_ccdf_log");

      using boost::math::tools::promote_args;
      using std::exp;

      T_partials_return P(0.0);

      check_positive_finite(function, "Shape parameter", alpha);
      check_positive_finite(function, "Scale parameter", beta);
      check_not_nan(function, "Random variable", y);
      check_nonnegative(function, "Random variable", y);
      check_consistent_sizes(function,
                             "Random variable", y,
                             "Shape parameter", alpha,
                             "Scale Parameter", beta);

      VectorView<const T_y> y_vec(y);
      VectorView<const T_shape> alpha_vec(alpha);
      VectorView<const T_inv_scale> beta_vec(beta);
      size_t N = max_size(y, alpha, beta);

      OperandsAndPartials<T_y, T_shape, T_inv_scale>
        operands_and_partials(y, alpha, beta);

      // Explicit return for extreme values
      // The gradients are technically ill-defined, but treated as zero
      for (size_t i = 0; i < stan::length(y); i++) {
        if (value_of(y_vec[i]) == 0)
          return operands_and_partials.value(0.0);
      }

      using boost::math::tgamma;
      using std::exp;
      using std::pow;
      using std::log;

      VectorBuilder<!is_constant_struct<T_shape>::value,
                    T_partials_return, T_shape> gamma_vec(stan::length(alpha));
      VectorBuilder<!is_constant_struct<T_shape>::value,
                    T_partials_return, T_shape>
        digamma_vec(stan::length(alpha));

      if (!is_constant_struct<T_shape>::value) {
        for (size_t i = 0; i < stan::length(alpha); i++) {
          const T_partials_return alpha_dbl = value_of(alpha_vec[i]);
          gamma_vec[i] = tgamma(alpha_dbl);
          digamma_vec[i] = digamma(alpha_dbl);
        }
      }

      for (size_t n = 0; n < N; n++) {
        // Explicit results for extreme values
        // The gradients are technically ill-defined, but treated as zero
        if (value_of(y_vec[n]) == std::numeric_limits<double>::infinity())
          return operands_and_partials.value(negative_infinity());

        const T_partials_return y_dbl = value_of(y_vec[n]);
        const T_partials_return alpha_dbl = value_of(alpha_vec[n]);
        const T_partials_return beta_dbl = value_of(beta_vec[n]);

        const T_partials_return Pn = gamma_q(alpha_dbl, beta_dbl * y_dbl);

        P += log(Pn);

        if (!is_constant_struct<T_y>::value)
          operands_and_partials.d_x1[n] -= beta_dbl * exp(-beta_dbl * y_dbl)
            * pow(beta_dbl * y_dbl, alpha_dbl-1) / tgamma(alpha_dbl) / Pn;
        if (!is_constant_struct<T_shape>::value)
          operands_and_partials.d_x2[n]
            += grad_reg_inc_gamma(alpha_dbl, beta_dbl
                                  * y_dbl, gamma_vec[n],
                                  digamma_vec[n]) / Pn;
        if (!is_constant_struct<T_inv_scale>::value)
          operands_and_partials.d_x3[n] -= y_dbl * exp(-beta_dbl * y_dbl)
            * pow(beta_dbl * y_dbl, alpha_dbl-1) / tgamma(alpha_dbl) / Pn;
      }
      return operands_and_partials.value(P);
    }
示例#29
0
    typename return_type<T_log_rate>::type
    poisson_log_log(const T_n& n, const T_log_rate& alpha) {
      typedef typename stan::partials_return_type<T_n,T_log_rate>::type
        T_partials_return;

      static const char* function("stan::prob::poisson_log_log");
      
      using boost::math::lgamma;
      using stan::math::check_not_nan;
      using stan::math::check_nonnegative;
      using stan::math::value_of;
      using stan::math::check_consistent_sizes;
      using stan::prob::include_summand;
      using std::exp;
      
      // check if any vectors are zero length
      if (!(stan::length(n)
            && stan::length(alpha)))
        return 0.0;

      // set up return value accumulator
      T_partials_return logp(0.0);

      // validate args
      check_nonnegative(function, "Random variable", n);
      check_not_nan(function, "Log rate parameter", alpha);
      check_consistent_sizes(function,
                             "Random variable", n, 
                             "Log rate parameter", alpha);
      
      // check if no variables are involved and prop-to
      if (!include_summand<propto,T_log_rate>::value)
        return 0.0;

      // set up expression templates wrapping scalars/vecs into vector views
      VectorView<const T_n> n_vec(n);
      VectorView<const T_log_rate> alpha_vec(alpha);
      size_t size = max_size(n, alpha);

      // FIXME: first loop size of alpha_vec, second loop if-ed for size==1
      for (size_t i = 0; i < size; i++)
        if (std::numeric_limits<double>::infinity() == alpha_vec[i])
          return LOG_ZERO;
      for (size_t i = 0; i < size; i++)
        if (-std::numeric_limits<double>::infinity() == alpha_vec[i] 
            && n_vec[i] != 0)
          return LOG_ZERO;
      
      // return accumulator with gradients
      agrad::OperandsAndPartials<T_log_rate> operands_and_partials(alpha);

      // FIXME: cache value_of for alpha_vec?  faster if only one?
      VectorBuilder<include_summand<propto,T_log_rate>::value,
                    T_partials_return, T_log_rate>
        exp_alpha(length(alpha));
      for (size_t i = 0; i < length(alpha); i++)
        if (include_summand<propto,T_log_rate>::value)
          exp_alpha[i] = exp(value_of(alpha_vec[i]));

      using stan::math::multiply_log;
      for (size_t i = 0; i < size; i++) {
        if (!(alpha_vec[i] == -std::numeric_limits<double>::infinity() 
              && n_vec[i] == 0)) {
          if (include_summand<propto>::value)
            logp -= lgamma(n_vec[i] + 1.0);
          if (include_summand<propto,T_log_rate>::value)
            logp += n_vec[i] * value_of(alpha_vec[i]) - exp_alpha[i];
        }

        // gradients
        if (!is_constant_struct<T_log_rate>::value)
          operands_and_partials.d_x1[i] += n_vec[i] - exp_alpha[i];
      }
      return operands_and_partials.to_var(logp,alpha);
    }
示例#30
0
    typename return_type<T_rate>::type
    poisson_cdf_log(const T_n& n, const T_rate& lambda) {
      static const char* function("stan::prob::poisson_cdf_log");
      typedef typename stan::partials_return_type<T_n,T_rate>::type 
        T_partials_return;
          
      using stan::math::check_not_nan;
      using stan::math::check_nonnegative;
      using stan::math::value_of;
      using stan::math::check_consistent_sizes;
          
      // Ensure non-zero argument slengths
      if (!(stan::length(n) && stan::length(lambda))) 
        return 0.0;
          
      T_partials_return P(0.0);
          
      // Validate arguments
      check_not_nan(function, "Rate parameter", lambda);
      check_nonnegative(function, "Rate parameter", lambda);
      check_consistent_sizes(function, 
                             "Random variable", n, 
                             "Rate parameter", lambda);
          
      // Wrap arguments into vector views
      VectorView<const T_n> n_vec(n);
      VectorView<const T_rate> lambda_vec(lambda);
      size_t size = max_size(n, lambda);
          
      // Compute vectorized cdf_log and gradient
      using stan::math::value_of;
      using stan::math::gamma_q;
      using boost::math::tgamma;
      using std::exp;
      using std::pow;
          
      agrad::OperandsAndPartials<T_rate> operands_and_partials(lambda);

      // Explicit return for extreme values
      // The gradients are technically ill-defined, but treated as neg infinity
      for (size_t i = 0; i < stan::length(n); i++) {
        if (value_of(n_vec[i]) < 0) 
          return operands_and_partials.to_var(stan::math::negative_infinity(),
                                              lambda);
      }
        
      for (size_t i = 0; i < size; i++) {
        // Explicit results for extreme values
        // The gradients are technically ill-defined, but treated as zero
        if (value_of(n_vec[i]) == std::numeric_limits<int>::max())
          continue;
          
        const T_partials_return n_dbl = value_of(n_vec[i]);
        const T_partials_return lambda_dbl = value_of(lambda_vec[i]);
        const T_partials_return Pi = gamma_q(n_dbl+1, lambda_dbl);

        P += log(Pi);
  
        if (!is_constant_struct<T_rate>::value)
          operands_and_partials.d_x1[i] -= exp(-lambda_dbl) 
            * pow(lambda_dbl,n_dbl) / tgamma(n_dbl+1) / Pi;

      }
      
      return operands_and_partials.to_var(P,lambda);
    }