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

Commits on Jul 2, 2020

  1. Copy the full SHA
    13be47d View commit details
  2. Merge pull request #2622 from pleroy/PolynomialConversion

    Conversion of a polynomial to a higher degree
    pleroy authored Jul 2, 2020
    Copy the full SHA
    57a213f View commit details
Showing with 57 additions and 0 deletions.
  1. +7 −0 numerics/polynomial.hpp
  2. +36 −0 numerics/polynomial_body.hpp
  3. +14 −0 numerics/polynomial_test.cpp
7 changes: 7 additions & 0 deletions numerics/polynomial.hpp
Original file line number Diff line number Diff line change
@@ -71,6 +71,13 @@ class PolynomialInMonomialBasis : public Polynomial<Value, Argument> {
explicit constexpr PolynomialInMonomialBasis(
Coefficients coefficients);

// A polynomial may be explicitly converted to a higher degree (possibly with
// a different evaluator).
template<int higher_degree_,
template<typename, typename, int> class HigherEvaluator>
explicit operator PolynomialInMonomialBasis<
Value, Argument, higher_degree_, HigherEvaluator>() const;

FORCE_INLINE(inline) Value
Evaluate(Argument const& argument) const override;
FORCE_INLINE(inline) Derivative<Value, Argument>
36 changes: 36 additions & 0 deletions numerics/polynomial_body.hpp
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
#include "geometry/cartesian_product.hpp"
#include "geometry/serialization.hpp"
#include "numerics/combinatorics.hpp"
#include "polynomial.hpp"

namespace principia {
namespace numerics {
@@ -25,6 +26,25 @@ using geometry::cartesian_product::operator/;
using geometry::polynomial_ring::operator*;
using quantities::Apply;

// Index-by-index assignment of RTuple to LTuple, which must have at least as
// many elements (and the types must match).
template<typename LTuple, typename RTuple,
typename = std::make_index_sequence<std::tuple_size_v<RTuple>>>
struct TupleAssigner;

template<typename LTuple, typename RTuple, std::size_t... indices>
struct TupleAssigner<LTuple, RTuple, std::index_sequence<indices...>> {
static void Assign(LTuple& left_tuple, RTuple const& right_tuple);
};

template<typename LTuple, typename RTuple, std::size_t... indices>
void TupleAssigner<LTuple, RTuple, std::index_sequence<indices...>>::Assign(
LTuple& left_tuple,
RTuple const& right_tuple) {
// This fold expression effectively implements repeated assignments.
((std::get<indices>(left_tuple) = std::get<indices>(right_tuple)), ...);
}

template<typename Tuple, int order,
typename = std::make_index_sequence<std::tuple_size_v<Tuple> - order>>
struct TupleDerivation;
@@ -189,6 +209,22 @@ PolynomialInMonomialBasis<Value, Argument, degree_, Evaluator>::degree() const {
return degree_;
}

template<typename Value, typename Argument, int degree_,
template<typename, typename, int> class Evaluator>
template<int higher_degree_,
template<typename, typename, int> class HigherEvaluator>
PolynomialInMonomialBasis<Value, Argument, degree_, Evaluator>::
operator PolynomialInMonomialBasis<Value, Argument, higher_degree_,
HigherEvaluator>() const {
static_assert(degree_ <= higher_degree_);
using Result = PolynomialInMonomialBasis<Value, Argument, higher_degree_,
HigherEvaluator>;
typename Result::Coefficients higher_coefficients;
TupleAssigner<typename Result::Coefficients, Coefficients>::Assign(
higher_coefficients, coefficients_);
return Result(higher_coefficients);
}

template<typename Value, typename Argument, int degree_,
template<typename, typename, int> class Evaluator>
template<int order>
14 changes: 14 additions & 0 deletions numerics/polynomial_test.cpp
Original file line number Diff line number Diff line change
@@ -152,6 +152,20 @@ TEST_F(PolynomialTest, Evaluate17) {
0 * Metre}), 0));
}

// Check that a conversion to increase the degree works.
TEST_F(PolynomialTest, Conversion) {
P2V const p2v(coefficients_);
P17 const p17 = P17(p2v);
Displacement<World> const d = p17.Evaluate(0.5 * Second);
Velocity<World> const v = p17.EvaluateDerivative(0.5 * Second);
EXPECT_THAT(d, AlmostEquals(Displacement<World>({0.25 * Metre,
0.5 * Metre,
1 * Metre}), 0));
EXPECT_THAT(v, AlmostEquals(Velocity<World>({1 * Metre / Second,
1 * Metre / Second,
0 * Metre / Second}), 0));
}

TEST_F(PolynomialTest, VectorSpace) {
P2V const p2v(coefficients_);
{