Change finite-support mju_sigmoid from a two-quadratic construction to a single quintic with zero 1st and 2nd derivatives at 0 and 1, the boundary of the smooth-support segment.
Note: this function is currently unused in the MuJoCo codebase. PiperOrigin-RevId: 529969804 Change-Id: I2bddc72916eff67625b806510935bc7f3ce5c770
This commit is contained in:
committed by
Copybara-Service
parent
26ff1fc4b5
commit
49efa9cc15
@@ -3160,7 +3160,7 @@ mju_sigmoid
|
||||
|
||||
.. mujoco-include:: mju_sigmoid
|
||||
|
||||
Sigmoid function over 0<=x<=1 constructed from half-quadratics.
|
||||
Sigmoid function over 0<=x<=1 using quintic polynomial.
|
||||
|
||||
.. _Derivatives-api:
|
||||
|
||||
|
||||
+13
-3
@@ -20,13 +20,23 @@ General
|
||||
^^^^^^^
|
||||
|
||||
- Added :ref:`mjd_inverseFD` for finite-differenced inverse-dynamics derivatives.
|
||||
- Added functions for operations on banded-then-dense "arrowhead" matrices. Such matrices are
|
||||
common when doing direct trajectory optimization.
|
||||
See :ref:`mju_cholFactorBand` documentation for details.
|
||||
- Added functions for operations on banded-then-dense "arrowhead" matrices. Such matrices are common when doing direct
|
||||
trajectory optimization. See :ref:`mju_cholFactorBand` documentation for details.
|
||||
- Added :ref:`mj_multiRay` function for intersecting multiple rays emanating from a single point.
|
||||
This is significantly faster than calling :ref:`mj_ray` multiple times.
|
||||
- Increased ``mjMAXUIITEM`` (maximum number of UI elements per section in Simulate) to 100.
|
||||
- Added :ref:`documentation<exProvider>` for resource providers.
|
||||
- Changed the formula for :ref:`mju_sigmoid`, a finite-support sigmoid :math:`s \colon \mathbf R \rightarrow [0, 1]`.
|
||||
Previously, the smooth part consisted of two stitched quadratics, once continuously differentiable.
|
||||
It is now a single quintic, twice continuously differentiable:
|
||||
|
||||
.. math::
|
||||
s(x) =
|
||||
\begin{cases}
|
||||
0, & & x \le 0 \\
|
||||
6x^5 - 15x^4 + 10x^3, & 0 \lt & x \lt 1 \\
|
||||
1, & 1 \le & x \qquad
|
||||
\end{cases}
|
||||
|
||||
Version 2.3.5 (April 25, 2023)
|
||||
------------------------------
|
||||
|
||||
@@ -301,6 +301,7 @@ Resource providers work via callbacks:
|
||||
- :ref:`mjfGetResourceDir<mjfGetResourceDir>`: This callback is optional and is used to extract the directory from a
|
||||
resource name. For example, the resource name ``http://www.example.com/myasset.obj`` would have
|
||||
``http://www.example.com/`` as its directory.
|
||||
|
||||
.. _exProviderUsage:
|
||||
|
||||
Usage
|
||||
|
||||
@@ -1216,7 +1216,7 @@ MJAPI mjtNum mju_Halton(int index, int base);
|
||||
// Call strncpy, then set dst[n-1] = 0.
|
||||
MJAPI char* mju_strncpy(char *dst, const char *src, int n);
|
||||
|
||||
// Sigmoid function over 0<=x<=1 constructed from half-quadratics.
|
||||
// Sigmoid function over 0<=x<=1 using quintic polynomial.
|
||||
MJAPI mjtNum mju_sigmoid(mjtNum x);
|
||||
|
||||
|
||||
|
||||
@@ -7752,7 +7752,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
||||
type=ValueType(name='mjtNum'),
|
||||
),
|
||||
),
|
||||
doc='Sigmoid function over 0<=x<=1 constructed from half-quadratics.',
|
||||
doc='Sigmoid function over 0<=x<=1 using quintic polynomial.',
|
||||
)),
|
||||
('mjd_transitionFD',
|
||||
FunctionDecl(
|
||||
|
||||
@@ -1156,7 +1156,7 @@ char* mju_strncpy(char *dst, const char *src, int n) {
|
||||
|
||||
|
||||
|
||||
// Sigmoid function over 0<=x<=1 constructed from half-quadratics.
|
||||
// sigmoid function over 0<=x<=1 using quintic polynomial
|
||||
mjtNum mju_sigmoid(mjtNum x) {
|
||||
// fast return
|
||||
if (x<=0) {
|
||||
@@ -1165,15 +1165,8 @@ mjtNum mju_sigmoid(mjtNum x) {
|
||||
if (x>=1) {
|
||||
return 1;
|
||||
}
|
||||
if (x==0.5) {
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
// lower part
|
||||
if (x<0.5) {
|
||||
return 2*x*x;
|
||||
}
|
||||
|
||||
// higher part
|
||||
return (1 - 2*(1-x)*(1-x));
|
||||
// sigmoid: f(x) = 6*x^5 - 15*x^4 + 10*x^3
|
||||
// solution of f(0) = f'(0) = f''(0) = 0, f(1) = 1, f'(1) = f''(1) = 0
|
||||
return x*x*x * (3*x * (2*x - 5) + 10);
|
||||
}
|
||||
|
||||
@@ -123,10 +123,10 @@ MJAPI void mju_insertionSortInt(int* list, int n);
|
||||
// Halton sequence
|
||||
MJAPI mjtNum mju_Halton(int index, int base);
|
||||
|
||||
// Call strncpy, then set dst[n-1] = 0.
|
||||
// call strncpy, then set dst[n-1] = 0
|
||||
MJAPI char* mju_strncpy(char *dst, const char *src, int n);
|
||||
|
||||
// Sigmoid function over 0<=x<=1 constructed from half-quadratics.
|
||||
// sigmoid function over 0<=x<=1 using quintic polynomial
|
||||
MJAPI mjtNum mju_sigmoid(mjtNum x);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -18,12 +18,14 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <mujoco/mjdata.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
#include "src/engine/engine_util_misc.h"
|
||||
#include "test/fixture.h"
|
||||
|
||||
namespace mujoco {
|
||||
namespace {
|
||||
|
||||
using ::testing::HasSubstr;
|
||||
using ::testing::DoubleNear;
|
||||
|
||||
TEST_F(MujocoTest, PrintsMemoryWarning) {
|
||||
EXPECT_THAT(mju_warningText(mjWARN_CNSTRFULL, pow(2, 10)),
|
||||
@@ -42,5 +44,31 @@ TEST_F(MujocoTest, PrintsMemoryWarning) {
|
||||
HasSubstr("1073741825 bytes"));
|
||||
}
|
||||
|
||||
TEST_F(MujocoTest, Sigmoid) {
|
||||
// function values
|
||||
EXPECT_EQ(mju_sigmoid(-1), 0);
|
||||
EXPECT_EQ(mju_sigmoid(0), 0);
|
||||
EXPECT_EQ(mju_sigmoid(0.5), 0.5);
|
||||
EXPECT_EQ(mju_sigmoid(1), 1);
|
||||
EXPECT_EQ(mju_sigmoid(2), 1);
|
||||
|
||||
// epsilon for finite-differencing
|
||||
const mjtNum dx = 1e-7;
|
||||
|
||||
// derivative at 0
|
||||
mjtNum dy_dx_0 = (mju_sigmoid(0 + dx) - mju_sigmoid(0)) / dx;
|
||||
EXPECT_THAT(dy_dx_0, DoubleNear(0, dx));
|
||||
|
||||
// derivative at 1
|
||||
mjtNum dy_dx_1 = (mju_sigmoid(1) - mju_sigmoid(1 - dx)) / dx;
|
||||
EXPECT_THAT(dy_dx_1, DoubleNear(0, dx));
|
||||
|
||||
// derivative at 0.5
|
||||
const mjtNum x = 0.5;
|
||||
mjtNum dy_dx_0p5 = (mju_sigmoid(x + dx) - mju_sigmoid(x - dx)) / (2*dx);
|
||||
mjtNum expected = 30*x*x*x*x - 60*x*x*x + 30*x*x;
|
||||
EXPECT_THAT(dy_dx_0p5, DoubleNear(expected, dx));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace mujoco
|
||||
|
||||
Reference in New Issue
Block a user