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: 63c389a002b9
Choose a base ref
...
head repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a403ffc54a1e
Choose a head ref
  • 16 commits
  • 7 files changed
  • 1 contributor

Commits on Apr 25, 2020

  1. Copy the full SHA
    6801494 View commit details
  2. Copy the full SHA
    7c99138 View commit details
  3. A statically typed attempt.

    pleroy committed Apr 25, 2020
    Copy the full SHA
    f6e10c3 View commit details
  4. Copy the full SHA
    8e96f49 View commit details
  5. Copy the full SHA
    bc24792 View commit details
  6. Trajectories.

    pleroy committed Apr 25, 2020
    Copy the full SHA
    ed2463c View commit details
  7. Support for tuples.

    pleroy committed Apr 25, 2020
    Copy the full SHA
    265bdfa View commit details
  8. Assertion.

    pleroy committed Apr 25, 2020
    Copy the full SHA
    03f8758 View commit details
  9. Copy the full SHA
    36a1e4b View commit details
  10. Comment.

    pleroy committed Apr 25, 2020
    Copy the full SHA
    82745d7 View commit details
  11. Copy the full SHA
    330d811 View commit details
  12. Lint.

    pleroy committed Apr 25, 2020
    Copy the full SHA
    bca75dd View commit details

Commits on Apr 26, 2020

  1. After egg's review.

    pleroy committed Apr 26, 2020
    Copy the full SHA
    34ba599 View commit details
  2. Now with OptionalExpressIn.

    pleroy committed Apr 26, 2020
    Copy the full SHA
    897ab16 View commit details
  3. Line length.

    pleroy committed Apr 26, 2020
    Copy the full SHA
    f642d67 View commit details
  4. Merge pull request #2544 from pleroy/ExpressIn

    Add a new class, ExpressIn, to help with type erasure of quantities in Mathematica output
    pleroy authored Apr 26, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    a403ffc View commit details
13 changes: 13 additions & 0 deletions base/traits.hpp
Original file line number Diff line number Diff line change
@@ -6,6 +6,17 @@ namespace principia {
namespace base {
namespace internal_traits {

template<typename... Ts>
constexpr bool all_different_v = false;

template<>
constexpr bool all_different_v<> = true;

template<typename T0, typename... Ts>
constexpr bool all_different_v<T0, Ts...> =
(!std::is_same_v<T0, Ts> && ...) && all_different_v<Ts...>;


template<template<typename...> typename T, typename U>
struct is_instance_of : std::false_type {};

@@ -56,5 +67,7 @@ inline constexpr bool is_serializable_v =
internal_traits::has_sfinae_read_from_message<T>::value ||
internal_traits::has_unconditional_read_from_message<T>::value;

using internal_traits::all_different_v;

} // namespace base
} // namespace principia
2 changes: 2 additions & 0 deletions mathematica/error_analysis_test.cpp
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ class ErrorAnalysisTest : public ::testing::Test {
protected:
};

#if !defined(_DEBUG)
TEST_F(ErrorAnalysisTest, DISABLED_IntegratorPlots) {
GenerateSimpleHarmonicMotionWorkErrorGraphs();
// Circular.
@@ -126,6 +127,7 @@ TEST_F(ErrorAnalysisTest, DISABLED_SECULAR_LocalErrorAnalysis) {
ParseQuantity<Time>(flags["granularity"].value_or("1 d")),
ParseQuantity<Time>(flags["duration"].value_or("500 d")));
}
#endif

} // namespace mathematica
} // namespace principia
2 changes: 1 addition & 1 deletion mathematica/local_error_analysis.cpp
Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@ void LocalErrorAnalyser::WriteLocalErrors(
}
OFStream file(path);
file << Assign("bodyNames", solar_system_->names());
file << Assign("errors", ExpressIn(Metre, errors));
file << Assign("errors", errors, ExpressIn(Metre));
}

