Skip to content

Commit

Permalink
Provide ExtractDoubleOrThrow for symbolic::Expression
Browse files Browse the repository at this point in the history
  • Loading branch information
soonho-tri committed Dec 14, 2017
1 parent f3569bb commit a11be7f
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 8 deletions.
1 change: 1 addition & 0 deletions common/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ drake_cc_library(
":cond",
":dummy_value",
":essential",
":extract_double",
":hash",
":number_traits",
":polynomial",
Expand Down
16 changes: 8 additions & 8 deletions common/extract_double.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ namespace drake {
/// Converts a ScalarType value to a double, failing at runtime (not compile
/// time) if the type cannot be converted to a double.
///
/// This function is useful for writing ScalarType-generic code that (1) is
/// only intended to be used on numeric types, (2) can reasonably discard any
/// supplemental scalar data, e.g., the derivatives of an AutoDiffScalar, and
/// (3) is reasonable to fail at runtime if called with a non-numeric
/// ScalarType.
/// This function is useful for writing ScalarType-generic code that (1) can
/// reasonably discard any supplemental scalar data, e.g., the derivatives of an
/// AutoDiffScalar, and (2) is reasonable to fail at runtime if the extraction
/// fails.
///
/// The default implementation throws an exception. ScalarTypes that are
/// numeric must overload this method to provide an appropriate extraction.
/// An overload for `double` is already provided.
/// The default implementation throws an exception. ScalarTypes that can hold a
/// numeric value must overload this method to provide an appropriate
/// extraction. An overload for `double` is already provided.
///
/// See autodiff_overloads.h to use this with Eigen's AutoDiffScalar.
/// See symbolic_expression.h to use this with symbolic::Expression.
/// See number_traits.h for specifying which ScalarTypes are numeric.
template <typename T>
double ExtractDoubleOrThrow(const T& scalar) {
Expand Down
5 changes: 5 additions & 0 deletions common/symbolic_expression.cc
Original file line number Diff line number Diff line change
Expand Up @@ -877,4 +877,9 @@ MatrixX<Expression> Jacobian(const Eigen::Ref<const VectorX<Expression>>& f,
return Jacobian(f, vector<Variable>(vars.data(), vars.data() + vars.size()));
}
} // namespace symbolic

double ExtractDoubleOrThrow(const symbolic::Expression& e) {
return e.Evaluate();
}

} // namespace drake
8 changes: 8 additions & 0 deletions common/symbolic_expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "drake/common/drake_copyable.h"
#include "drake/common/dummy_value.h"
#include "drake/common/eigen_types.h"
#include "drake/common/extract_double.h"
#include "drake/common/hash.h"
#include "drake/common/number_traits.h"
#include "drake/common/polynomial.h"
Expand Down Expand Up @@ -768,6 +769,13 @@ template <>
struct is_numeric<symbolic::Expression> {
static constexpr bool value = false;
};

/// Returns the symbolic expression's value() as a double.
///
/// @throws If it is not possible to evaluate the symbolic expression with an
/// empty environment.
double ExtractDoubleOrThrow(const symbolic::Expression& e);

} // namespace drake

namespace std {
Expand Down
14 changes: 14 additions & 0 deletions common/test/symbolic_expression_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1849,6 +1849,20 @@ TEST_F(SymbolicExpressionTest, MemcpyKeepsExpressionIntact) {
EXPECT_TRUE(IsMemcpyMovable(expr));
}
}

TEST_F(SymbolicExpressionTest, ExtractDoubleTest) {
const Expression e1{10.0};
EXPECT_EQ(ExtractDoubleOrThrow(e1), 10.0);

// 'x_' can't be converted to a double value.
const Expression e2{x_};
EXPECT_THROW(ExtractDoubleOrThrow(e2), std::exception);

// 2x - 7 -2x + 2 => -5
const Expression e3{2 * x_ - 7 - 2 * x_ + 2};
EXPECT_EQ(ExtractDoubleOrThrow(e3), -5);
}

} // namespace
} // namespace symbolic
} // namespace drake

0 comments on commit a11be7f

Please sign in to comment.