Skip to content

Commit

Permalink
[JMT] Add derivative of smooth_pos, smooth_neg, and smooth_clamp
Browse files Browse the repository at this point in the history
  • Loading branch information
jmanzanero committed Mar 17, 2024
1 parent fdf54c0 commit 4a147aa
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
9 changes: 9 additions & 0 deletions lion/foundation/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,15 @@ inline std::vector<T> string_to_double_vector(std::string str)
template<bool ActuallySmooth = true, typename T, typename S>
constexpr T smooth_pos(const T &x, S eps2);

template<bool ActuallySmooth = true, typename T, typename S>
constexpr T smooth_pos_derivative(const T &x, S eps2);

template<bool ActuallySmooth = true, typename T, typename S>
constexpr T smooth_neg(const T &x, S eps2);

template<bool ActuallySmooth = true, typename T, typename S>
constexpr T smooth_neg_derivative(const T &x, S eps2);

template<bool ActuallySmooth = true, bool UseSinAtanFormula = true, typename T, typename S>
constexpr T smooth_sign(const T &x, S eps);

Expand All @@ -152,6 +158,9 @@ constexpr T smooth_min(const T &x, const T1 &hi, S eps);
template<bool ActuallySmooth = true, typename T, typename T1, typename T2, typename S>
constexpr T smooth_clamp(const T &x, const T1 &lo, const T2 &hi, S eps2);

template<bool ActuallySmooth = true, typename T, typename T1, typename T2, typename S>
constexpr T smooth_clamp_derivative(const T &x, const T1 &lo, const T2 &hi, S eps2);

template<bool ActuallySmooth = true, bool UseSinAtanFormula = true, typename T, typename S>
constexpr T smooth_step(const T &x, S eps);

Expand Down
61 changes: 61 additions & 0 deletions lion/foundation/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,30 @@ constexpr T smooth_pos(const T &x, S eps2)
}


template<bool ActuallySmooth, typename T, typename S>
constexpr T smooth_pos_derivative(const T &x, S eps2)
{
//
// Returns the positive part of input "x", smoothed
// out near 0 with parameter "eps2" (unless template
// parameter "ActuallySmooth" is false, in that case
// the function returns the strict positive part
// of "x").
//

if constexpr (ActuallySmooth) {
using std::sqrt;

return scalar{0.5} * (scalar{1} + x/sqrt(eps2+x*x));
}
else {
(void)eps2;

return x > T{ 0 } ? T{ 1 } : T{ 0 };
}
}


template<bool ActuallySmooth, typename T, typename S>
constexpr T smooth_neg(const T &x, S eps2)
{
Expand All @@ -224,6 +248,21 @@ constexpr T smooth_neg(const T &x, S eps2)
}


template<bool ActuallySmooth, typename T, typename S>
constexpr T smooth_neg_derivative(const T &x, S eps2)
{
//
// Returns the negative part of input "x", smoothed
// out near 0 with parameter "eps2" (unless template
// parameter "ActuallySmooth" is false, in that case
// the function returns the strict negative part
// of "x").
//

return smooth_pos_derivative<ActuallySmooth>(-x, eps2);
}


template<bool ActuallySmooth, bool UseSmoothAbsFormula, typename T, typename S>
constexpr T smooth_sign(const T &x, S eps)
{
Expand Down Expand Up @@ -407,6 +446,28 @@ constexpr T smooth_clamp(const T &x, const T1 &lo, const T2 &hi, S eps2)
}


template<bool ActuallySmooth, typename T, typename T1, typename T2, typename S>
constexpr T smooth_clamp_derivative(const T &x, const T1 &lo, const T2 &hi, S eps2)
{
//
// Clamps "x" to "[x_lower, x_upper]", using a squared root smooth modulation,
// unless template parameter "ActuallySmooth" is false, in
// that case we strictly clamp the value.
//

if constexpr (ActuallySmooth) {
using std::sqrt;

const auto Dxlo = x - lo;
const auto Dxhi = x - hi;
return S{ 0.5 } * (Dxlo / sqrt(Dxlo * Dxlo + eps2) - Dxhi / sqrt(Dxhi * Dxhi + eps2));
}
else {
return x < hi ? (x > lo ? T{ 1 } : T{ 0 }) : T{ 0 };
}
}


template<bool ActuallySmooth, bool UseSmoothAbsFormula, typename T, typename S>
constexpr T smooth_step(const T &x, S eps)
{
Expand Down

0 comments on commit 4a147aa

Please sign in to comment.