not_null<std::unique_ptr<Ephemeris<ICRS>>> LocalErrorAnalyser::ForkEphemeris(
168 changes: 116 additions & 52 deletions mathematica/mathematica.hpp
Original file line number Diff line number Diff line change
@@ -3,112 +3,176 @@

#include <string>
#include <tuple>
#include <type_traits>
#include <vector>

#include "astronomy/orbital_elements.hpp"
#include "base/traits.hpp"
#include "geometry/grassmann.hpp"
#include "geometry/point.hpp"
#include "geometry/quaternion.hpp"
#include "geometry/r3_element.hpp"
#include "numerics/fixed_arrays.hpp"
#include "physics/degrees_of_freedom.hpp"
#include "quantities/elementary_functions.hpp"
#include "quantities/quantities.hpp"
#include "quantities/tuples.hpp"

namespace principia {
namespace mathematica {
namespace internal_mathematica {

using base::all_different_v;
using geometry::Bivector;
using geometry::Point;
using geometry::Quaternion;
using geometry::R3Element;
using geometry::Vector;
using numerics::FixedVector;
using physics::DegreesOfFreedom;
using quantities::Amount;
using quantities::Angle;
using quantities::Current;
using quantities::Exponentiation;
using quantities::is_tuple_v;
using quantities::Length;
using quantities::LuminousIntensity;
using quantities::Mass;
using quantities::Pow;
using quantities::Quantity;
using quantities::Quotient;
using quantities::Temperature;
using quantities::Time;

// A helper class for type erasure of quantities. It may be used with the
// functions in this file to remove the dimensions of quantities (we know that
// Mathematica is sluggish when processing quantities). Usage:
//
// ToMathematica(... , ExpressIn(Metre, Second, Degree));
//
// The construction parameters must be values of distinct SI base quantities
// (or Angle). They define a system of units.. They may be in any order. If
// the other arguments of the functions contain quantities that are not spanned
// by that system of units, the call is ill-formed.
template<typename... Qs>
class ExpressIn {
public:
// Check that only SI base quantities or Angle are specified.
static_assert(
((std::is_same_v<Qs, Length> || std::is_same_v<Qs, Mass> ||
std::is_same_v<Qs, Time> || std::is_same_v<Qs, Current> ||
std::is_same_v<Qs, Temperature> || std::is_same_v<Qs, Amount> ||
std::is_same_v<Qs, LuminousIntensity> || std::is_same_v<Qs, Angle>) &&
...), "Must instantiate with SI base quantities or Angle");

// Check that all quantities are different.
static_assert(all_different_v<Qs...>, "Must use different quantities");

ExpressIn(Qs const&... qs); // NOLINT(runtime/explicit)

template<typename Q>
double operator()(Q const& q) const;

private:
template<std::int64_t exponent, typename Q1, typename Q2>
Quotient<Q2, Exponentiation<Q1, exponent>> Divide(Q2 const& q2) const;

std::tuple<Qs...> units_;
};

std::string Apply(std::string const& function,
std::vector<std::string> const& arguments);

template<typename T>
std::string Option(std::string const& name, T const& right);
template<typename T, typename OptionalExpressIn = std::nullopt_t>
std::string Option(std::string const& name,
T const& right,
OptionalExpressIn express_in = std::nullopt);

template<typename T>
std::string Assign(std::string const& name, T const& right);
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 U>
std::string PlottableDataset(std::vector<T> const& x, std::vector<U> const& y);
template<typename T, typename U, typename OptionalExpressIn = std::nullopt_t>
std::string PlottableDataset(std::vector<T> const& x,
std::vector<U> const& y,
OptionalExpressIn express_in = std::nullopt);

template<typename T>
std::string ToMathematica(std::vector<T> const& list);
template<typename T, typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(std::vector<T> const& list,
OptionalExpressIn express_in = std::nullopt);

template<typename It>
std::string ToMathematica(It begin, It end);
template<typename It, typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(It begin, It end,
OptionalExpressIn express_in = std::nullopt);

std::string ToMathematica(double const& real);
template<typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(double real,
OptionalExpressIn express_in = std::nullopt);

template<typename T, int size>
std::string ToMathematica(FixedVector<T, size> const& fixed_vector);
template<typename T, int size, typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(FixedVector<T, size> const& fixed_vector,
OptionalExpressIn express_in = std::nullopt);

template<typename T>
std::string ToMathematica(R3Element<T> const& r3_element);
template<typename T, typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(R3Element<T> const& r3_element,
OptionalExpressIn express_in = std::nullopt);

std::string ToMathematica(Quaternion const& quaternion);
template<typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(Quaternion const& quaternion,
OptionalExpressIn express_in = std::nullopt);

template<typename D>
std::string ToMathematica(Quantity<D> const& quantity);
template<typename D, typename... Qs>
std::string ToMathematica(Quantity<D> const& quantity,
ExpressIn<Qs...> express_in);

template<typename S, typename F>
std::string ToMathematica(Vector<S, F> const& vector);
template<typename D, typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(Quantity<D> const& quantity,
std::nullopt_t express_in = std::nullopt);

template<typename S, typename F>
std::string ToMathematica(Bivector<S, F> const& bivector);
template<typename S, typename F, typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(Vector<S, F> const& vector,
OptionalExpressIn express_in = std::nullopt);

template<typename V>
std::string ToMathematica(Point<V> const& point);
template<typename S, typename F, typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(Bivector<S, F> const& bivector,
OptionalExpressIn express_in = std::nullopt);

template<typename F>
std::string ToMathematica(DegreesOfFreedom<F> const& degrees_of_freedom);
template<typename V, typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(Point<V> const& point,
OptionalExpressIn express_in = std::nullopt);

template<typename... Types>
std::string ToMathematica(std::tuple<Types...> const& tuple);
template<typename F, typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(DegreesOfFreedom<F> const& degrees_of_freedom,
OptionalExpressIn express_in = std::nullopt);

template<typename Tuple,
typename = std::enable_if_t<is_tuple_v<Tuple>>,
typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(Tuple const& tuple,
OptionalExpressIn express_in = std::nullopt);

template<typename R,
typename = std::void_t<decltype(std::declval<R>().time)>,
typename = std::void_t<decltype(std::declval<R>().degrees_of_freedom)>>
std::string ToMathematica(R ref);
typename = std::void_t<decltype(std::declval<R>().degrees_of_freedom)>,
typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(R ref,
OptionalExpressIn express_in = std::nullopt);

template<typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(
astronomy::OrbitalElements::EquinoctialElements const& elements);
astronomy::OrbitalElements::EquinoctialElements const& elements,
OptionalExpressIn express_in = std::nullopt);

// Returns its argument.
std::string ToMathematica(std::string const& str);
template<typename OptionalExpressIn = std::nullopt_t>
std::string ToMathematica(std::string const& str,
OptionalExpressIn express_in = std::nullopt);

// Wraps the string in quotes.
// TODO(egg): escape things properly.
std::string Escape(std::string const& str);

// TODO(phl): This doesn't work well for complex structures like orbital
// elements or trajectory iterators. Surely we can do better.
template<typename T>
struct RemoveUnit;

template<typename T>
typename RemoveUnit<T>::Unitless ExpressIn(
typename RemoveUnit<T>::Unit const& unit,
T const& value);

template<typename V>
typename RemoveUnit<Point<V>>::Unitless ExpressIn(
typename RemoveUnit<Point<V>>::Unit const& unit,
Point<V> const& value);

template<typename T>
typename RemoveUnit<std::vector<T>>::Unitless ExpressIn(
typename RemoveUnit<std::vector<T>>::Unit const& unit,
std::vector<T> const& values);

} // namespace internal_mathematica

using internal_mathematica::Apply;
Loading