Skip to content

Commit

Permalink
feat: adds sigmoid(), sigmoid_approx() and sigmoid_fast() functions
Browse files Browse the repository at this point in the history
  • Loading branch information
NickUfer committed Oct 4, 2024
1 parent bac64b2 commit 7f21c7f
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 0 deletions.
9 changes: 9 additions & 0 deletions core/math/math_funcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,15 @@ class Math {
}
return p_target;
}

static _ALWAYS_INLINE_ double sigmoid(double p_x) { return 1.0 / (1.0 + ::exp(-p_x)); }
static _ALWAYS_INLINE_ float sigmoid(float p_x) { return 1.0f / (1.0f + expf(-p_x)); }

static _ALWAYS_INLINE_ double sigmoid_approx(double p_x) { return 0.5 + p_x / (4.0 + fabs(p_x)); }
static _ALWAYS_INLINE_ float sigmoid_approx(float p_x) { return 0.5f + p_x / (4.0f + fabsf(p_x)); }

static _ALWAYS_INLINE_ double sigmoid_fast(double p_x) { return p_x / (1.0 + fabs(p_x)); }
static _ALWAYS_INLINE_ float sigmoid_fast(float p_x) { return p_x / (1.0f + fabsf(p_x)); }
};

#endif // MATH_FUNCS_H
16 changes: 16 additions & 0 deletions core/variant/variant_utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,18 @@ double VariantUtilityFunctions::pingpong(double value, double length) {
return Math::pingpong(value, length);
}

double VariantUtilityFunctions::sigmoid(double x) {
return Math::sigmoid(x);
}

double VariantUtilityFunctions::sigmoid_approx(double x) {
return Math::sigmoid_approx(x);
}

double VariantUtilityFunctions::sigmoid_fast(double x) {
return Math::sigmoid_fast(x);
}

Variant VariantUtilityFunctions::max(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (p_argcount < 2) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
Expand Down Expand Up @@ -1787,6 +1799,10 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDR(nearest_po2, sarray("value"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(pingpong, sarray("value", "length"), Variant::UTILITY_FUNC_TYPE_MATH);

FUNCBINDR(sigmoid, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(sigmoid_approx, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(sigmoid_fast, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);

// Random

FUNCBIND(randomize, sarray(), Variant::UTILITY_FUNC_TYPE_RANDOM);
Expand Down
3 changes: 3 additions & 0 deletions core/variant/variant_utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ struct VariantUtilityFunctions {
static double clampf(double x, double min, double max);
static int64_t clampi(int64_t x, int64_t min, int64_t max);
static int64_t nearest_po2(int64_t x);
static double sigmoid(double x);
static double sigmoid_approx(double x);
static double sigmoid_fast(double x);
// Random
static void randomize();
static int64_t randi();
Expand Down
57 changes: 57 additions & 0 deletions doc/classes/@GlobalScope.xml
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,63 @@
[/codeblock]
</description>
</method>
<method name="sigmoid">
<return type="float" />
<param index="0" name="x" type="float" />
<description>
Computes the sigmoid of [param x], which maps the input value into the range (0, 1).
The sigmoid function is defined as:
[codeblock]
sigmoid(x) = 1 / (1 + exp(-x))
[/codeblock]
This is the most accurate implementation of the sigmoid.
[codeblock]
var result = sigmoid(0.0) # result is 0.5
var result = sigmoid(1.0) # result is approximately 0.88
var result = sigmoid(-1.0) # result is approximately 0.27
var result = sigmoid(5.0) # result is approximately 0.99
[/codeblock]
[b]Note:[/b] For faster but less accurate approximation, see [method sigmoid_approx] or [method sigmoid_fast].
</description>
</method>
<method name="sigmoid_approx">
<return type="float" />
<param index="0" name="x" type="float" />
<description>
Computes an approximation of the sigmoid function for [param x].
The approximation is defined as:
[codeblock]
sigmoid_approx(x) = 0.5 + (x / (4 + abs(x)))
[/codeblock]
This function is faster than the standard [method sigmoid], especially useful in performance-sensitive environments where a balance between accuracy and speed is desired.
It provides a closer approximation to the sigmoid than the [method sigmoid_fast] function, especially around [param x] = 0.
[codeblock]
var result = sigmoid_approx(0.0) # result is 0.5
var result = sigmoid_approx(2.0) # result is approximately 0.83
var result = sigmoid_approx(-1.0) # result is approximately 0.3
var result = sigmoid_approx(5.0) # result is approximately 1.05
[/codeblock]
</description>
</method>
<method name="sigmoid_fast">
<return type="float" />
<param index="0" name="x" type="float" />
<description>
Computes a fast approximation of the sigmoid function for [param x].
The fast sigmoid is defined as:
[codeblock]
fast_sigmoid(x) = x / (1 + abs(x))
[/codeblock]
This function is faster to compute than the standard [method sigmoid] and [method sigmoid_approx], but is less accurate, particularly in the steep transition area around 0.
It is commonly used in real-time systems and machine learning where performance is critical.
[codeblock]
var result = sigmoid_fast(0.0) # result is 0
var result = sigmoid_fast(2.0) # result is approximately 0.67
var result = sigmoid_fast(-1.0) # result is approximately -0.5
var result = sigmoid_fast(5.0) # result is approximately 0.83
[/codeblock]
</description>
</method>
<method name="hash">
<return type="int" />
<param index="0" name="variable" type="Variant" />
Expand Down

0 comments on commit 7f21c7f

Please sign in to comment.