1 #ifndef __STAN__AGRAD__AGRAD_HPP__
2 #define __STAN__AGRAD__AGRAD_HPP__
29 static void grad(chainable* vi);
85 static inline void*
operator new(
size_t nbytes) {
139 vari(
const double x,
bool stacked):
156 throw std::logic_error(
"vari destruction handled automatically");
185 return os << v <<
" " << v->
val_ <<
" : " << v->
adj_;
200 o <<
"STACK, size=" <<
var_stack_.size() << std::endl;
201 for (
size_t i = 0; i <
var_stack_.size(); ++i)
204 <<
" " << (static_cast<vari*>(
var_stack_[i]))->val_
205 <<
" : " << (static_cast<vari*>(
var_stack_[i]))->adj_
248 return (
vi_ == static_cast<vari*>(0U));
278 vi_(new
vari(static_cast<double>(b))) {
288 vi_(new
vari(static_cast<double>(c))) {
298 vi_(new
vari(static_cast<double>(n))) {
308 vi_(new
vari(static_cast<double>(n))) {
318 vi_(new
vari(static_cast<double>(n))) {
328 vi_(new
vari(static_cast<double>(n))) {
338 vi_(new
vari(static_cast<double>(n))) {
347 var(
unsigned long int n) :
348 vi_(new
vari(static_cast<double>(n))) {
357 var(
unsigned long long n) :
358 vi_(new
vari(static_cast<double>(n))) {
368 vi_(new
vari(static_cast<double>(n))) {
378 vi_(new
vari(static_cast<double>(x))) {
397 vi_(new
vari(static_cast<double>(x))) {
405 inline double val()
const {
417 inline double adj()
const {
434 std::vector<double>& g) {
437 for (
size_t i = 0; i < x.size(); ++i)
607 return os << v.
val() <<
':' << v.
adj();
613 class op_v_vari :
public vari {
617 op_v_vari(
double f, vari* avi) :
623 class op_vv_vari :
public vari {
628 op_vv_vari(
double f, vari* avi, vari* bvi):
635 class op_vd_vari :
public vari {
640 op_vd_vari(
double f, vari* avi,
double b) :
647 class op_dv_vari :
public vari {
652 op_dv_vari(
double f,
double a, vari* bvi) :
659 class op_vvv_vari :
public vari {
665 op_vvv_vari(
double f, vari* avi, vari* bvi, vari* cvi) :
673 class op_vvd_vari :
public vari {
679 op_vvd_vari(
double f, vari* avi, vari* bvi,
double c) :
687 class op_vdv_vari :
public vari {
693 op_vdv_vari(
double f, vari* avi,
double b, vari* cvi) :
701 class op_vdd_vari :
public vari {
707 op_vdd_vari(
double f, vari* avi,
double b,
double c) :
715 class op_dvv_vari :
public vari {
721 op_dvv_vari(
double f,
double a, vari* bvi, vari* cvi) :
729 class op_dvd_vari :
public vari {
735 op_dvd_vari(
double f,
double a, vari* bvi,
double c) :
743 class op_ddv_vari :
public vari {
749 op_ddv_vari(
double f,
double a,
double b, vari* cvi) :
758 class precomp_v_vari :
public op_v_vari {
762 precomp_v_vari(
double val, vari* avi,
double da)
763 : op_v_vari(val,avi),
772 class op_vector_vari :
public vari {
777 op_vector_vari(
double f,
const std::vector<stan::agrad::var>& vs) :
780 vis_ = (vari**)
operator new(
sizeof(vari*) * vs.size());
781 for (
size_t i = 0; i < vs.size(); ++i)
784 vari* operator[](
size_t n)
const {
792 class neg_vari :
public op_v_vari {
794 neg_vari(vari* avi) :
795 op_v_vari(-(avi->val_), avi) {
803 class add_vv_vari :
public op_vv_vari {
805 add_vv_vari(vari* avi, vari* bvi) :
806 op_vv_vari(avi->val_ + bvi->val_, avi, bvi) {
814 class add_vd_vari :
public op_vd_vari {
816 add_vd_vari(vari* avi,
double b) :
817 op_vd_vari(avi->val_ + b, avi, b) {
824 class increment_vari :
public op_v_vari {
826 increment_vari(vari* avi) :
827 op_v_vari(avi->val_ + 1.0, avi) {
834 class decrement_vari :
public op_v_vari {
836 decrement_vari(vari* avi) :
837 op_v_vari(avi->val_ - 1.0, avi) {
844 class subtract_vv_vari :
public op_vv_vari {
846 subtract_vv_vari(vari* avi, vari* bvi) :
847 op_vv_vari(avi->val_ - bvi->val_, avi, bvi) {
855 class subtract_vd_vari :
public op_vd_vari {
857 subtract_vd_vari(vari* avi,
double b) :
858 op_vd_vari(avi->val_ - b, avi, b) {
865 class subtract_dv_vari :
public op_dv_vari {
867 subtract_dv_vari(
double a, vari* bvi) :
868 op_dv_vari(a - bvi->val_, a, bvi) {
875 class multiply_vv_vari :
public op_vv_vari {
877 multiply_vv_vari(vari* avi, vari* bvi) :
878 op_vv_vari(avi->val_ * bvi->val_, avi, bvi) {
886 class multiply_vd_vari :
public op_vd_vari {
888 multiply_vd_vari(vari* avi,
double b) :
889 op_vd_vari(avi->val_ * b, avi, b) {
897 class divide_vv_vari :
public op_vv_vari {
899 divide_vv_vari(vari* avi, vari* bvi) :
900 op_vv_vari(avi->val_ / bvi->val_, avi, bvi) {
908 class divide_vd_vari :
public op_vd_vari {
910 divide_vd_vari(vari* avi,
double b) :
911 op_vd_vari(avi->val_ / b, avi, b) {
918 class divide_dv_vari :
public op_dv_vari {
920 divide_dv_vari(
double a, vari* bvi) :
921 op_dv_vari(a / bvi->val_, a, bvi) {
928 class exp_vari :
public op_v_vari {
930 exp_vari(vari* avi) :
931 op_v_vari(std::
exp(avi->val_),avi) {
934 avi_->adj_ += adj_ * val_;
938 class log_vari :
public op_v_vari {
940 log_vari(vari* avi) :
941 op_v_vari(std::
log(avi->val_),avi) {
950 class log10_vari :
public op_v_vari {
953 log10_vari(vari* avi) :
954 op_v_vari(std::
log10(avi->val_),avi),
962 class sqrt_vari :
public op_v_vari {
964 sqrt_vari(vari* avi) :
965 op_v_vari(std::
sqrt(avi->val_),avi) {
968 avi_->adj_ += adj_ / (2.0 * val_);
972 class pow_vv_vari :
public op_vv_vari {
974 pow_vv_vari(vari* avi, vari* bvi) :
975 op_vv_vari(std::
pow(avi->val_,bvi->val_),avi,bvi) {
978 if (
avi_->val_ == 0.0)
return;
984 class pow_vd_vari :
public op_vd_vari {
986 pow_vd_vari(vari* avi,
double b) :
987 op_vd_vari(std::
pow(avi->val_,b),avi,b) {
990 if (
avi_->val_ == 0.0)
return;
995 class pow_dv_vari :
public op_dv_vari {
997 pow_dv_vari(
double a, vari* bvi) :
998 op_dv_vari(std::
pow(a,bvi->val_),a,bvi) {
1001 if (
ad_ == 0.0)
return;
1006 class cos_vari :
public op_v_vari {
1008 cos_vari(vari* avi) :
1009 op_v_vari(std::
cos(avi->val_),avi) {
1016 class sin_vari :
public op_v_vari {
1018 sin_vari(vari* avi) :
1019 op_v_vari(std::
sin(avi->val_),avi) {
1026 class tan_vari :
public op_v_vari {
1028 tan_vari(vari* avi) :
1029 op_v_vari(std::
tan(avi->val_),avi) {
1032 avi_->adj_ += adj_ * (1.0 + val_ * val_);
1036 class acos_vari :
public op_v_vari {
1038 acos_vari(vari* avi) :
1039 op_v_vari(std::
acos(avi->val_),avi) {
1046 class asin_vari :
public op_v_vari {
1048 asin_vari(vari* avi) :
1049 op_v_vari(std::
asin(avi->val_),avi) {
1056 class atan_vari :
public op_v_vari {
1058 atan_vari(vari* avi) :
1059 op_v_vari(std::
atan(avi->val_),avi) {
1062 avi_->adj_ += adj_ / (1.0 + (
avi_->val_ *
avi_->val_));
1066 class atan2_vv_vari :
public op_vv_vari {
1068 atan2_vv_vari(vari* avi, vari* bvi) :
1069 op_vv_vari(std::
atan2(avi->val_,bvi->val_),avi,bvi) {
1072 double a_sq_plus_b_sq = (
avi_->val_ *
avi_->val_) + (
bvi_->val_ *
bvi_->val_);
1073 avi_->adj_ += adj_ *
bvi_->val_ / a_sq_plus_b_sq;
1074 bvi_->adj_ -= adj_ *
avi_->val_ / a_sq_plus_b_sq;
1078 class atan2_vd_vari :
public op_vd_vari {
1080 atan2_vd_vari(vari* avi,
double b) :
1081 op_vd_vari(std::
atan2(avi->val_,b),avi,b) {
1085 avi_->adj_ += adj_ * bd_ / a_sq_plus_b_sq;
1089 class atan2_dv_vari :
public op_dv_vari {
1091 atan2_dv_vari(
double a, vari* bvi) :
1092 op_dv_vari(std::
atan2(a,bvi->val_),a,bvi) {
1096 bvi_->adj_ -= adj_ *
ad_ / a_sq_plus_b_sq;
1100 class cosh_vari :
public op_v_vari {
1102 cosh_vari(vari* avi) :
1103 op_v_vari(std::
cosh(avi->val_),avi) {
1110 class sinh_vari :
public op_v_vari {
1112 sinh_vari(vari* avi) :
1113 op_v_vari(std::
sinh(avi->val_),avi) {
1120 class tanh_vari :
public op_v_vari {
1122 tanh_vari(vari* avi) :
1123 op_v_vari(std::
tanh(avi->val_),avi) {
1127 avi_->adj_ += adj_ / (cosh *
cosh);
1132 class floor_vari :
public vari {
1134 floor_vari(vari* avi) :
1135 vari(std::
floor(avi->val_)) {
1139 class ceil_vari :
public vari {
1141 ceil_vari(vari* avi) :
1142 vari(std::
ceil(avi->val_)) {
1146 class fmod_vv_vari :
public op_vv_vari {
1148 fmod_vv_vari(vari* avi, vari* bvi) :
1149 op_vv_vari(std::
fmod(avi->val_,bvi->val_),avi,bvi) {
1153 bvi_->adj_ -= adj_ *
static_cast<int>(
avi_->val_ /
bvi_->val_);
1157 class fmod_vd_vari :
public op_v_vari {
1159 fmod_vd_vari(vari* avi,
double b) :
1160 op_v_vari(std::
fmod(avi->val_,b),avi) {
1167 class fmod_dv_vari :
public op_dv_vari {
1169 fmod_dv_vari(
double a, vari* bvi) :
1170 op_dv_vari(std::
fmod(a,bvi->val_),a,bvi) {
1173 int d =
static_cast<int>(
ad_ /
bvi_->val_);
1174 bvi_->adj_ -= adj_ * d;
1191 return a.
val() == b.
val();
1204 return a.
val() == b;
1216 return a == b.
val();
1228 return a.
val() != b.
val();
1241 return a.
val() != b;
1254 return a != b.
val();
1265 return a.
val() < b.
val();
1300 return a.
val() > b.
val();
1337 return a.
val() <= b.
val();
1350 return a.
val() <= b;
1363 return a <= b.
val();
1376 return a.
val() >= b.
val();
1389 return a.
val() >= b;
1402 return a >= b.
val();
1455 return var(
new neg_vari(a.
vi_));
1472 return var(
new add_vv_vari(a.
vi_,b.
vi_));
1490 return var(
new add_vd_vari(a.
vi_,b));
1507 return var(
new add_vd_vari(b.
vi_,a));
1525 return var(
new subtract_vv_vari(a.
vi_,b.
vi_));
1542 return var(
new subtract_vd_vari(a.
vi_,b));
1557 return var(
new subtract_dv_vari(a,b.
vi_));
1574 return var(
new multiply_vv_vari(a.
vi_,b.
vi_));
1591 return var(
new multiply_vd_vari(a.
vi_,b));
1608 return var(
new multiply_vd_vari(b.
vi_,a));
1626 return var(
new divide_vv_vari(a.
vi_,b.
vi_));
1643 return var(
new divide_vd_vari(a.
vi_,b));
1658 return var(
new divide_dv_vari(a,b.
vi_));
1671 a.
vi_ =
new increment_vari(a.
vi_);
1688 a.
vi_ =
new increment_vari(a.
vi_);
1706 a.
vi_ =
new decrement_vari(a.
vi_);
1723 a.
vi_ =
new decrement_vari(a.
vi_);
1736 return var(
new exp_vari(a.
vi_));
1750 return var(
new log_vari(a.
vi_));
1764 return var(
new log10_vari(a.
vi_));
1781 return var(
new sqrt_vari(a.
vi_));
1798 return var(
new pow_vv_vari(base.
vi_,exponent.
vi_));
1814 if (exponent == 0.5)
1816 if (exponent == 1.0)
1818 if (exponent == 2.0)
1820 return var(
new pow_vd_vari(base.vi_,exponent));
1836 return var(
new pow_dv_vari(base,exponent.
vi_));
1853 return var(
new cos_vari(a.
vi_));
1867 return var(
new sin_vari(a.
vi_));
1881 return var(
new tan_vari(a.
vi_));
1896 return var(
new acos_vari(a.
vi_));
1911 return var(
new asin_vari(a.
vi_));
1926 return var(
new atan_vari(a.
vi_));
1944 return var(
new atan2_vv_vari(a.
vi_,b.
vi_));
1960 return var(
new atan2_vd_vari(a.
vi_,b));
1976 return var(
new atan2_dv_vari(a,b.
vi_));
1992 return var(
new cosh_vari(a.
vi_));
2006 return var(
new sinh_vari(a.
vi_));
2020 return var(
new tanh_vari(a.
vi_));
2047 return var(
new neg_vari(a.
vi_));
2071 return var(
new floor_vari(a.
vi_));
2093 return var(
new ceil_vari(a.
vi_));
2114 return var(
new fmod_vv_vari(a.
vi_,b.
vi_));
2131 return var(
new fmod_vd_vari(a.
vi_,b));
2148 return var(
new fmod_dv_vari(a,b.
vi_));
2173 return var(
new neg_vari(a.
vi_));
2208 std::vector<chainable*>::reverse_iterator it;
2220 for (
size_t i = 0; i <
var_stack_.size(); ++i)
2253 std::vector<var>& independents,
2254 std::vector<std::vector<double> >&
jacobian) {
2255 jacobian.resize(dependents.size());
2256 for (
size_t i = 0; i < dependents.size(); ++i) {
2257 jacobian[i].resize(independents.size());
2260 jacobian.push_back(std::vector<double>(0));
2261 grad(dependents[i].vi_);
2262 for (
size_t j = 0; j < independents.size(); ++j)
2263 jacobian[i][j] = independents[j].adj();
2276 vi_ =
new add_vd_vari(
vi_,b);
2288 vi_ =
new subtract_vd_vari(
vi_,b);
2300 vi_ =
new multiply_vd_vari(
vi_,b);
2312 vi_ =
new divide_vd_vari(
vi_,b);
2329 struct numeric_limits<stan::agrad::var> {
2330 static const bool is_specialized =
true;
2333 static const int digits = numeric_limits<double>::digits;
2334 static const int digits10 = numeric_limits<double>::digits10;
2335 static const bool is_signed = numeric_limits<double>::is_signed;
2336 static const bool is_integer = numeric_limits<double>::is_integer;
2337 static const bool is_exact = numeric_limits<double>::is_exact;
2338 static const int radix = numeric_limits<double>::radix;
2342 static const int min_exponent = numeric_limits<double>::min_exponent;
2343 static const int min_exponent10 = numeric_limits<double>::min_exponent10;
2344 static const int max_exponent = numeric_limits<double>::max_exponent;
2345 static const int max_exponent10 = numeric_limits<double>::max_exponent10;
2347 static const bool has_infinity = numeric_limits<double>::has_infinity;
2348 static const bool has_quiet_NaN = numeric_limits<double>::has_quiet_NaN;
2349 static const bool has_signaling_NaN = numeric_limits<double>::has_signaling_NaN;
2350 static const float_denorm_style has_denorm = numeric_limits<double>::has_denorm;
2351 static const bool has_denorm_loss = numeric_limits<double>::has_denorm_loss;
2357 static const bool is_iec559 = numeric_limits<double>::is_iec559;
2358 static const bool is_bounded = numeric_limits<double>::is_bounded;
2359 static const bool is_modulo = numeric_limits<double>::is_modulo;
2361 static const bool traps = numeric_limits<double>::traps;
2362 static const bool tinyness_before = numeric_limits<double>::tinyness_before;
2363 static const float_round_style round_style = numeric_limits<double>::round_style;