Skip to content

Commit

Permalink
symbolic: ExtractDoubleOrThrow(NAN) should be NAN (RobotLocomotion#10773
Browse files Browse the repository at this point in the history
)

During transmogrification of a Context<Expression> to Context<double>,
the user may have placed NAN bombs in state variables or parameters
which should be unused by the computation in question (e.g., the
dynamics may not depend on some output-scaling parameter). In this
case, we should just faithfully convert the Expression NAN to a
double NAN, without throwing an exception.
  • Loading branch information
jwnimmer-tri authored Feb 27, 2019
1 parent d1e1c97 commit 404a6da
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 0 deletions.
8 changes: 8 additions & 0 deletions common/symbolic_expression.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,14 @@ Variables GetDistinctVariables(const Eigen::Ref<const MatrixX<Expression>>& v) {
} // namespace symbolic

double ExtractDoubleOrThrow(const symbolic::Expression& e) {
if (is_nan(e)) {
// If this was a literal NaN provided by the user or a dummy_value<T>, then
// it is sound to promote it as the "extracted value" during scalar
// conversion. (In contrast, if an expression tree includes a NaN term,
// then it's still desirable to throw an exception and we should NOT return
// NaN in that case.)
return std::numeric_limits<double>::quiet_NaN();
}
return e.Evaluate();
}

Expand Down
7 changes: 7 additions & 0 deletions common/test/symbolic_expression_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1927,6 +1927,13 @@ TEST_F(SymbolicExpressionTest, ExtractDoubleTest) {
// 2x - 7 -2x + 2 => -5
const Expression e3{2 * x_ - 7 - 2 * x_ + 2};
EXPECT_EQ(ExtractDoubleOrThrow(e3), -5);

// Literal NaN should come through without an exception during Extract.
EXPECT_TRUE(std::isnan(ExtractDoubleOrThrow(e_nan_)));

// Computed NaN should still throw.
const Expression bogus = zero_ / e_nan_;
EXPECT_THROW(ExtractDoubleOrThrow(bogus), std::exception);
}

TEST_F(SymbolicExpressionTest, Jacobian) {
Expand Down

0 comments on commit 404a6da

Please sign in to comment.