Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 73de88502144
Choose a base ref
...
head repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 8958d13c5251
Choose a head ref
  • 8 commits
  • 7 files changed
  • 2 contributors

Commits on Aug 19, 2020

  1. ToMathematica for polynomials.

    pleroy committed Aug 19, 2020
    Copy the full SHA
    83afb1d View commit details
  2. Add SetDelayed.

    pleroy committed Aug 19, 2020
    Copy the full SHA
    ad86f43 View commit details
  3. Copy the full SHA
    efb8702 View commit details
  4. Expectation.

    pleroy committed Aug 19, 2020
    Copy the full SHA
    984c772 View commit details

Commits on Aug 20, 2020

  1. Lint.

    pleroy committed Aug 20, 2020
    Copy the full SHA
    e6c50ac View commit details
  2. Copy the full SHA
    a9d6221 View commit details
  3. Copy the full SHA
    dd3136f View commit details
  4. Merge pull request #2683 from pleroy/ToMathematica

    ToMathematica for polynomials and (not quite) Poisson series
    pleroy authored Aug 20, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    8958d13 View commit details
Showing with 284 additions and 5 deletions.
  1. +9 −0 base/macros.hpp
  2. +25 −2 mathematica/mathematica.hpp
  3. +72 −2 mathematica/mathematica_body.hpp
  4. +117 −0 mathematica/mathematica_test.cpp
  5. +26 −0 numerics/poisson_series.hpp
  6. +34 −0 numerics/polynomial.hpp
  7. +1 −1 numerics/polynomial_body.hpp
9 changes: 9 additions & 0 deletions base/macros.hpp
Original file line number Diff line number Diff line change
@@ -186,5 +186,14 @@ template_and_class_key declared_name; \
} \
using internal_##package_name::declared_name

#define FORWARD_DECLARE_FUNCTION_FROM(package_name, \
template_and_result, \
declared_name, \
parameters) \
namespace internal_##package_name { \
template_and_result declared_name parameters; \
} \
using internal_##package_name::declared_name

} // namespace base
} // namespace principia
27 changes: 25 additions & 2 deletions mathematica/mathematica.hpp
Original file line number Diff line number Diff line change
@@ -18,6 +18,8 @@
#include "geometry/r3x3_matrix.hpp"
#include "geometry/symmetric_bilinear_form.hpp"
#include "numerics/fixed_arrays.hpp"
#include "numerics/poisson_series.hpp"
#include "numerics/polynomial.hpp"
#include "physics/degrees_of_freedom.hpp"
#include "quantities/elementary_functions.hpp"
#include "quantities/quantities.hpp"
@@ -37,6 +39,8 @@ using geometry::R3x3Matrix;
using geometry::SymmetricBilinearForm;
using geometry::Vector;
using numerics::FixedVector;
using numerics::PoissonSeries;
using numerics::PolynomialInMonomialBasis;
using physics::DegreesOfFreedom;
using quantities::Amount;
using quantities::Angle;
@@ -92,16 +96,22 @@ class ExpressIn {
std::tuple<Qs...> units_;
};

// TODO(phl): Rename this function to Rule.
template<typename T, typename OptionalExpressIn = std::nullopt_t>
std::string Option(std::string const& name,
T const& right,
OptionalExpressIn express_in = std::nullopt);

// TODO(phl): Rename this function to Set.
template<typename T, typename OptionalExpressIn = std::nullopt_t>
std::string Assign(std::string const& name,
T const& right,
OptionalExpressIn express_in = std::nullopt);

template<typename T, typename OptionalExpressIn = std::nullopt_t>
std::string Function(T const& body,
OptionalExpressIn express_in = std::nullopt);

