15 #if defined(TINY_AD_USE_STD_VALARRAY) 16 #include "tiny_valarray.hpp" 17 #define TINY_VECTOR(type,size) tiny_vector<type, size> 18 #elif defined(TINY_AD_USE_EIGEN_VEC) 19 #include <Eigen/Dense> 20 #define TINY_VECTOR(type,size) Eigen::Array<type, size, 1> 22 #include "tiny_vec.hpp" 23 #define TINY_VECTOR(type,size) tiny_vec<type, size> 27 template<
class Type,
class Vector>
32 ad(Type v, Vector d){value = v; deriv = d;}
33 ad(
double v) {value = v; deriv.setZero();}
34 ad operator+ (
const ad &other)
const{
35 return ad(value + other.value,
38 ad operator+ ()
const{
41 ad operator- (
const ad &other)
const{
42 return ad(value - other.value,
45 ad operator- ()
const{
46 return ad(-value, -deriv);
49 return ad(value * other.value,
53 ad operator/ (
const ad &other)
const{
54 Type res = value / other.value;
56 (deriv - res * other.deriv) /
60 #define COMPARISON_OPERATOR(OP) \ 61 template<class other> \ 62 bool operator OP (const other &x) const{ \ 63 return (value OP x); \ 65 COMPARISON_OPERATOR(<)
66 COMPARISON_OPERATOR(>)
67 COMPARISON_OPERATOR(<=)
68 COMPARISON_OPERATOR(>=)
69 COMPARISON_OPERATOR(==)
70 COMPARISON_OPERATOR(!=)
71 #undef COMPARISON_OPERATOR 73 ad operator+ (
const double &x)
const{
74 return ad(value + x, deriv);
76 ad operator- (
const double &x)
const{
77 return ad(value - x, deriv);
80 return ad(value * x, deriv * x);
82 ad operator/ (
const double &x)
const{
83 return ad(value / x, deriv / x);
86 ad& operator+=(
const ad &other){
91 ad& operator-=(
const ad &other){
96 ad& operator*=(
const ad &other){
99 deriv += other.deriv * value;
100 value *= other.value;
107 ad& operator/=(
const ad &other){
108 value /= other.value;
109 deriv -= other.deriv * value;
110 deriv /= other.value;
115 template<
class T,
class V>
116 ad<T, V> operator+ (
const double &x,
const ad<T, V> &y) {
119 template<
class T,
class V>
120 ad<T, V> operator- (
const double &x,
const ad<T, V> &y) {
123 template<
class T,
class V>
124 ad<T, V>
operator* (
const double &x,
const ad<T, V> &y) {
127 template<
class T,
class V>
128 ad<T, V> operator/ (
const double &x,
const ad<T, V> &y) {
129 T value = x / y.value;
130 return ad<T, V>(value, T(-value / y.value) * y.deriv);
133 #define UNARY_MATH_ZERO_DERIV(F) \ 134 template<class T, class V> \ 135 double F (const ad<T, V> &x){ \ 138 using ::floor; using ::ceil;
139 using ::trunc; using ::round;
140 UNARY_MATH_ZERO_DERIV(floor)
141 UNARY_MATH_ZERO_DERIV(ceil)
142 UNARY_MATH_ZERO_DERIV(trunc)
143 UNARY_MATH_ZERO_DERIV(round)
145 double sign(const T &x){
return (x > 0) - (x < 0);}
146 bool isfinite(
const double &x)CSKIP( {
return std::isfinite(x);} )
147 template<class T, class V>
148 bool isfinite(
const ad<T, V> &x){
return isfinite(x.value);}
149 #undef UNARY_MATH_ZERO_DERIV 151 #define UNARY_MATH_DERIVATIVE(F,DF) \ 152 template<class T, class V> \ 153 ad<T, V> F (const ad<T, V> &x){ \ 154 return ad<T, V>(F (x.value), \ 155 T(DF(x.value)) * x.deriv); \ 157 using ::exp; using ::log;
158 using ::sin; using ::cos; using ::tan;
159 using ::sinh; using ::cosh; using ::tanh;
160 using ::sqrt; using ::fabs;
161 template<
class T> T D_tan(
const T &x) {
162 T y = cos(x);
return 1. / (y * y);
164 template<
class T> T D_tanh(
const T &x) {
165 T y = cosh(x);
return 1. / (y * y);
167 UNARY_MATH_DERIVATIVE(exp, exp)
168 UNARY_MATH_DERIVATIVE(log, 1.0/)
169 UNARY_MATH_DERIVATIVE(sin, cos)
170 UNARY_MATH_DERIVATIVE(cos, -sin)
171 UNARY_MATH_DERIVATIVE(tan, D_tan)
172 UNARY_MATH_DERIVATIVE(sinh, cosh)
173 UNARY_MATH_DERIVATIVE(cosh, sinh)
174 UNARY_MATH_DERIVATIVE(tanh, D_tanh)
175 UNARY_MATH_DERIVATIVE(sqrt, 0.5/sqrt)
176 UNARY_MATH_DERIVATIVE(fabs, sign)
177 using ::expm1; using ::log1p;
178 UNARY_MATH_DERIVATIVE(expm1, exp)
179 template<class T> T D_log1p(const T &x) {
return 1. / (x + 1.);}
180 UNARY_MATH_DERIVATIVE(log1p, D_log1p)
182 using ::asin; using ::acos; using ::atan;
183 template<class T> T D_asin(const T &x) {
184 return 1. / sqrt(1. - x * x);
186 template<
class T> T D_acos(
const T &x) {
187 return -1. / sqrt(1. - x * x);
189 template<
class T> T D_atan(
const T &x) {
190 return 1. / (1. + x * x);
192 UNARY_MATH_DERIVATIVE(asin, D_asin)
193 UNARY_MATH_DERIVATIVE(acos, D_acos)
194 UNARY_MATH_DERIVATIVE(atan, D_atan)
195 #undef UNARY_MATH_DERIVATIVE 197 template<
class T,
class V>
198 ad<T, V> pow (
const ad<T, V> &x,
const ad<T, V> &y){
199 return exp(y * log(x));
202 template<
class T,
class V>
203 ad<T, V> pow (
const ad<T, V> &x,
const double &y){
204 return ad<T, V> (pow(x.value, y),
205 T( y * pow(x.value, y - 1.) ) * x.deriv);
208 #define COMPARISON_OPERATOR_FLIP(OP1, OP2) \ 209 template<class T, class V> \ 210 bool operator OP1 (const double &x, const ad<T, V> &y) { \ 213 COMPARISON_OPERATOR_FLIP(<,>)
214 COMPARISON_OPERATOR_FLIP(<=,>=)
215 COMPARISON_OPERATOR_FLIP(>,<)
216 COMPARISON_OPERATOR_FLIP(>=,<=)
217 COMPARISON_OPERATOR_FLIP(==,==)
218 COMPARISON_OPERATOR_FLIP(!=,!=)
219 #undef COMPARISON_OPERATOR_FLIP 221 double asDouble(
double x) CSKIP( {
return x;} )
222 template<class T, class V>
223 double asDouble (
const ad<T, V> &x){
224 return asDouble(x.value);
228 double max_fabs(
double x) CSKIP( {
return fabs(x);} )
229 template<class T, class V>
230 double max_fabs (
const ad<T, V> &x){
231 double ans = max_fabs(x.value);
232 for(
int i=0; i<x.deriv.size(); i++) {
233 double tmp = max_fabs(x.deriv[i]);
234 ans = (tmp > ans ? tmp : ans);
242 double Rf_lgammafn(
double);
243 double Rf_psigamma(
double,
double);
246 double lgamma(
const double &x) {
247 return Rf_psigamma(x, deriv-1);
250 double lgamma<0>(
const double &x) CSKIP( {
return Rf_lgammafn(x);} )
251 double lgamma(
const double &x) CSKIP( {
return lgamma<0>(x);} )
252 template<int deriv, class T, class V>
253 ad<T, V>
lgamma (
const ad<T, V> &x){
254 return ad<T, V> (lgamma< deriv >(x.value),
255 T(lgamma< deriv + 1 >(x.value)) * x.deriv);
257 template<
class T,
class V>
258 ad<T, V>
lgamma (
const ad<T, V> &x){
263 template<
class T,
class V>
264 std::ostream &operator<<(std::ostream &os, const ad<T, V> &x) {
266 os <<
" value=" << x.value;
267 os <<
" deriv=" << x.deriv;
280 #define VARIABLE(order, nvar, scalartype) variable<order, nvar, scalartype> 281 template<
int order,
int nvar,
class Double=
double>
282 struct variable : ad< VARIABLE(order-1, nvar, Double),
283 TINY_VECTOR( VARIABLE(order-1, nvar, Double) , nvar) > {
284 typedef ad< VARIABLE(order-1, nvar, Double),
285 TINY_VECTOR(VARIABLE(order-1, nvar, Double), nvar) > Base;
286 typedef variable<
order-1, nvar, Double> Type;
287 static const int result_size = nvar * Type::result_size;
288 #define ___COMMON_CTORS___ \ 290 variable(Base x) : Base(x) {} \ 291 variable(double x) : Base(x) {} \ 292 variable(double x, int id) : Base(x) { \ 295 template<int T1, int T2, class T3> \ 296 variable(variable<T1,T2,T3> x) { \ 297 Base::value = x; Base::deriv.setZero(); \ 299 template<class T1, class T2> \ 300 variable(ad<T1,T2> x) { \ 301 Base::value = x; Base::deriv.setZero(); \ 303 template<int T1, int T2, class T3> \ 304 variable(variable<T1,T2,T3> x, int id) { \ 305 Base::value = x; Base::deriv.setZero(); \ 308 template<class T1, class T2> \ 309 variable(ad<T1,T2> x, int id) { \ 310 Base::value = x; Base::deriv.setZero(); \ 314 void setid(
int i0,
int count = 0){
315 this->value.setid(i0, count);
316 this->deriv[i0].setid(i0, count + 1);
318 TINY_VECTOR(Double, result_size) getDeriv(){
319 TINY_VECTOR(Double, result_size) ans;
320 int stride = result_size / nvar;
321 for(
int i=0; i<nvar; i++)
322 ans.segment(i * stride, stride) = this->deriv[i].getDeriv();
327 template<
int nvar,
class Double>
328 struct variable<1, nvar, Double> : ad<Double, TINY_VECTOR(Double,nvar) >{
329 typedef ad<Double, TINY_VECTOR(Double,nvar) > Base;
330 static const int result_size = nvar;
332 void setid(
int i0,
int count = 0){
334 this->deriv[i0] = 1.0;
338 TINY_VECTOR(Double, nvar) getDeriv(){
342 #undef ___COMMON_CTORS___ vector< Type > operator*(matrix< Type > A, vector< Type > x)
Type lgamma(Type x)
Logarithm of gamma function (following R argument convention).
std::vector< size_t > order(std::vector< T > x)
Get permutation that sorts a vector.