1 #ifndef __STAN__AGRAD__AGRAD_HPP__
2 #define __STAN__AGRAD__AGRAD_HPP__
60 throw std::logic_error(
"chainable destruction handled automatically");
95 static inline void*
operator new(
size_t nbytes) {
157 throw std::logic_error(
"vari destruction handled automatically");
186 return os << v <<
" " << v->
val_ <<
" : " << v->
adj_;
209 o <<
"STACK, size=" <<
var_stack_.size() << std::endl;
210 for (
size_t i = 0; i <
var_stack_.size(); ++i)
257 return (
vi_ == static_cast<vari*>(0U));
287 vi_(new
vari(static_cast<double>(b))) {
297 vi_(new
vari(static_cast<double>(c))) {
307 vi_(new
vari(static_cast<double>(n))) {
317 vi_(new
vari(static_cast<double>(n))) {
327 vi_(new
vari(static_cast<double>(n))) {
337 vi_(new
vari(static_cast<double>(n))) {
347 vi_(new
vari(static_cast<double>(n))) {
356 var(
unsigned long int n) :
357 vi_(new
vari(static_cast<double>(n))) {
366 var(
unsigned long long n) :
367 vi_(new
vari(static_cast<double>(n))) {
377 vi_(new
vari(static_cast<double>(n))) {
387 vi_(new
vari(static_cast<double>(x))) {
406 vi_(new
vari(static_cast<double>(x))) {
414 inline double val()
const {
426 inline double adj()
const {
443 std::vector<double>& g) {
446 for (
size_t i = 0; i < x.size(); ++i)
447 g.push_back(x[i].vi_->adj_);
616 return os << v.
val() <<
':' << v.
adj();
622 class op_v_vari :
public vari {
626 op_v_vari(
double f, vari* avi) :
632 class op_vv_vari :
public vari {
637 op_vv_vari(
double f, vari* avi, vari* bvi):
644 class op_vd_vari :
public vari {
649 op_vd_vari(
double f, vari* avi,
double b) :
656 class op_dv_vari :
public vari {
661 op_dv_vari(
double f,
double a, vari* bvi) :
668 class op_vvv_vari :
public vari {
674 op_vvv_vari(
double f, vari* avi, vari* bvi, vari* cvi) :
682 class op_vvd_vari :
public vari {
688 op_vvd_vari(
double f, vari* avi, vari* bvi,
double c) :
696 class op_vdv_vari :
public vari {
702 op_vdv_vari(
double f, vari* avi,
double b, vari* cvi) :
710 class op_vdd_vari :
public vari {
716 op_vdd_vari(
double f, vari* avi,
double b,
double c) :
724 class op_dvv_vari :
public vari {
730 op_dvv_vari(
double f,
double a, vari* bvi, vari* cvi) :
738 class op_dvd_vari :
public vari {
744 op_dvd_vari(
double f,
double a, vari* bvi,
double c) :
752 class op_ddv_vari :
public vari {
758 op_ddv_vari(
double f,
double a,
double b, vari* cvi) :
767 class op_vector_vari :
public vari {
772 op_vector_vari(
double f,
const std::vector<stan::agrad::var>& vs) :
775 vis_ = (vari**)
operator new(
sizeof(vari*[vs.size()]));
776 for (
size_t i = 0; i < vs.size(); ++i)
779 vari* operator[](
size_t n)
const {
787 class neg_vari :
public op_v_vari {
789 neg_vari(vari* avi) :
790 op_v_vari(-(avi->val_), avi) {
798 class add_vv_vari :
public op_vv_vari {
800 add_vv_vari(vari* avi, vari* bvi) :
801 op_vv_vari(avi->val_ + bvi->val_, avi, bvi) {
809 class add_vd_vari :
public op_vd_vari {
811 add_vd_vari(vari* avi,
double b) :
812 op_vd_vari(avi->val_ + b, avi, b) {
819 class increment_vari :
public op_v_vari {
821 increment_vari(vari* avi) :
822 op_v_vari(avi->val_ + 1.0, avi) {
829 class decrement_vari :
public op_v_vari {
831 decrement_vari(vari* avi) :
832 op_v_vari(avi->val_ - 1.0, avi) {
839 class subtract_vv_vari :
public op_vv_vari {
841 subtract_vv_vari(vari* avi, vari* bvi) :
842 op_vv_vari(avi->val_ - bvi->val_, avi, bvi) {
850 class subtract_vd_vari :
public op_vd_vari {
852 subtract_vd_vari(vari* avi,
double b) :
853 op_vd_vari(avi->val_ - b, avi, b) {
860 class subtract_dv_vari :
public op_dv_vari {
862 subtract_dv_vari(
double a, vari* bvi) :
863 op_dv_vari(a - bvi->val_, a, bvi) {
870 class multiply_vv_vari :
public op_vv_vari {
872 multiply_vv_vari(vari* avi, vari* bvi) :
873 op_vv_vari(avi->val_ * bvi->val_, avi, bvi) {
881 class multiply_vd_vari :
public op_vd_vari {
883 multiply_vd_vari(vari* avi,
double b) :
884 op_vd_vari(avi->val_ * b, avi, b) {
892 class divide_vv_vari :
public op_vv_vari {
894 divide_vv_vari(vari* avi, vari* bvi) :
895 op_vv_vari(avi->val_ / bvi->val_, avi, bvi) {
903 class divide_vd_vari :
public op_vd_vari {
905 divide_vd_vari(vari* avi,
double b) :
906 op_vd_vari(avi->val_ / b, avi, b) {
913 class divide_dv_vari :
public op_dv_vari {
915 divide_dv_vari(
double a, vari* bvi) :
916 op_dv_vari(a / bvi->val_, a, bvi) {
923 class exp_vari :
public op_v_vari {
925 exp_vari(vari* avi) :
926 op_v_vari(std::
exp(avi->val_),avi) {
929 avi_->adj_ += adj_ * val_;
933 class log_vari :
public op_v_vari {
935 log_vari(vari* avi) :
936 op_v_vari(std::
log(avi->val_),avi) {
945 class log10_vari :
public op_v_vari {
948 log10_vari(vari* avi) :
949 op_v_vari(std::
log10(avi->val_),avi),
957 class sqrt_vari :
public op_v_vari {
959 sqrt_vari(vari* avi) :
960 op_v_vari(std::
sqrt(avi->val_),avi) {
963 avi_->adj_ += adj_ / (2.0 * val_);
967 class pow_vv_vari :
public op_vv_vari {
969 pow_vv_vari(vari* avi, vari* bvi) :
970 op_vv_vari(std::
pow(avi->val_,bvi->val_),avi,bvi) {
973 if (
avi_->val_ == 0.0)
return;
979 class pow_vd_vari :
public op_vd_vari {
981 pow_vd_vari(vari* avi,
double b) :
982 op_vd_vari(std::
pow(avi->val_,b),avi,b) {
985 if (
avi_->val_ == 0.0)
return;
990 class pow_dv_vari :
public op_dv_vari {
992 pow_dv_vari(
double a, vari* bvi) :
993 op_dv_vari(std::
pow(a,bvi->val_),a,bvi) {
996 if (
ad_ == 0.0)
return;
1001 class cos_vari :
public op_v_vari {
1003 cos_vari(vari* avi) :
1004 op_v_vari(std::
cos(avi->val_),avi) {
1011 class sin_vari :
public op_v_vari {
1013 sin_vari(vari* avi) :
1014 op_v_vari(std::
sin(avi->val_),avi) {
1021 class tan_vari :
public op_v_vari {
1023 tan_vari(vari* avi) :
1024 op_v_vari(std::
tan(avi->val_),avi) {
1027 avi_->adj_ += adj_ * (1.0 + val_ * val_);
1031 class acos_vari :
public op_v_vari {
1033 acos_vari(vari* avi) :
1034 op_v_vari(std::
acos(avi->val_),avi) {
1041 class asin_vari :
public op_v_vari {
1043 asin_vari(vari* avi) :
1044 op_v_vari(std::
asin(avi->val_),avi) {
1051 class atan_vari :
public op_v_vari {
1053 atan_vari(vari* avi) :
1054 op_v_vari(std::
atan(avi->val_),avi) {
1057 avi_->adj_ += adj_ / (1.0 + (
avi_->val_ *
avi_->val_));
1061 class atan2_vv_vari :
public op_vv_vari {
1063 atan2_vv_vari(vari* avi, vari* bvi) :
1064 op_vv_vari(std::
atan2(avi->val_,bvi->val_),avi,bvi) {
1067 double a_sq_plus_b_sq = (
avi_->val_ *
avi_->val_) + (
bvi_->val_ *
bvi_->val_);
1068 avi_->adj_ +=
bvi_->val_ / a_sq_plus_b_sq;
1069 bvi_->adj_ -=
avi_->val_ / a_sq_plus_b_sq;
1073 class atan2_vd_vari :
public op_vd_vari {
1075 atan2_vd_vari(vari* avi,
double b) :
1076 op_vd_vari(std::
atan2(avi->val_,b),avi,b) {
1080 avi_->adj_ += bd_ / a_sq_plus_b_sq;
1084 class atan2_dv_vari :
public op_dv_vari {
1086 atan2_dv_vari(
double a, vari* bvi) :
1087 op_dv_vari(std::
atan2(a,bvi->val_),a,bvi) {
1091 bvi_->adj_ -=
ad_ / a_sq_plus_b_sq;
1095 class cosh_vari :
public op_v_vari {
1097 cosh_vari(vari* avi) :
1098 op_v_vari(std::
cosh(avi->val_),avi) {
1105 class sinh_vari :
public op_v_vari {
1107 sinh_vari(vari* avi) :
1108 op_v_vari(std::
sinh(avi->val_),avi) {
1115 class tanh_vari :
public op_v_vari {
1117 tanh_vari(vari* avi) :
1118 op_v_vari(std::
tanh(avi->val_),avi) {
1122 avi_->adj_ += adj_ / (cosh *
cosh);
1127 class floor_vari :
public vari {
1129 floor_vari(vari* avi) :
1130 vari(std::
floor(avi->val_)) {
1134 class ceil_vari :
public vari {
1136 ceil_vari(vari* avi) :
1137 vari(std::
ceil(avi->val_)) {
1141 class fmod_vv_vari :
public op_vv_vari {
1143 fmod_vv_vari(vari* avi, vari* bvi) :
1144 op_vv_vari(std::
fmod(avi->val_,bvi->val_),avi,bvi) {
1148 bvi_->adj_ -= adj_ *
static_cast<int>(
avi_->val_ /
bvi_->val_);
1152 class fmod_vd_vari :
public op_v_vari {
1154 fmod_vd_vari(vari* avi,
double b) :
1155 op_v_vari(std::
fmod(avi->val_,b),avi) {
1162 class fmod_dv_vari :
public op_dv_vari {
1164 fmod_dv_vari(
double a, vari* bvi) :
1165 op_dv_vari(std::
fmod(a,bvi->val_),a,bvi) {
1168 int d =
static_cast<int>(
ad_ /
bvi_->val_);
1169 bvi_->adj_ -= adj_ * d;
1185 template <
typename T>
1199 inline double as_double<agrad::var>(
agrad::var x) {
return x.vi_->val_; }
1212 return a.
val() == b.
val();
1225 return a.
val() == b;
1237 return a == b.
val();
1249 return a.
val() != b.
val();
1262 return a.
val() != b;
1275 return a != b.
val();
1286 return a.
val() < b.
val();
1321 return a.
val() > b.
val();
1358 return a.
val() <= b.
val();
1371 return a.
val() <= b;
1384 return a <= b.
val();
1397 return a.
val() >= b.
val();
1410 return a.
val() >= b;
1423 return a >= b.
val();
1476 return var(
new neg_vari(a.
vi_));
1493 return var(
new add_vv_vari(a.
vi_,b.
vi_));
1511 return var(
new add_vd_vari(a.
vi_,b));
1528 return var(
new add_vd_vari(b.
vi_,a));
1546 return var(
new subtract_vv_vari(a.
vi_,b.
vi_));
1563 return var(
new subtract_vd_vari(a.
vi_,b));
1578 return var(
new subtract_dv_vari(a,b.
vi_));
1595 return var(
new multiply_vv_vari(a.
vi_,b.
vi_));
1612 return var(
new multiply_vd_vari(a.
vi_,b));
1629 return var(
new multiply_vd_vari(b.
vi_,a));
1647 return var(
new divide_vv_vari(a.
vi_,b.
vi_));
1664 return var(
new divide_vd_vari(a.
vi_,b));
1679 return var(
new divide_dv_vari(a,b.
vi_));
1692 a.
vi_ =
new increment_vari(a.
vi_);
1711 a.
vi_ =
new increment_vari(a.
vi_);
1729 a.
vi_ =
new decrement_vari(a.
vi_);
1748 a.
vi_ =
new decrement_vari(a.
vi_);
1761 return var(
new exp_vari(a.
vi_));
1775 return var(
new log_vari(a.
vi_));
1789 return var(
new log10_vari(a.
vi_));
1806 return var(
new sqrt_vari(a.
vi_));
1823 return var(
new pow_vv_vari(base.
vi_,exponent.
vi_));
1839 if (exponent == 0.5)
1841 if (exponent == 1.0)
1843 if (exponent == 2.0)
1845 return var(
new pow_vd_vari(base.vi_,exponent));
1861 return var(
new pow_dv_vari(base,exponent.
vi_));
1878 return var(
new cos_vari(a.
vi_));
1892 return var(
new sin_vari(a.
vi_));
1906 return var(
new tan_vari(a.
vi_));
1921 return var(
new acos_vari(a.
vi_));
1936 return var(
new asin_vari(a.
vi_));
1951 return var(
new atan_vari(a.
vi_));
1969 return var(
new atan2_vv_vari(a.
vi_,b.
vi_));
1985 return var(
new atan2_vd_vari(a.
vi_,b));
2001 return var(
new atan2_dv_vari(a,b.
vi_));
2017 return var(
new cosh_vari(a.
vi_));
2031 return var(
new sinh_vari(a.
vi_));
2045 return var(
new tanh_vari(a.
vi_));
2072 return var(
new neg_vari(a.
vi_));
2096 return var(
new floor_vari(a.
vi_));
2118 return var(
new ceil_vari(a.
vi_));
2139 return var(
new fmod_vv_vari(a.
vi_,b.
vi_));
2156 return var(
new fmod_vd_vari(a.
vi_,b));
2173 return var(
new fmod_dv_vari(a,b.
vi_));
2198 return var(
new neg_vari(a.
vi_));
2237 std::vector<chainable*>::iterator begin =
var_stack_.begin();
2238 std::vector<chainable*>::iterator it =
var_stack_.end();
2239 if (begin == it)
return;
2240 for (--it; (it >= begin) && (*it != vi); --it) ;
2244 for (; it >= begin; --it)
2252 for (
size_t i = 0; i <
var_stack_.size(); ++i)
2283 std::vector<var>& independents,
2284 std::vector<std::vector<double> >&
jacobian) {
2285 jacobian.resize(dependents.size());
2286 for (
size_t i = 0; i < dependents.size(); ++i) {
2287 jacobian[i].resize(independents.size());
2290 jacobian.push_back(std::vector<double>(0));
2291 grad(dependents[i].vi_);
2292 for (
size_t j = 0; j < independents.size(); ++j)
2293 jacobian[i][j] = independents[j].adj();
2306 vi_ =
new add_vd_vari(
vi_,b);
2318 vi_ =
new subtract_vd_vari(
vi_,b);
2330 vi_ =
new multiply_vd_vari(
vi_,b);
2342 vi_ =
new divide_vd_vari(
vi_,b);
2359 struct numeric_limits<stan::agrad::var> {
2360 static const bool is_specialized =
true;
2363 static const int digits = numeric_limits<double>::digits;
2364 static const int digits10 = numeric_limits<double>::digits10;
2365 static const bool is_signed = numeric_limits<double>::is_signed;
2366 static const bool is_integer = numeric_limits<double>::is_integer;
2367 static const bool is_exact = numeric_limits<double>::is_exact;
2368 static const int radix = numeric_limits<double>::radix;
2372 static const int min_exponent = numeric_limits<double>::min_exponent;
2373 static const int min_exponent10 = numeric_limits<double>::min_exponent10;
2374 static const int max_exponent = numeric_limits<double>::max_exponent;
2375 static const int max_exponent10 = numeric_limits<double>::max_exponent10;
2377 static const bool has_infinity = numeric_limits<double>::has_infinity;
2378 static const bool has_quiet_NaN = numeric_limits<double>::has_quiet_NaN;
2379 static const bool has_signaling_NaN = numeric_limits<double>::has_signaling_NaN;
2380 static const float_denorm_style has_denorm = numeric_limits<double>::has_denorm;
2381 static const bool has_denorm_loss = numeric_limits<double>::has_denorm_loss;
2387 static const bool is_iec559 = numeric_limits<double>::is_iec559;
2388 static const bool is_bounded = numeric_limits<double>::is_bounded;
2389 static const bool is_modulo = numeric_limits<double>::is_modulo;
2391 static const bool traps = numeric_limits<double>::traps;
2392 static const bool tinyness_before = numeric_limits<double>::tinyness_before;
2393 static const float_round_style round_style = numeric_limits<double>::round_style;