template<typename T, typename U, typename OptionalExpressIn = std::nullopt_t>
std::string PlottableDataset(std::vector<T> const& x,
std::vector<U> const& y,
@@ -168,8 +178,7 @@ template<typename V, typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(Point<V> const& point,
OptionalExpressIn express_in = std::nullopt);

template<typename S,
typename F,
template<typename S, typename F,
template<typename, typename> typename M,
typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(SymmetricBilinearForm<S, F, M> const& form,
@@ -192,6 +201,19 @@ template<typename R,
std::string ToMathematica(R ref,
OptionalExpressIn express_in = std::nullopt);

template<typename V, typename A, int d,
template<typename, typename, int> class E,
typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(
PolynomialInMonomialBasis<V, A, d, E> const& polynomial,
OptionalExpressIn express_in = std::nullopt);

template<typename V, int d,
template<typename, typename, int> class E,
typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(PoissonSeries<V, d, E> const& series,
OptionalExpressIn express_in = std::nullopt);

template<typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(
astronomy::OrbitalElements::EquinoctialElements const& elements,
@@ -244,6 +266,7 @@ class Logger final {

using internal_mathematica::Assign;
using internal_mathematica::ExpressIn;
using internal_mathematica::Function;
using internal_mathematica::Logger;
using internal_mathematica::Option;
using internal_mathematica::PlottableDataset;
74 changes: 72 additions & 2 deletions mathematica/mathematica_body.hpp
Original file line number Diff line number Diff line change
@@ -10,13 +10,15 @@
#include <vector>

#include "base/not_constructible.hpp"
#include "base/traits.hpp"
#include "quantities/si.hpp"

namespace principia {
namespace mathematica {
namespace internal_mathematica {

using astronomy::J2000;
using base::is_instance_of_v;
using base::not_constructible;
using base::not_null;
using quantities::DebugString;
@@ -124,6 +126,12 @@ std::string Assign(std::string const& name,
return Apply("Set", {name, ToMathematica(right, express_in)}) + ";\n";
}

template<typename T, typename OptionalExpressIn>
std::string Function(T const& body,
OptionalExpressIn express_in) {
return Apply("Function", {ToMathematica(body, express_in)}) + ";\n";
}

template<typename T, typename U, typename OptionalExpressIn>
std::string PlottableDataset(std::vector<T> const& x,
std::vector<U> const& y,
@@ -256,8 +264,7 @@ std::string ToMathematica(Point<V> const & point,
return ToMathematica(point - Point<V>(), express_in);
}

template<typename S,
typename F,
template<typename S, typename F,
template<typename, typename> typename M,
typename OptionalExpressIn>
std::string ToMathematica(SymmetricBilinearForm<S, F, M> const& form,
@@ -293,6 +300,69 @@ std::string ToMathematica(R const ref,
ToMathematica(ref.degrees_of_freedom, express_in)});
}

template<typename V, typename A, int d,
template<typename, typename, int> class E,
typename OptionalExpressIn>
std::string ToMathematica(
PolynomialInMonomialBasis<V, A, d, E> const& polynomial,
OptionalExpressIn express_in) {
using Coefficients =
typename PolynomialInMonomialBasis<V, A, d, E>::Coefficients;
std::vector<std::string> coefficients;
coefficients.reserve(std::tuple_size_v<Coefficients>);
TupleHelper<std::tuple_size_v<Coefficients>,
Coefficients,
OptionalExpressIn>::ToMathematicaStrings(polynomial.coefficients_,
coefficients,
express_in);
std::string argument;
if constexpr (is_instance_of_v<Point, A>) {
argument =
Apply("Subtract", {"#", ToMathematica(polynomial.origin_, express_in)});
} else {
argument = "#";
}
std::vector<std::string> monomials;
for (int i = 0; i < coefficients.size(); ++i) {
if (i == 0) {
monomials.push_back(coefficients[i]);
} else if (i == 1) {
monomials.push_back(Apply("Times", {coefficients[i], argument}));
} else {
monomials.push_back(Apply(
"Times",
{coefficients[i], Apply("Power", {argument, std::to_string(i)})}));
}
}
return Apply("Plus", monomials);
}

template<typename V, int d,
template<typename, typename, int> class E,
typename OptionalExpressIn>
std::string ToMathematica(PoissonSeries<V, d, E> const& series,
std::string const& variable,
OptionalExpressIn express_in) {
std::vector<std::string> components = {
ToMathematica(series.aperiodic_, variable, express_in)};
for (auto const& [ω, polynomials] : series.periodic_) {
std::string const polynomial_sin =
ToMathematica(polynomials.sin, variable, express_in);
std::string const polynomial_cos =
ToMathematica(polynomials.cos, variable, express_in);
std::string const angle =
Apply("Times",
{ToMathematica(ω, express_in),
Apply("Subtract",
{variable, ToMathematica(series.origin_, express_in)})});
components.push_back(Apply("Times",
{polynomial_sin, Apply("Sin", {angle})}));
components.push_back(Apply("Times",
{polynomial_cos, Apply("Cos", {angle})}));
}
return Apply("Plus", components);
}

template<typename OptionalExpressIn>
std::string ToMathematica(
astronomy::OrbitalElements::EquinoctialElements const& elements,
117 changes: 117 additions & 0 deletions mathematica/mathematica_test.cpp
Original file line number Diff line number Diff line change
@@ -15,6 +15,9 @@
#include "geometry/symmetric_bilinear_form.hpp"
#include "gtest/gtest.h"
#include "numerics/fixed_arrays.hpp"
#include "numerics/poisson_series.hpp"
#include "numerics/polynomial.hpp"
#include "numerics/polynomial_evaluators.hpp"
#include "physics/degrees_of_freedom.hpp"
#include "physics/discrete_trajectory.hpp"
#include "quantities/quantities.hpp"
@@ -36,9 +39,14 @@ using geometry::SymmetricBilinearForm;
using geometry::Vector;
using geometry::Velocity;
using numerics::FixedVector;
using numerics::HornerEvaluator;
using numerics::PoissonSeries;
using numerics::PolynomialInMonomialBasis;
using physics::DegreesOfFreedom;
using physics::DiscreteTrajectory;
using quantities::Length;
using quantities::Speed;
using quantities::Time;
using quantities::si::Degree;
using quantities::si::Metre;
using quantities::si::Radian;
@@ -284,6 +292,103 @@ TEST_F(MathematicaTest, ToMathematica) {
"SetPrecision[+8.00000000000000000*^+00,$MachinePrecision]]",
ToMathematica(elements));
}
{
PolynomialInMonomialBasis<Length, Time, 2, HornerEvaluator> polynomial1(
{2 * Metre, -3 * Metre / Second, 4 * Metre / Second / Second});
EXPECT_EQ(
"Plus["
"Quantity["
"SetPrecision[+2.00000000000000000*^+00,$MachinePrecision],"
"\" m\"],"
"Times["
"Quantity["
"SetPrecision[-3.00000000000000000*^+00,$MachinePrecision],"
"\" m s^-1\"],"
"#],"
"Times["
"Quantity["
"SetPrecision[+4.00000000000000000*^+00,$MachinePrecision],"
"\" m s^-2\"],"
"Power["
"#,"
"2]]]",
ToMathematica(polynomial1));
PolynomialInMonomialBasis<Length, Instant, 2, HornerEvaluator> polynomial2(
{5 * Metre, 6 * Metre / Second, -7 * Metre / Second / Second},
Instant() + 2 * Second);
EXPECT_EQ(
"Plus["
"Quantity["
"SetPrecision[+5.00000000000000000*^+00,$MachinePrecision],"
"\" m\"],"
"Times["
"Quantity["
"SetPrecision[+6.00000000000000000*^+00,$MachinePrecision],"
"\" m s^-1\"],"
"Subtract["
"#,"
"Quantity["
"SetPrecision[+2.00000000000000000*^+00,$MachinePrecision],"
"\" s\"]]],"
"Times["
"Quantity["
"SetPrecision[-7.00000000000000000*^+00,$MachinePrecision],"
"\" m s^-2\"],"
"Power["
"Subtract["
"#,"
"Quantity["
"SetPrecision[+2.00000000000000000*^+00,$MachinePrecision],"
"\" s\"]],"
"2]]]",
ToMathematica(polynomial2));
}
#if !PRINCIPIA_COMPILER_MSVC
// This test does not compile with MSVC 16.6.3: it thinks that operators + and
// - on polynomials are ambiguous deep in the constructor of PoissonSeries.
// But don't despair, because the exact same code compiled in a different
// place (frequency_analysis_test.cpp) works like a charm...
{
using Series = PoissonSeries<double, 0, HornerEvaluator>;
Instant const t0 = Instant() + 3 * Second;
Series series(Series::Polynomial({1.5}, t0),
{{4 * Radian / Second,
{/*sin=*/Series::Polynomial({0.5}, t0),
/*cos=*/Series::Polynomial({-1}, t0)}}});
EXPECT_EQ(
"Plus["
"Plus["
"SetPrecision[+1.50000000000000000*^+00,$MachinePrecision]],"
"Times["
"Plus["
"SetPrecision[+5.00000000000000000*^-01,$MachinePrecision]],"
"Sin["
"Times["
"Quantity["
"SetPrecision["
"+4.00000000000000000*^+00,$MachinePrecision],"
"\" s^-1 rad\"],"
"Subtract["
"#,"
"Quantity["
"SetPrecision[+3.00000000000000000*^+00,$MachinePrecision],"
"\" s\"]]]]],"
"Times["
"Plus["
"SetPrecision[-1.00000000000000000*^+00,$MachinePrecision]],"
"Cos["
"Times["
"Quantity["
"SetPrecision[+4.00000000000000000*^+00,$MachinePrecision],"
"\" s^-1 rad\"],"
"Subtract["
"#,"
"Quantity["
"SetPrecision[+3.00000000000000000*^+00,$MachinePrecision],"
"\" s\"]]]]]]",
ToMathematica(series));
}
#endif
{
std::optional<std::string> opt1;
std::optional<std::string> opt2("foo");
@@ -311,6 +416,18 @@ TEST_F(MathematicaTest, Assign) {
Assign("var", 3.0));
}

TEST_F(MathematicaTest, Function) {
PolynomialInMonomialBasis<double, double, 1, HornerEvaluator> polynomial(
{1, -3});
EXPECT_EQ(
"Function["
"Plus["
"SetPrecision[+1.00000000000000000*^+00,$MachinePrecision],"
"Times[SetPrecision[-3.00000000000000000*^+00,$MachinePrecision],"
"#]]];\n",
Function(polynomial));
}

TEST_F(MathematicaTest, PlottableDataset) {
EXPECT_EQ(
"Transpose["
26 changes: 26 additions & 0 deletions numerics/poisson_series.hpp
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@

#include <algorithm>
#include <map>
#include <string>
#include <vector>

#include "geometry/interval.hpp"
@@ -12,6 +13,25 @@
#include "quantities/quantities.hpp"

namespace principia {
namespace numerics {
FORWARD_DECLARE_FROM(poisson_series,
TEMPLATE(typename Value, int degree_,
template<typename, typename, int> class Evaluator)
class,
PoissonSeries);
} // namespace numerics

namespace mathematica {
FORWARD_DECLARE_FUNCTION_FROM(
mathematica,
TEMPLATE(typename Value, int degree_,
template<typename, typename, int> class Evaluator,
typename OptionalExpressIn) std::string,
ToMathematica,
(numerics::PoissonSeries<Value, degree_, Evaluator> const& series,
OptionalExpressIn express_in));
} // namespace mathematica

namespace numerics {
namespace internal_poisson_series {

@@ -105,6 +125,12 @@ class PoissonSeries {
template<typename V, int d, template<typename, typename, int> class E>
friend std::ostream& operator<<(std::ostream& out,
PoissonSeries<V, d, E> const& series);
template<typename V, int d,
template<typename, typename, int> class E,
typename O>
friend std::string mathematica::ToMathematica(
PoissonSeries<V, d, E> const& polynomial,
O express_in);
};

// Vector space of Poisson series.
Loading