Skip to content

Commit bf38e2c

Browse files
committed
faster implementation of SO3 random
1 parent 70066d0 commit bf38e2c

File tree

2 files changed

+59
-32
lines changed

2 files changed

+59
-32
lines changed

include/manif/impl/se3/SE3_base.h

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -374,28 +374,41 @@ struct RandomEvaluatorImpl<SE3Base<Derived>>
374374
static void run(T& m)
375375
{
376376
// @note:
377+
// We are using:
378+
// http://mathworld.wolfram.com/HyperspherePointPicking.html
379+
// which is faster than Quaternion::UnitRandom, and also,
377380
// Quaternion::UnitRandom is not available in Eigen 3.3-beta1
378381
// which is the default version in Ubuntu 16.04
379-
// So we copy its implementation here.
380382

381383
using std::sqrt;
382-
using std::sin;
383-
using std::cos;
384-
385-
using Scalar = typename SE3Base<Derived>::Scalar;
386-
using Translation = typename SE3Base<Derived>::Translation;
387-
using Quaternion = typename SE3Base<Derived>::QuaternionDataType;
388-
389-
const Scalar u1 = Eigen::internal::random<Scalar>(0, 1),
390-
u2 = Eigen::internal::random<Scalar>(0, 2*EIGEN_PI),
391-
u3 = Eigen::internal::random<Scalar>(0, 2*EIGEN_PI);
392-
const Scalar a = sqrt(1. - u1),
393-
b = sqrt(u1);
394-
395-
m = Derived(Translation::Random(),
396-
Quaternion(a * sin(u2), a * cos(u2), b * sin(u3), b * cos(u3)));
397-
398-
//m = Derived(Translation::Random(), Quaternion::UnitRandom());
384+
using Scalar = typename SO3Base<Derived>::Scalar;
385+
using Quaternion = typename SO3Base<Derived>::QuaternionDataType;
386+
387+
while (true)
388+
{
389+
const Scalar u1 = Eigen::internal::random<Scalar>(-1, 1),
390+
u2 = Eigen::internal::random<Scalar>(-1, 1);
391+
if (u1 * u1 + u2 * u2 > 1.0)
392+
{
393+
continue;
394+
}
395+
396+
while (true)
397+
{
398+
const Scalar u3 = Eigen::internal::random<Scalar>(-1, 1),
399+
u4 = Eigen::internal::random<Scalar>(-1, 1);
400+
if (u3 * u3 + u4 * u4 > 1.0)
401+
{
402+
continue;
403+
}
404+
const Scalar zw_factor = sqrt((1 - u1 * u1 - u2 * u2) / (u3 * u3 + u4 * u4));
405+
const Scalar z = u3 * zw_factor;
406+
const Scalar w = u4 * zw_factor;
407+
m = Derived(Translation::Random(), Quaternion(u1, u2, z, w));
408+
break;
409+
}
410+
break;
411+
}
399412
}
400413
};
401414

include/manif/impl/so3/SO3_base.h

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -359,28 +359,42 @@ struct RandomEvaluatorImpl<SO3Base<Derived>>
359359
template <typename T>
360360
static void run(T& m)
361361
{
362-
363362
// @note:
363+
// We are using:
364+
// http://mathworld.wolfram.com/HyperspherePointPicking.html
365+
// which is faster than Quaternion::UnitRandom, and also,
364366
// Quaternion::UnitRandom is not available in Eigen 3.3-beta1
365367
// which is the default version in Ubuntu 16.04
366-
// So we copy its implementation here.
367368

368369
using std::sqrt;
369-
using std::sin;
370-
using std::cos;
371-
372370
using Scalar = typename SO3Base<Derived>::Scalar;
373371
using Quaternion = typename SO3Base<Derived>::QuaternionDataType;
374372

375-
const Scalar u1 = Eigen::internal::random<Scalar>(0, 1),
376-
u2 = Eigen::internal::random<Scalar>(0, 2*EIGEN_PI),
377-
u3 = Eigen::internal::random<Scalar>(0, 2*EIGEN_PI);
378-
const Scalar a = sqrt(1. - u1),
379-
b = sqrt(u1);
380-
m = Derived(Quaternion(a * sin(u2), a * cos(u2), b * sin(u3), b * cos(u3)));
381-
382-
383-
// m = Derived(Quaternion::UnitRandom());
373+
while (true)
374+
{
375+
const Scalar u1 = Eigen::internal::random<Scalar>(-1, 1),
376+
u2 = Eigen::internal::random<Scalar>(-1, 1);
377+
if (u1 * u1 + u2 * u2 > 1.0)
378+
{
379+
continue;
380+
}
381+
382+
while (true)
383+
{
384+
const Scalar u3 = Eigen::internal::random<Scalar>(-1, 1),
385+
u4 = Eigen::internal::random<Scalar>(-1, 1);
386+
if (u3 * u3 + u4 * u4 > 1.0)
387+
{
388+
continue;
389+
}
390+
const Scalar zw_factor = sqrt((1 - u1 * u1 - u2 * u2) / (u3 * u3 + u4 * u4));
391+
const Scalar z = u3 * zw_factor;
392+
const Scalar w = u4 * zw_factor;
393+
m = Derived(Quaternion(u1, u2, z, w));
394+
break;
395+
}
396+
break;
397+
}
384398
}
385399
};
386400

0 commit comments

Comments
 (0)