forked from pz4kybsvg/Conception
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
295 lines
8.8 KiB
295 lines
8.8 KiB
#include "drake/common/drake_bool.h"
|
|
|
|
#include <utility>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "drake/common/autodiff.h"
|
|
#include "drake/common/symbolic/expression.h"
|
|
#include "drake/common/test_utilities/symbolic_test_util.h"
|
|
|
|
namespace drake {
|
|
|
|
using std::move;
|
|
|
|
using symbolic::Expression;
|
|
using symbolic::Formula;
|
|
using symbolic::Variable;
|
|
using symbolic::test::ExprEqual;
|
|
using symbolic::test::FormulaEqual;
|
|
|
|
// ---------------
|
|
// Case T = double
|
|
// ---------------
|
|
class BoolTestDouble : public ::testing::Test {
|
|
protected:
|
|
void SetUp() override {
|
|
// clang-format off
|
|
m_ << 1, 2,
|
|
3, 4;
|
|
// clang-format on
|
|
}
|
|
|
|
MatrixX<double> m_{2, 2};
|
|
MatrixX<double> zero_m_{0, 0};
|
|
};
|
|
|
|
TEST_F(BoolTestDouble, TypeCheck) {
|
|
static_assert(std::is_same_v<boolean<double>, bool>,
|
|
"boolean<double> should be bool");
|
|
static_assert(std::is_same_v<scalar_predicate<double>::type, bool>,
|
|
"scalar_predicate<double>::type should be bool");
|
|
static_assert(scalar_predicate<double>::is_bool,
|
|
"scalar_predicate<double>::is_bool should be true");
|
|
}
|
|
|
|
TEST_F(BoolTestDouble, All) {
|
|
auto bools = Eigen::Matrix<bool, 3, 3>::Constant(true).eval();
|
|
EXPECT_TRUE(drake::all(bools));
|
|
bools(0, 0) = false;
|
|
EXPECT_FALSE(drake::all(bools));
|
|
|
|
// Vacuously true.
|
|
EXPECT_TRUE(drake::all(Eigen::Matrix<bool, 0, 0>::Constant(false)));
|
|
}
|
|
|
|
TEST_F(BoolTestDouble, AllOf) {
|
|
EXPECT_TRUE(all_of(m_, [](const double v) { return v >= 0.0; }));
|
|
EXPECT_FALSE(all_of(m_, [](const double v) { return v >= 2.0; }));
|
|
|
|
// Vacuously true.
|
|
EXPECT_TRUE(all_of(zero_m_, [](const double v) { return v >= 0.0; }));
|
|
}
|
|
|
|
TEST_F(BoolTestDouble, Any) {
|
|
auto bools = Eigen::Matrix<bool, 3, 3>::Constant(false).eval();
|
|
EXPECT_FALSE(any(bools));
|
|
bools(0, 0) = true;
|
|
EXPECT_TRUE(any(bools));
|
|
|
|
// Vacuously false.
|
|
EXPECT_FALSE(any(Eigen::Matrix<bool, 0, 0>::Constant(true)));
|
|
}
|
|
|
|
TEST_F(BoolTestDouble, AnyOf) {
|
|
EXPECT_TRUE(any_of(m_, [](const double v) { return v >= 4.0; }));
|
|
EXPECT_FALSE(any_of(m_, [](const double v) { return v >= 5.0; }));
|
|
|
|
// Vacuously false.
|
|
EXPECT_FALSE(
|
|
any_of(zero_m_, [](const double v) { return v >= 0.0; }));
|
|
}
|
|
|
|
TEST_F(BoolTestDouble, None) {
|
|
auto bools = Eigen::Matrix<bool, 3, 3>::Constant(false).eval();
|
|
EXPECT_TRUE(none(bools));
|
|
bools(0, 0) = true;
|
|
EXPECT_FALSE(none(bools));
|
|
|
|
// Vacuously true.
|
|
EXPECT_TRUE(none(Eigen::Matrix<bool, 0, 0>::Constant(true)));
|
|
}
|
|
|
|
TEST_F(BoolTestDouble, NoneOf) {
|
|
EXPECT_TRUE(none_of(m_, [](const double v) { return v >= 5.0; }));
|
|
EXPECT_FALSE(none_of(m_, [](const double v) { return v >= 4.0; }));
|
|
|
|
// Vacuously true.
|
|
EXPECT_TRUE(
|
|
none_of(zero_m_, [](const double v) { return v >= 0.0; }));
|
|
}
|
|
|
|
// -------------------
|
|
// Case T = AutoDiffXd
|
|
// -------------------
|
|
class BoolTestAutoDiffXd : public ::testing::Test {
|
|
protected:
|
|
void SetUp() override {
|
|
m_(0, 0) = AutoDiffXd{1., Eigen::Vector2d{1., 0.}};
|
|
m_(0, 1) = AutoDiffXd{0., Eigen::Vector2d{1., 0.}};
|
|
m_(1, 0) = AutoDiffXd{0., Eigen::Vector2d{0., 1.}};
|
|
m_(1, 1) = AutoDiffXd{1., Eigen::Vector2d{0., 1.}};
|
|
}
|
|
|
|
MatrixX<AutoDiffXd> m_{2, 2};
|
|
MatrixX<AutoDiffXd> zero_m_{0, 0};
|
|
};
|
|
|
|
TEST_F(BoolTestAutoDiffXd, TypeCheck) {
|
|
static_assert(std::is_same_v<boolean<AutoDiffXd>, bool>,
|
|
"boolean<AutoDiffXd> should be bool");
|
|
static_assert(std::is_same_v<scalar_predicate<AutoDiffXd>::type, bool>,
|
|
"scalar_predicate<AutoDiffXd>::type should be bool");
|
|
static_assert(scalar_predicate<AutoDiffXd>::is_bool,
|
|
"scalar_predicate<AutoDiffXd>::is_bool should be true");
|
|
}
|
|
|
|
TEST_F(BoolTestAutoDiffXd, AllOf) {
|
|
EXPECT_TRUE(all_of(m_,
|
|
[](const AutoDiffXd& v) {
|
|
return v.derivatives()[0] == 1.0 ||
|
|
v.derivatives()[1] == 1.0;
|
|
}));
|
|
EXPECT_FALSE(
|
|
all_of(m_, [](const AutoDiffXd& v) { return v >= 1.0; }));
|
|
|
|
// Vacuously true.
|
|
EXPECT_TRUE(
|
|
all_of(zero_m_, [](const AutoDiffXd& v) { return v >= 1.0; }));
|
|
}
|
|
|
|
TEST_F(BoolTestAutoDiffXd, AnyOf) {
|
|
EXPECT_TRUE(any_of(m_,
|
|
[](const AutoDiffXd& v) {
|
|
return v.derivatives()[0] == 1.0 &&
|
|
v.derivatives()[1] == 0.0;
|
|
}));
|
|
EXPECT_FALSE(any_of(m_,
|
|
[](const AutoDiffXd& v) {
|
|
return v.derivatives()[0] == 1.0 &&
|
|
v.derivatives()[1] == 1.0;
|
|
}));
|
|
|
|
// Vacuously false.
|
|
EXPECT_FALSE(
|
|
any_of(zero_m_, [](const AutoDiffXd& v) { return v >= 1.0; }));
|
|
}
|
|
|
|
TEST_F(BoolTestAutoDiffXd, NoneOf) {
|
|
EXPECT_TRUE(none_of(m_,
|
|
[](const AutoDiffXd& v) {
|
|
return v.derivatives()[0] == 1.0 &&
|
|
v.derivatives()[1] == 1.0;
|
|
}));
|
|
EXPECT_FALSE(none_of(m_,
|
|
[](const AutoDiffXd& v) {
|
|
return v.derivatives()[0] == 1.0 &&
|
|
v.derivatives()[1] == 0.0;
|
|
}));
|
|
|
|
// Vacuously true.
|
|
EXPECT_TRUE(
|
|
none_of(zero_m_, [](const AutoDiffXd& v) { return v >= 1.0; }));
|
|
}
|
|
|
|
// -----------------------------
|
|
// Case T = symbolic::Expression
|
|
// -----------------------------
|
|
class BoolTestSymbolic : public ::testing::Test {
|
|
protected:
|
|
void SetUp() override {
|
|
// clang-format off
|
|
m_ << x_, y_,
|
|
z_, w_;
|
|
// clang-format on
|
|
}
|
|
|
|
const Variable x_{"x"};
|
|
const Variable y_{"y"};
|
|
const Variable z_{"z"};
|
|
const Variable w_{"w"};
|
|
MatrixX<Expression> m_{2, 2};
|
|
MatrixX<Expression> zero_m_{0, 0};
|
|
};
|
|
|
|
TEST_F(BoolTestSymbolic, TypeCheck) {
|
|
static_assert(
|
|
std::is_same_v<boolean<Expression>, Formula>,
|
|
"boolean<Expression> should be Formula");
|
|
static_assert(
|
|
std::is_same_v<scalar_predicate<Expression>::type, Formula>,
|
|
"scalar_predicate<Expression>::type should be Formula");
|
|
static_assert(
|
|
!scalar_predicate<Expression>::is_bool,
|
|
"scalar_predicate<Expression>::is_bool should be false");
|
|
}
|
|
|
|
TEST_F(BoolTestSymbolic, All) {
|
|
const MatrixX<Formula> formulae = m_.unaryExpr(&symbolic::isnan);
|
|
EXPECT_PRED2(FormulaEqual, all(formulae),
|
|
isnan(x_) && isnan(y_) && isnan(z_) && isnan(w_));
|
|
|
|
// Vacuously true.
|
|
EXPECT_TRUE(drake::all(MatrixX<Formula>::Constant(0, 0, Formula::False())));
|
|
}
|
|
|
|
TEST_F(BoolTestSymbolic, AllOf) {
|
|
EXPECT_PRED2(
|
|
FormulaEqual,
|
|
all_of(m_, [](const Expression& v) { return !isnan(v); }),
|
|
!isnan(x_) && !isnan(y_) && !isnan(z_) && !isnan(w_));
|
|
|
|
// Vacuously true.
|
|
EXPECT_TRUE(
|
|
all_of(zero_m_, [](const Expression& v) { return v >= 0.0; }));
|
|
}
|
|
|
|
TEST_F(BoolTestSymbolic, Any) {
|
|
const MatrixX<Formula> formulae = m_.unaryExpr(&symbolic::isnan);
|
|
EXPECT_PRED2(FormulaEqual, any(formulae),
|
|
isnan(x_) || isnan(y_) || isnan(z_) || isnan(w_));
|
|
|
|
// Vacuously false.
|
|
EXPECT_FALSE(any(MatrixX<Formula>::Constant(0, 0, Formula::True())));
|
|
}
|
|
|
|
TEST_F(BoolTestSymbolic, AnyOf) {
|
|
EXPECT_PRED2(FormulaEqual,
|
|
any_of(m_, [](const Expression& v) { return isnan(v); }),
|
|
isnan(x_) || isnan(y_) || isnan(z_) || isnan(w_));
|
|
|
|
// Vacuously false.
|
|
EXPECT_FALSE(
|
|
any_of(zero_m_, [](const Expression& v) { return v >= 0.0; }));
|
|
}
|
|
|
|
TEST_F(BoolTestSymbolic, None) {
|
|
const MatrixX<Formula> formulae = m_.unaryExpr(&symbolic::isnan);
|
|
EXPECT_PRED2(FormulaEqual, none(formulae),
|
|
!isnan(x_) && !isnan(y_) && !isnan(z_) && !isnan(w_));
|
|
|
|
// Vacuously true.
|
|
EXPECT_TRUE(none(MatrixX<Formula>::Constant(0, 0, Formula::False())));
|
|
}
|
|
|
|
TEST_F(BoolTestSymbolic, NoneOf) {
|
|
EXPECT_PRED2(
|
|
FormulaEqual,
|
|
none_of(m_, [](const Expression& v) { return isnan(v); }),
|
|
!isnan(x_) && !isnan(y_) && !isnan(z_) && !isnan(w_));
|
|
|
|
// Vacuously true.
|
|
EXPECT_TRUE(
|
|
none_of(zero_m_, [](const Expression& v) { return v >= 0.0; }));
|
|
}
|
|
|
|
GTEST_TEST(IfThenElseTest, VectorX) {
|
|
const bool predicate = true;
|
|
const Eigen::VectorXd a = Eigen::Vector3d(1.0, 2.0, 3.0);
|
|
const Eigen::VectorXd b = Eigen::Vector3d(4.0, 5.0, 6.0);
|
|
const Eigen::VectorXd result = if_then_else(predicate, a, b);
|
|
ASSERT_EQ(result.size(), 3);
|
|
EXPECT_EQ(result[0], 1.0);
|
|
EXPECT_EQ(result[1], 2.0);
|
|
EXPECT_EQ(result[2], 3.0);
|
|
}
|
|
|
|
GTEST_TEST(IfThenElseTest, Vector3) {
|
|
const bool predicate = false;
|
|
const Eigen::Vector3d a = Eigen::Vector3d(1.0, 2.0, 3.0);
|
|
const Eigen::Vector3d b = Eigen::Vector3d(4.0, 5.0, 6.0);
|
|
const Eigen::Vector3d result = if_then_else(predicate, a, b);
|
|
EXPECT_EQ(result[0], 4.0);
|
|
EXPECT_EQ(result[1], 5.0);
|
|
EXPECT_EQ(result[2], 6.0);
|
|
}
|
|
|
|
GTEST_TEST(IfThenElseTest, VectorBad) {
|
|
const bool predicate = true;
|
|
const Eigen::VectorXd a = Eigen::VectorXd::Zero(2);
|
|
const Eigen::VectorXd b = Eigen::VectorXd::Zero(3);
|
|
EXPECT_THROW(if_then_else(predicate, a, b), std::exception);
|
|
}
|
|
|
|
} // namespace drake
|