Skip to content

Commit

Permalink
[common] Extract core symbolic algebra into its own library (RobotLoc…
Browse files Browse the repository at this point in the history
…omotion#17419)

The vast majority of Drake code only uses the basic algebra of
Variable, Expression, and Formula; it does not use extra analysis on
top (polynomials, rationals, decomposition, simplification, etc.).

By carving out Expression (and closely-related classes) into its own
library, we can improve Drake's build times. Our pervasively-used
default scalars now only pull in the basic algebra support, not all of
the extra analysis code.

This commit both adds such a library, and updates Drake to use it
in cases where the extra code is not required.
  • Loading branch information
jwnimmer-tri authored Jun 27, 2022
1 parent af2d887 commit 9b0cc4b
Show file tree
Hide file tree
Showing 149 changed files with 570 additions and 464 deletions.
181 changes: 1 addition & 180 deletions common/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -207,22 +207,8 @@ drake_cc_library(
"symbolic_codegen.cc",
"symbolic_codegen.h",
"symbolic_decompose.cc",
"symbolic_environment.cc",
"symbolic_environment.h",
"symbolic_expression.cc",
"symbolic_expression.h",
"symbolic_expression_cell.cc",
"symbolic_expression_cell.h",
"symbolic_expression_visitor.h",
"symbolic_formula.cc",
"symbolic_formula.h",
"symbolic_formula_cell.cc",
"symbolic_formula_cell.h",
"symbolic_formula_visitor.h",
"symbolic_generic_polynomial.cc",
"symbolic_generic_polynomial.h",
"symbolic_ldlt.cc",
"symbolic_ldlt.h",
"symbolic_monomial.cc",
"symbolic_monomial.h",
"symbolic_monomial_basis_element.cc",
Expand All @@ -238,10 +224,6 @@ drake_cc_library(
"symbolic_rational_function.h",
"symbolic_simplification.cc",
"symbolic_simplification.h",
"symbolic_variable.cc",
"symbolic_variable.h",
"symbolic_variables.cc",
"symbolic_variables.h",
],
hdrs = [
"symbolic.h",
Expand All @@ -258,6 +240,7 @@ drake_cc_library(
":extract_double",
":hash",
":random",
"//common/symbolic:expression",
"@fmt",
],
)
Expand Down Expand Up @@ -1146,93 +1129,6 @@ drake_cc_googletest(
],
)

drake_cc_googletest(
name = "symbolic_environment_test",
deps = [
":essential",
":symbolic",
],
)

drake_cc_googletest(
name = "symbolic_expansion_test",
deps = [
":essential",
":symbolic",
"//common/test_utilities:limit_malloc",
"//common/test_utilities:symbolic_test_util",
],
)

drake_cc_googletest(
name = "symbolic_expression_test",
deps = [
":essential",
":polynomial",
":symbolic",
"//common/test_utilities:eigen_matrix_compare",
"//common/test_utilities:is_memcpy_movable",
"//common/test_utilities:symbolic_test_util",
],
)

drake_cc_googletest(
name = "symbolic_expression_cell_test",
deps = [
":essential",
":symbolic",
"//common/test_utilities:symbolic_test_util",
],
)

drake_cc_googletest(
name = "symbolic_expression_differentiation_test",
deps = [
":essential",
":symbolic",
"//common/test_utilities:symbolic_test_util",
],
)

drake_cc_googletest(
name = "symbolic_expression_jacobian_test",
deps = [
":essential",
":symbolic",
"//common/test_utilities:symbolic_test_util",
],
)

drake_cc_googletest(
name = "symbolic_expression_array_test",
deps = [
":essential",
":symbolic",
"//common/test_utilities:symbolic_test_util",
],
)

drake_cc_googletest(
name = "symbolic_expression_matrix_test",
deps = [
":essential",
":symbolic",
"//common/test_utilities:eigen_matrix_compare",
"//common/test_utilities:expect_throws_message",
"//common/test_utilities:symbolic_test_util",
],
)

drake_cc_googletest(
name = "symbolic_expression_transform_test",
deps = [
":essential",
":symbolic",
"//common/test_utilities:eigen_matrix_compare",
"//math:geometric_transform",
],
)

drake_cc_googletest(
name = "symbolic_latex_test",
deps = [
Expand All @@ -1254,24 +1150,6 @@ drake_cc_googletest(
],
)

drake_cc_googletest(
name = "symbolic_ldlt_test",
deps = [
":essential",
":symbolic",
"//common/test_utilities:eigen_matrix_compare",
"//common/test_utilities:expect_no_throw",
],
)

drake_cc_googletest(
name = "symbolic_mixing_scalar_types_test",
deps = [
":essential",
":symbolic",
],
)

drake_cc_googletest(
name = "symbolic_polynomial_basis_element_test",
deps = [
Expand Down Expand Up @@ -1340,63 +1218,6 @@ drake_cc_googletest(
],
)

drake_cc_googletest(
name = "symbolic_substitution_test",
deps = [
":essential",
":symbolic",
"//common/test_utilities:symbolic_test_util",
],
)

drake_cc_googletest(
name = "symbolic_variable_overloading_test",
deps = [
":essential",
":symbolic",
"//common/test_utilities:expect_no_throw",
"//common/test_utilities:symbolic_test_util",
],
)

drake_cc_googletest(
name = "symbolic_formula_test",
deps = [
":essential",
":symbolic",
"//common/test_utilities:expect_no_throw",
"//common/test_utilities:is_memcpy_movable",
"//common/test_utilities:symbolic_test_util",
],
)

drake_cc_googletest(
name = "symbolic_formula_visitor_test",
deps = [
":essential",
":symbolic",
"//common/test_utilities:symbolic_test_util",
],
)

drake_cc_googletest(
name = "symbolic_variable_test",
deps = [
":essential",
":symbolic",
"//common/test_utilities:is_memcpy_movable",
"//common/test_utilities:symbolic_test_util",
],
)

drake_cc_googletest(
name = "symbolic_variables_test",
deps = [
":essential",
":symbolic",
],
)

drake_cc_googletest(
name = "temp_directory_test",
# Run each test case in a different process, to avoid environment variable
Expand Down
2 changes: 1 addition & 1 deletion common/autodiffxd_make_coherent.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include "drake/common/autodiff.h"
#include "drake/common/symbolic.h"
#include "drake/common/symbolic/expression.h"

namespace drake {

Expand Down
2 changes: 1 addition & 1 deletion common/default_scalars.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include "drake/common/autodiff.h"
#include "drake/common/symbolic.h"
#include "drake/common/symbolic/expression.h"

// N.B. `CommonScalarPack` and `NonSymbolicScalarPack` in `systems_pybind.h`
// should be kept in sync with this file.
Expand Down
2 changes: 1 addition & 1 deletion common/polynomial.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "drake/common/autodiff.h"
#include "drake/common/default_scalars.h"
#include "drake/common/drake_assert.h"
#include "drake/common/symbolic.h"
#include "drake/common/symbolic/expression.h"

namespace drake {
/** A scalar multi-variate polynomial, modeled after the msspoly in spotless.
Expand Down
2 changes: 1 addition & 1 deletion common/schema/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ drake_cc_library(
"//common:name_value",
"//common:nice_type_name",
"//common:random",
"//common:symbolic",
"//common:unused",
"//common/symbolic:expression",
],
)

Expand Down
2 changes: 1 addition & 1 deletion common/schema/stochastic.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include "drake/common/eigen_types.h"
#include "drake/common/name_value.h"
#include "drake/common/random.h"
#include "drake/common/symbolic.h"
#include "drake/common/symbolic/expression.h"

namespace drake {
namespace schema {
Expand Down
36 changes: 18 additions & 18 deletions common/symbolic.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
#pragma once

/// @file
/// Provides public header files of Drake's symbolic library.
/// A user of the symbolic library should only include this header file.
/// Including other individual headers such as symbolic_expression.h will
/// Provides public header files for the extended portion of Drake's symbolic
/// library that goes beyond the basic algebra (e.g., when using polynomials,
/// simplification, decomposition, etc.).
///
/// Many users will only need to use the "drake/common/symbolic/expression.h"
/// file instead of this one.
///
/// A user of the extended symbolic library should only include this header
/// file. Including other individual headers such as symbolic_polynomial.h will
/// generate a compile-time error.
///
/// Many symbolic types are not closed under the defined operations. For
/// example, relational operations (i.e. <) over symbolic::Expression produce
/// symbolic::Formula. Another example is addition (+) over Monomial which gives
/// Polynomial. If a user does not include the necessary set of header files,
/// he/she will get either 1) incomprehensible c++ errors or 2) undefined
/// runtime behaviors. The problem is trickier if we use symbolic objects via
/// Eigen.
/// Extended symbolic types are not closed under the defined operations. For
/// example, addition (+) over Monomial gives a Polynomial. If a user does not
/// include the necessary set of header files, he/she will get either
/// 1) incomprehensible c++ errors or 2) undefined runtime behaviors. The
/// problem is trickier if we use symbolic objects via Eigen.

// Add the basic algebra library, which is used by all of the below.
#include "drake/common/symbolic/expression.h"

// In each header included below, it asserts that this macro
// `DRAKE_COMMON_SYMBOLIC_HEADER` is defined. If the macro is not defined, it
Expand All @@ -29,12 +37,6 @@
// order-of-specialization-includes-changed mistakes.
//
// clang-format off
#include "drake/common/symbolic_variable.h"
#include "drake/common/symbolic_variables.h"
#include "drake/common/symbolic_environment.h"
#include "drake/common/symbolic_expression.h"
#include "drake/common/symbolic_expression_visitor.h"
#include "drake/common/symbolic_ldlt.h"
#include "drake/common/symbolic_monomial.h"
#include "drake/common/symbolic_monomial_util.h"
#include "drake/common/symbolic_polynomial.h"
Expand All @@ -45,8 +47,6 @@
#include "drake/common/symbolic_polynomial_basis.h"
#include "drake/common/symbolic_generic_polynomial.h"
#include "drake/common/symbolic_rational_function.h"
#include "drake/common/symbolic_formula.h"
#include "drake/common/symbolic_formula_visitor.h"
#include "drake/common/symbolic_simplification.h"
#include "drake/common/symbolic_codegen.h"
// clang-format on
Expand Down
34 changes: 34 additions & 0 deletions common/symbolic/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# -*- python -*-

load(
"@drake//tools/skylark:drake_cc.bzl",
"drake_cc_library",
"drake_cc_package_library",
)
load("//tools/lint:lint.bzl", "add_lint_tests")

package(default_visibility = ["//visibility:public"])

drake_cc_package_library(
name = "symbolic",
visibility = [
# TODO(jwnimmer-tri) Once we have moved all of the symbolic code from
# drake/common/* into drake/common/symbolic/*, then we should make this
# package library public. In the meantime, exposing it makes it too
# easy to typo "//common:symbolic" vs "//common/symbolic".
"//visibility:private",
],
deps = [
":expression",
],
)

drake_cc_library(
name = "expression",
hdrs = ["expression.h"],
deps = [
"//common/symbolic/expression",
],
)

add_lint_tests()
10 changes: 10 additions & 0 deletions common/symbolic/expression.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

/// @file
/// When using Drake's symbolic expressions library (e.g., the classes
/// drake::symbolic::Expression or drake::symbolic::Formula), we provide
/// a single include statement to cover all of he requied classes:
/// `#include <drake/common/symbolic/expression.h>`.

// Delegate the internal implementation details to our subdirectory.
#include "drake/common/symbolic/expression/all.h"
Loading

0 comments on commit 9b0cc4b

Please sign in to comment.