Skip to content

Commit

Permalink
Add is_expanded and use it in Expand() to catch redundant calls (Robo…
Browse files Browse the repository at this point in the history
  • Loading branch information
soonho-tri authored Jul 3, 2019
1 parent 3b5ba55 commit 8f61d07
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 79 deletions.
1 change: 1 addition & 0 deletions common/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,7 @@ drake_cc_googletest(
deps = [
":essential",
":symbolic",
"//common/test_utilities:limit_malloc",
"//common/test_utilities:symbolic_test_util",
],
)
Expand Down
19 changes: 18 additions & 1 deletion common/symbolic_expression.cc
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,17 @@ bool Expression::is_polynomial() const {
return ptr_->is_polynomial();
}

bool Expression::is_expanded() const {
DRAKE_ASSERT(ptr_ != nullptr);
return ptr_->is_expanded();
}

Expression& Expression::set_expanded() {
DRAKE_ASSERT(ptr_ != nullptr);
ptr_->set_expanded();
return *this;
}

Polynomiald Expression::ToPolynomial() const {
DRAKE_ASSERT(ptr_ != nullptr);
return ptr_->ToPolynomial();
Expand Down Expand Up @@ -189,7 +200,13 @@ Expression Expression::EvaluatePartial(const Environment& env) const {

Expression Expression::Expand() const {
DRAKE_ASSERT(ptr_ != nullptr);
return ptr_->Expand();
if (ptr_->is_expanded()) {
// If it is already expanded, return the current expression without calling
// Expand() on the cell.
return *this;
} else {
return ptr_->Expand();
}
}

Expression Expression::Substitute(const Variable& var,
Expand Down
21 changes: 21 additions & 0 deletions common/symbolic_expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,17 @@ class Expression {
*/
Expression EvaluatePartial(const Environment& env) const;

/** Returns true if this symbolic expression is already
* expanded. Expression::Expand() uses this flag to avoid calling
* ExpressionCell::Expand() on an pre-expanded expressions.
* Expression::Expand() also sets this flag before returning the result.
*
* @note This check is conservative in that `false` does not always indicate
* that the expression is not expanded. This is because exact checks can be
* costly and we want to avoid the exact check at the construction time.
*/
bool is_expanded() const;

/** Expands out products and positive integer powers in expression. For
* example, `(x + 1) * (x - 1)` is expanded to `x^2 - 1` and `(x + y)^2` is
* expanded to `x^2 + 2xy + y^2`. Note that Expand applies recursively to
Expand Down Expand Up @@ -526,6 +537,13 @@ class Expression {
friend class ExpressionAddFactory;
friend class ExpressionMulFactory;

// The following classes call the private method `set_expand()` and need to be
// friends of this class.
friend class ExpressionAdd;
friend class ExpressionMul;
friend class ExpressionDiv;
friend class ExpressionPow;

private:
explicit Expression(std::shared_ptr<ExpressionCell> ptr);
void HashAppend(DelegatingHasher* hasher) const;
Expand All @@ -534,6 +552,9 @@ class Expression {
// destructive updates on the pointed cell if the cell is not shared with
// other Expressions (that is, ptr_.use_count() == 1).
std::shared_ptr<ExpressionCell> ptr_;

/** Sets this symbolic expression as already expanded. */
Expression& set_expanded();
};

Expression operator+(Expression lhs, const Expression& rhs);
Expand Down
Loading

0 comments on commit 8f61d07

Please sign in to comment.