28#ifndef EIGEN_DONT_PARALLELIZE
29#define EIGEN_DONT_PARALLELIZE
87#define DECLARE_DIFFSCALAR_BASE() \
88 thread_local size_t DiffScalarBase::m_variableCount = 0
113template <
typename _Scalar,
typename _Gradient = Eigen::Matrix<_Scalar, Eigen::Dynamic, 1>>
234 throw std::runtime_error(
"DScalar1: Division by zero!");
320 temp =
a * std::pow(
s.value,
a - 1);
344 return DScalar1(std::sin(
s.value),
s.grad * std::cos(
s.value));
350 return DScalar1(std::cos(
s.value),
s.grad * -std::sin(
s.value));
355 if (std::abs(
s.value) >= 1)
356 throw std::runtime_error(
"acos: Expected a value in (-1, 1)");
367 if (std::abs(
s.value) >= 1)
368 throw std::runtime_error(
"asin: Expected a value in (-1, 1)");
433#if defined(__MITSUBA_MITSUBA_H_)
466template <
typename Scalar,
typename VecType>
470 <<
", grad=" << s.
getGradient().format(Eigen::IOFormat(4, 1,
", ",
"; ",
"",
"",
"[",
"]"))
498template <
typename _Scalar,
typename _Gradient = Eigen::Matrix<_Scalar, Eigen::Dynamic, 1>,
499 typename _Hessian = Eigen::Matrix<_Scalar, Eigen::Dynamic, Eigen::Dynamic>>
631 throw std::runtime_error(
"DScalar2: Division by zero!");
660 result.hess +=
s.grad *
s.grad.transpose()
738 result.hess +=
s.grad *
s.grad.transpose()
747 temp =
a * std::pow(
s.value,
a - 1);
756 result.hess +=
s.grad *
s.grad.transpose()
757 * (
a * (
a - 1) * std::pow(
s.value,
a - 2));
773 result.hess = (
s.grad *
s.grad.transpose()
791 result.hess =
s.hess /
s.value - (
s.grad *
s.grad.transpose() / (
s.value *
s.value));
833 if (std::abs(
s.value) >= 1)
834 throw std::runtime_error(
"acos: Expected a value in (-1, 1)");
846 result.hess +=
s.grad *
s.grad.transpose()
854 if (std::abs(
s.value) >= 1)
855 throw std::runtime_error(
"asin: Expected a value in (-1, 1)");
867 result.hess +=
s.grad *
s.grad.transpose()
887 +
y.grad *
x.grad.transpose()
889 -
x.grad *
y.grad.transpose())
937#if defined(__MITSUBA_MITSUBA_H_)
983template <
typename Scalar,
typename VecType,
typename MatType>
987 <<
", grad=" << s.
getGradient().format(Eigen::IOFormat(4, 1,
", ",
"; ",
"",
"",
"[",
"]"))
988 <<
", hess=" << s.
getHessian().format(Eigen::IOFormat(4, 0,
", ",
"; ",
"",
"",
"[",
"]"))
997template <
typename _Scalar,
typename _Gradient>
1001 static const bool is_specialized = std::numeric_limits<_Scalar>::is_specialized;
1002 static const bool is_signed = std::numeric_limits<_Scalar>::is_signed;
1003 static const bool is_integer = std::numeric_limits<_Scalar>::is_integer;
1004 static const bool is_exact = std::numeric_limits<_Scalar>::is_exact;
1005 static const int radix = std::numeric_limits<_Scalar>::radix;
1006 static const bool has_infinity = std::numeric_limits<_Scalar>::has_infinity;
1007 static const bool has_quiet_NaN = std::numeric_limits<_Scalar>::has_quiet_NaN;
1008 static const bool has_signaling_NaN = std::numeric_limits<_Scalar>::has_signaling_NaN;
1009 static const bool is_iec559 = std::numeric_limits<_Scalar>::is_iec559;
1010 static const bool is_bounded = std::numeric_limits<_Scalar>::is_bounded;
1011 static const bool is_modulo = std::numeric_limits<_Scalar>::is_modulo;
1012 static const bool traps = std::numeric_limits<_Scalar>::traps;
1013 static const bool tinyness_before = std::numeric_limits<_Scalar>::tinyness_before;
1014 static const std::float_denorm_style has_denorm = std::numeric_limits<_Scalar>::has_denorm;
1015 static const bool has_denorm_loss = std::numeric_limits<_Scalar>::has_denorm_loss;
1016 static const int min_exponent = std::numeric_limits<_Scalar>::min_exponent;
1017 static const int max_exponent = std::numeric_limits<_Scalar>::max_exponent;
1018 static const int min_exponent10 = std::numeric_limits<_Scalar>::min_exponent10;
1019 static const int max_exponent10 = std::numeric_limits<_Scalar>::max_exponent10;
1020 static const std::float_round_style round_style = std::numeric_limits<_Scalar>::round_style;
1021 static const int digits = std::numeric_limits<_Scalar>::digits;
1022 static const int digits10 = std::numeric_limits<_Scalar>::digits10;
1023 static const int max_digits10 = std::numeric_limits<_Scalar>::max_digits10;
1025 static constexpr _Scalar
min() {
return std::numeric_limits<_Scalar>::min(); }
1027 static constexpr _Scalar
max() {
return std::numeric_limits<_Scalar>::max(); }
1029 static constexpr _Scalar
lowest() {
return std::numeric_limits<_Scalar>::lowest(); }
1031 static constexpr _Scalar
epsilon() {
return std::numeric_limits<_Scalar>::epsilon(); }
1033 static constexpr _Scalar
round_error() {
return std::numeric_limits<_Scalar>::round_error(); }
1035 static constexpr _Scalar
infinity() {
return std::numeric_limits<_Scalar>::infinity(); }
1037 static constexpr _Scalar
quiet_NaN() {
return std::numeric_limits<_Scalar>::quiet_NaN(); }
1041 return std::numeric_limits<_Scalar>::signaling_NaN();
1044 static constexpr _Scalar
denorm_min() {
return std::numeric_limits<_Scalar>::denorm_min(); }
1047template <
typename _Scalar,
typename _Gradient,
typename _Hessian>
1048class numeric_limits<
DScalar2<_Scalar, _Gradient, _Hessian>>
1051 static const bool is_specialized = std::numeric_limits<_Scalar>::is_specialized;
1052 static const bool is_signed = std::numeric_limits<_Scalar>::is_signed;
1053 static const bool is_integer = std::numeric_limits<_Scalar>::is_integer;
1054 static const bool is_exact = std::numeric_limits<_Scalar>::is_exact;
1055 static const int radix = std::numeric_limits<_Scalar>::radix;
1056 static const bool has_infinity = std::numeric_limits<_Scalar>::has_infinity;
1057 static const bool has_quiet_NaN = std::numeric_limits<_Scalar>::has_quiet_NaN;
1058 static const bool has_signaling_NaN = std::numeric_limits<_Scalar>::has_signaling_NaN;
1059 static const bool is_iec559 = std::numeric_limits<_Scalar>::is_iec559;
1060 static const bool is_bounded = std::numeric_limits<_Scalar>::is_bounded;
1061 static const bool is_modulo = std::numeric_limits<_Scalar>::is_modulo;
1062 static const bool traps = std::numeric_limits<_Scalar>::traps;
1063 static const bool tinyness_before = std::numeric_limits<_Scalar>::tinyness_before;
1064 static const std::float_denorm_style has_denorm = std::numeric_limits<_Scalar>::has_denorm;
1065 static const bool has_denorm_loss = std::numeric_limits<_Scalar>::has_denorm_loss;
1066 static const int min_exponent = std::numeric_limits<_Scalar>::min_exponent;
1067 static const int max_exponent = std::numeric_limits<_Scalar>::max_exponent;
1068 static const int min_exponent10 = std::numeric_limits<_Scalar>::min_exponent10;
1069 static const int max_exponent10 = std::numeric_limits<_Scalar>::max_exponent10;
1070 static const std::float_round_style round_style = std::numeric_limits<_Scalar>::round_style;
1071 static const int digits = std::numeric_limits<_Scalar>::digits;
1072 static const int digits10 = std::numeric_limits<_Scalar>::digits10;
1073 static const int max_digits10 = std::numeric_limits<_Scalar>::max_digits10;
1075 static constexpr _Scalar
min() {
return std::numeric_limits<_Scalar>::min(); }
1077 static constexpr _Scalar
max() {
return std::numeric_limits<_Scalar>::max(); }
1079 static constexpr _Scalar
lowest() {
return std::numeric_limits<_Scalar>::lowest(); }
1081 static constexpr _Scalar
epsilon() {
return std::numeric_limits<_Scalar>::epsilon(); }
1083 static constexpr _Scalar
round_error() {
return std::numeric_limits<_Scalar>::round_error(); }
1085 static constexpr _Scalar
infinity() {
return std::numeric_limits<_Scalar>::infinity(); }
1087 static constexpr _Scalar
quiet_NaN() {
return std::numeric_limits<_Scalar>::quiet_NaN(); }
1091 return std::numeric_limits<_Scalar>::signaling_NaN();
1094 static constexpr _Scalar
denorm_min() {
return std::numeric_limits<_Scalar>::denorm_min(); }
std::ostream & operator<<(std::ostream &out, const DScalar1< Scalar, VecType > &s)
static constexpr _Scalar denorm_min()
static constexpr _Scalar signaling_NaN()
static constexpr _Scalar epsilon()
static constexpr _Scalar min()
static constexpr _Scalar infinity()
static constexpr _Scalar quiet_NaN()
static constexpr _Scalar max()
static constexpr _Scalar lowest()
static constexpr _Scalar round_error()
static constexpr _Scalar min()
static constexpr _Scalar signaling_NaN()
static constexpr _Scalar denorm_min()
static constexpr _Scalar quiet_NaN()
static constexpr _Scalar infinity()
static constexpr _Scalar epsilon()
static constexpr _Scalar round_error()
static constexpr _Scalar max()
static constexpr _Scalar lowest()
Automatic differentiation scalar with first-order derivatives.
friend DScalar1 sin(const DScalar1 &s)
DScalar1(const DScalar1 &s)
Copy constructor.
DScalar1 & operator/=(const Scalar &v)
friend DScalar1 atan2(const DScalar1 &y, const DScalar1 &x)
friend DScalar1 operator-(const DScalar1 &s)
friend DScalar1 cos(const DScalar1 &s)
bool operator<=(const Scalar &s) const
DScalar1 & operator+=(const Scalar &v)
friend DScalar1 operator*(const DScalar1 &lhs, const Scalar &rhs)
DScalar1 & operator-=(const DScalar1 &s)
friend DScalar1 operator/(const DScalar1 &lhs, const DScalar1 &rhs)
bool operator==(const Scalar &s) const
friend DScalar1 operator*(const DScalar1 &lhs, const DScalar1 &rhs)
friend DScalar1 operator-(const DScalar1 &lhs, const DScalar1 &rhs)
const Gradient & getGradient() const
bool operator<(const DScalar1 &s) const
DScalar1 & operator+=(const DScalar1 &s)
bool operator>=(const Scalar &s) const
friend DScalar1 operator-(const DScalar1 &lhs, const Scalar &rhs)
bool operator>(const Scalar &s) const
bool operator!=(const Scalar &s) const
friend DScalar1 inverse(const DScalar1 &s)
friend DScalar1 operator/(const DScalar1 &lhs, const Scalar &rhs)
friend DScalar1 operator/(const Scalar &lhs, const DScalar1 &rhs)
DScalar1(Scalar value_, const Gradient &grad_)
Construct a scalar associated with the given gradient.
friend DScalar1 operator*(const Scalar &lhs, const DScalar1 &rhs)
static DVector2 vector(const Eigen::Matrix< Scalar, 2, 1 > &v)
Initialize a constant two-dimensional vector.
DScalar1 & operator*=(const Scalar &v)
Eigen::Matrix< DScalar1, 2, 1 > DVector2
static DVector3 vector(const Eigen::Matrix< Scalar, 3, 1 > &v)
Create a constant three-dimensional vector.
bool operator>=(const DScalar1 &s) const
friend DScalar1 asin(const DScalar1 &s)
friend DScalar1 operator+(const DScalar1 &lhs, const Scalar &rhs)
DScalar1(size_t index, const Scalar &value_)
Construct a new scalar with the specified value and one first derivative set to 1.
friend DScalar1 pow(const DScalar1 &s, const Scalar &a)
bool operator<=(const DScalar1 &s) const
DScalar1(Scalar value_=(Scalar) 0)
Create a new constant automatic differentiation scalar.
friend DScalar1 operator-(const Scalar &lhs, const DScalar1 &rhs)
DScalar1 & operator-=(const Scalar &v)
friend DScalar1 abs(const DScalar1 &s)
friend DScalar1 exp(const DScalar1 &s)
Eigen::Matrix< DScalar1, 3, 1 > DVector3
friend DScalar1 operator+(const Scalar &lhs, const DScalar1 &rhs)
friend DScalar1 operator+(const DScalar1 &lhs, const DScalar1 &rhs)
void operator=(const Scalar &v)
friend DScalar1 acos(const DScalar1 &s)
bool operator>(const DScalar1 &s) const
friend DScalar1 sqrt(const DScalar1 &s)
friend DScalar1 log(const DScalar1 &s)
const Scalar & getValue() const
bool operator<(const Scalar &s) const
void operator=(const DScalar1 &s)
Automatic differentiation scalar with first- and second-order derivatives.
Eigen::Matrix< DScalar2, 2, 1 > DVector2
bool operator<=(const Scalar &s) const
DScalar2 & operator+=(const DScalar2 &s)
bool operator<(const Scalar &s) const
friend DScalar2 atan2(const DScalar2 &y, const DScalar2 &x)
friend DScalar2 sin(const DScalar2 &s)
bool operator>(const Scalar &s) const
bool operator>(const DScalar2 &s) const
const Scalar & getValue() const
friend DScalar2 operator+(const DScalar2 &lhs, const DScalar2 &rhs)
const Gradient & getGradient() const
bool operator<(const DScalar2 &s) const
friend DScalar2 inverse(const DScalar2 &s)
DScalar2 & operator/=(const Scalar &v)
friend DScalar2 operator*(const DScalar2 &lhs, const Scalar &rhs)
void operator=(const Scalar &v)
bool operator==(const Scalar &s) const
DScalar2 & operator+=(const Scalar &v)
friend DScalar2 cos(const DScalar2 &s)
friend DScalar2 acos(const DScalar2 &s)
DScalar2(Scalar value_, const Gradient &grad_, const Hessian &hess_)
Construct a scalar associated with the given gradient and Hessian.
DScalar2(size_t index, const Scalar &value_)
Construct a new scalar with the specified value and one first derivative set to 1.
bool operator>=(const Scalar &s) const
DScalar2(const DScalar2 &s)
Copy constructor.
bool operator>=(const DScalar2 &s) const
friend DScalar2 operator-(const DScalar2 &lhs, const DScalar2 &rhs)
static DVector2 vector(const Eigen::Matrix< Scalar, 2, 1 > &v)
Initialize a constant two-dimensional vector.
const Hessian & getHessian() const
Eigen::Matrix< DScalar2, 3, 1 > DVector3
friend DScalar2 operator+(const DScalar2 &lhs, const Scalar &rhs)
friend DScalar2 exp(const DScalar2 &s)
friend DScalar2 log(const DScalar2 &s)
friend DScalar2 operator/(const DScalar2 &lhs, const Scalar &rhs)
DScalar2(Scalar value_=(Scalar) 0)
Create a new constant automatic differentiation scalar.
bool operator!=(const DScalar2 &s) const
friend DScalar2 operator*(const DScalar2 &lhs, const DScalar2 &rhs)
void operator=(const DScalar2 &s)
friend DScalar2 operator+(const Scalar &lhs, const DScalar2 &rhs)
friend DScalar2 abs(const DScalar2 &s)
bool operator<=(const DScalar2 &s) const
friend DScalar2 operator/(const Scalar &lhs, const DScalar2 &rhs)
friend DScalar2 sqrt(const DScalar2 &s)
friend DScalar2 operator-(const DScalar2 &s)
friend DScalar2 asin(const DScalar2 &s)
DScalar2 & operator-=(const Scalar &v)
DScalar2 & operator-=(const DScalar2 &s)
friend DScalar2 pow(const DScalar2 &s, const Scalar &a)
friend DScalar2 operator*(const Scalar &lhs, const DScalar2 &rhs)
static DVector3 vector(const Eigen::Matrix< Scalar, 3, 1 > &v)
Create a constant three-dimensional vector.
DScalar2 & operator*=(const Scalar &v)
friend DScalar2 operator-(const Scalar &lhs, const DScalar2 &rhs)
bool operator!=(const Scalar &s) const
friend DScalar2 operator/(const DScalar2 &lhs, const DScalar2 &rhs)
friend DScalar2 operator-(const DScalar2 &lhs, const Scalar &rhs)
Base class of all automatic differentiation types.
static thread_local size_t m_variableCount
static size_t getVariableCount()
Get the variable count used by the automatic differentiation layer.
static void setVariableCount(size_t value)
Set the independent variable count used by the automatic differentiation layer.