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

Commits on Feb 18, 2018

  1. Copy the full SHA
    c041e13 View commit details
  2. Simplify Grassmann.

    pleroy committed Feb 18, 2018
    Copy the full SHA
    2a5eb87 View commit details
  3. Less SFINAE.

    pleroy committed Feb 18, 2018
    Copy the full SHA
    c694a6d View commit details
  4. Cleanup.

    pleroy committed Feb 18, 2018
    Copy the full SHA
    6a38484 View commit details
  5. After egg's review.

    pleroy committed Feb 18, 2018
    Copy the full SHA
    6492bbf View commit details
  6. Merge pull request #1727 from pleroy/Scalars

    Unify scalar multiplications and divisions of R3Elements and Multivectors
    pleroy authored Feb 18, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    9e788ff View commit details
36 changes: 14 additions & 22 deletions geometry/grassmann.hpp
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@
#include "base/not_null.hpp"
#include "geometry/r3_element.hpp"
#include "quantities/quantities.hpp"
#include "quantities/traits.hpp"
#include "serialization/geometry.pb.h"

namespace principia {
@@ -21,6 +22,7 @@ namespace internal_grassmann {

using base::not_null;
using quantities::Angle;
using quantities::is_quantity;
using quantities::Product;
using quantities::Quantity;
using quantities::Quotient;
@@ -255,33 +257,23 @@ Multivector<Scalar, Frame, rank> operator-(
Multivector<Scalar, Frame, rank> const& left,
Multivector<Scalar, Frame, rank> const& right);

template<typename Scalar, typename Frame, int rank>
Multivector<Scalar, Frame, rank> operator*(
double left,
Multivector<Scalar, Frame, rank> const& right);
template<typename Scalar, typename Frame, int rank>
Multivector<Scalar, Frame, rank> operator*(
Multivector<Scalar, Frame, rank> const& left,
double right);
template<typename Scalar, typename Frame, int rank>
Multivector<Scalar, Frame, rank> operator/(
Multivector<Scalar, Frame, rank> const& left,
double right);

template<typename LDimension, typename RScalar, typename Frame, int rank>
Multivector<Product<Quantity<LDimension>, RScalar>, Frame, rank>
operator*(Quantity<LDimension> const& left,
template<typename LScalar, typename RScalar, typename Frame, int rank,
typename = std::enable_if_t<is_quantity<LScalar>::value>>
Multivector<Product<LScalar, RScalar>, Frame, rank>
operator*(LScalar const& left,
Multivector<RScalar, Frame, rank> const& right);

template<typename LScalar, typename RDimension, typename Frame, int rank>
Multivector<Product<LScalar, Quantity<RDimension>>, Frame, rank>
template<typename LScalar, typename RScalar, typename Frame, int rank,
typename = std::enable_if_t<is_quantity<RScalar>::value>>
Multivector<Product<LScalar, RScalar>, Frame, rank>
operator*(Multivector<LScalar, Frame, rank> const& left,
Quantity<RDimension> const& right);
RScalar const& right);

template<typename LScalar, typename RDimension, typename Frame, int rank>
Multivector<Quotient<LScalar, Quantity<RDimension>>, Frame, rank>
template<typename LScalar, typename RScalar, typename Frame, int rank,
typename = std::enable_if_t<is_quantity<RScalar>::value>>
Multivector<Quotient<LScalar, RScalar>, Frame, rank>
operator/(Multivector<LScalar, Frame, rank> const& left,
Quantity<RDimension> const& right);
RScalar const& right);

template<typename Scalar, typename Frame, int rank>
bool operator==(Multivector<Scalar, Frame, rank> const& left,
45 changes: 12 additions & 33 deletions geometry/grassmann_body.hpp
Original file line number Diff line number Diff line change
@@ -355,48 +355,27 @@ Multivector<Scalar, Frame, rank> operator-(
left.coordinates() - right.coordinates());
}

template<typename Scalar, typename Frame, int rank>
Multivector<Scalar, Frame, rank> operator*(
double const left,
Multivector<Scalar, Frame, rank> const& right) {
return Multivector<Scalar, Frame, rank>(left * right.coordinates());
}

template<typename Scalar, typename Frame, int rank>
Multivector<Scalar, Frame, rank> operator*(
Multivector<Scalar, Frame, rank> const& left,
double const right) {
return Multivector<Scalar, Frame, rank>(left.coordinates() * right);
}

template<typename Scalar, typename Frame, int rank>
Multivector<Scalar, Frame, rank> operator/(
Multivector<Scalar, Frame, rank> const& left,
double const right) {
return Multivector<Scalar, Frame, rank>(left.coordinates() / right);
}

template<typename LDimension, typename RScalar, typename Frame, int rank>
Multivector<Product<Quantity<LDimension>, RScalar>, Frame, rank>
operator*(Quantity<LDimension> const& left,
template<typename LScalar, typename RScalar, typename Frame, int rank, typename>
Multivector<Product<LScalar, RScalar>, Frame, rank>
operator*(LScalar const& left,
Multivector<RScalar, Frame, rank> const& right) {
return Multivector<Product<Quantity<LDimension>, RScalar>, Frame, rank>(
return Multivector<Product<LScalar, RScalar>, Frame, rank>(
left * right.coordinates());
}

template<typename LScalar, typename RDimension, typename Frame, int rank>
Multivector<Product<LScalar, Quantity<RDimension>>, Frame, rank>
template<typename LScalar, typename RScalar, typename Frame, int rank, typename>
Multivector<Product<LScalar, RScalar>, Frame, rank>
operator*(Multivector<LScalar, Frame, rank> const& left,
Quantity<RDimension> const& right) {
return Multivector<Product<LScalar, Quantity<RDimension>>, Frame, rank>(
RScalar const& right) {
return Multivector<Product<LScalar, RScalar>, Frame, rank>(
left.coordinates() * right);
}

template<typename LScalar, typename RDimension, typename Frame, int rank>
Multivector<Quotient<LScalar, Quantity<RDimension>>, Frame, rank>
template<typename LScalar, typename RScalar, typename Frame, int rank, typename>
Multivector<Quotient<LScalar, RScalar>, Frame, rank>
operator/(Multivector<LScalar, Frame, rank> const& left,
Quantity<RDimension> const& right) {
return Multivector<Quotient<LScalar, Quantity<RDimension>>, Frame, rank>(
RScalar const& right) {
return Multivector<Quotient<LScalar, RScalar>, Frame, rank>(
left.coordinates() / right);
}

31 changes: 15 additions & 16 deletions geometry/r3_element.hpp
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ namespace internal_r3_element {

using base::not_null;
using quantities::Angle;
using quantities::is_quantity;
using quantities::Product;
using quantities::Quantity;
using quantities::Quotient;
@@ -104,27 +105,25 @@ template<typename Scalar>
R3Element<Scalar> operator-(R3Element<Scalar> const& left,
R3Element<Scalar> const& right);

template<typename Scalar>
R3Element<Scalar> operator*(double left, R3Element<Scalar> const& right);
template<typename Scalar>
R3Element<Scalar> operator*(R3Element<Scalar> const& left, double right);
template<typename Scalar>
R3Element<Scalar> operator/(R3Element<Scalar> const& left, double right);

// Dimensionful multiplication |LScalar * R3Element<RScalar>| is the tensor
// product LScalar ⊗ Scalar³. Since LScalar ⊗ Scalar³ ≅ (LScalar ⊗ Scalar)³,
// the result is an R3Element<Product<LScalar, RScalar>>.
// The special case where one of the scalars is |double| is handled separately
// above in order to allow implicit conversions to |double|.
template<typename LDimension, typename RScalar>
R3Element<Product<Quantity<LDimension>, RScalar>>
operator*(Quantity<LDimension> const& left, R3Element<RScalar> const& right);
template<typename LScalar, typename RDimension>
R3Element<Product<LScalar, Quantity<RDimension>>>
operator*(R3Element<LScalar> const& left, Quantity<RDimension> const& right);
template<typename LScalar, typename RDimension>
R3Element<Quotient<LScalar, Quantity<RDimension>>>
operator/(R3Element<LScalar> const& left, Quantity<RDimension> const& right);
template<typename LScalar, typename RScalar,
typename = std::enable_if_t<is_quantity<LScalar>::value>>
R3Element<Product<LScalar, RScalar>>
operator*(LScalar const& left, R3Element<RScalar> const& right);

template<typename LScalar, typename RScalar,
typename = std::enable_if_t<is_quantity<RScalar>::value>>
R3Element<Product<LScalar, RScalar>>
operator*(R3Element<LScalar> const& left, RScalar const& right);

template<typename LScalar, typename RScalar,
typename = std::enable_if_t<is_quantity<RScalar>::value>>
R3Element<Quotient<LScalar, RScalar>>
operator/(R3Element<LScalar> const& left, RScalar const& right);

template<typename Scalar>
bool operator==(R3Element<Scalar> const& left,
98 changes: 25 additions & 73 deletions geometry/r3_element_body.hpp
Original file line number Diff line number Diff line change
@@ -223,94 +223,46 @@ R3Element<Scalar> operator-(R3Element<Scalar> const& left,
#endif
}

template<typename Scalar>
R3Element<Scalar> operator*(double const left,
R3Element<Scalar> const& right) {
#if PRINCIPIA_USE_SSE2_INTRINSICS
__m128d const left_128d = ToM128D(left);
return R3Element<Scalar>(_mm_mul_pd(right.xy, left_128d),
_mm_mul_sd(right.zt, left_128d));
#else
return R3Element<Scalar>(left * right.x,
left * right.y,
left * right.z);
#endif
}

template<typename Scalar>
R3Element<Scalar> operator*(R3Element<Scalar> const& left,
double const right) {
#if PRINCIPIA_USE_SSE2_INTRINSICS
__m128d const right_128d = ToM128D(right);
return R3Element<Scalar>(_mm_mul_pd(left.xy, right_128d),
_mm_mul_sd(left.zt, right_128d));
#else
return R3Element<Scalar>(left.x * right,
left.y * right,
left.z * right);
#endif
}

template<typename Scalar>
R3Element<Scalar> operator/(R3Element<Scalar> const& left,
double const right) {
#if PRINCIPIA_USE_SSE2_INTRINSICS
__m128d const right_128d = ToM128D(right);
return R3Element<Scalar>(_mm_div_pd(left.xy, right_128d),
_mm_div_sd(left.zt, right_128d));
#else
return R3Element<Scalar>(left.x / right,
left.y / right,
left.z / right);
#endif
}

template<typename LDimension, typename RScalar>
R3Element<Product<Quantity<LDimension>, RScalar>>
operator*(Quantity<LDimension> const& left, R3Element<RScalar> const& right) {
template<typename LScalar, typename RScalar, typename>
R3Element<Product<LScalar, RScalar>> operator*(
LScalar const& left,
R3Element<RScalar> const& right) {
#if PRINCIPIA_USE_SSE2_INTRINSICS
__m128d const left_128d = ToM128D(left);
return R3Element<Product<Quantity<LDimension>, RScalar>>(
_mm_mul_pd(right.xy, left_128d),
_mm_mul_sd(right.zt, left_128d));
return R3Element<Product<LScalar, RScalar>>(_mm_mul_pd(right.xy, left_128d),
_mm_mul_sd(right.zt, left_128d));
#else
return R3Element<Product<Quantity<LDimension>, RScalar>>(
left * right.x,
left * right.y,
left * right.z);
return R3Element<Product<LScalar, RScalar>>(left * right.x,
left * right.y,
left * right.z);
#endif
}

template<typename LScalar, typename RDimension>
R3Element<Product<LScalar, Quantity<RDimension>>>
operator*(R3Element<LScalar> const& left, Quantity<RDimension> const& right) {
template<typename LScalar, typename RScalar, typename>
R3Element<Product<LScalar, RScalar>> operator*(R3Element<LScalar> const& left,
RScalar const& right) {
#if PRINCIPIA_USE_SSE2_INTRINSICS
__m128d const right_128d = ToM128D(right);
return R3Element<Product<LScalar, Quantity<RDimension>>>(
_mm_mul_pd(left.xy, right_128d),
_mm_mul_sd(left.zt, right_128d));
return R3Element<Product<LScalar, RScalar>>(_mm_mul_pd(left.xy, right_128d),
_mm_mul_sd(left.zt, right_128d));
#else
return R3Element<Product<LScalar, Quantity<RDimension>>>(
left.x * right,
left.y * right,
left.z * right);
return R3Element<Product<LScalar, RScalar>>(left.x * right,
left.y * right,
left.z * right);
#endif
}

template<typename LScalar, typename RDimension>
R3Element<Quotient<LScalar, Quantity<RDimension>>>
operator/(R3Element<LScalar> const& left,
Quantity<RDimension> const& right) {
template<typename LScalar, typename RScalar, typename>
R3Element<Quotient<LScalar, RScalar>> operator/(R3Element<LScalar> const& left,
RScalar const& right) {
#if PRINCIPIA_USE_SSE2_INTRINSICS
__m128d const right_128d = ToM128D(right);
return R3Element<Quotient<LScalar, Quantity<RDimension>>>(
_mm_div_pd(left.xy, right_128d),
_mm_div_sd(left.zt, right_128d));
return R3Element<Quotient<LScalar, RScalar>>(_mm_div_pd(left.xy, right_128d),
_mm_div_sd(left.zt, right_128d));
#else
return R3Element<Quotient<LScalar, Quantity<RDimension>>>(
left.x / right,
left.y / right,
left.z / right);
return R3Element<Quotient<LScalar, RScalar>>(left.x / right,
left.y / right,
left.z / right);
#endif
}

13 changes: 5 additions & 8 deletions quantities/elementary_functions.hpp
Original file line number Diff line number Diff line change
@@ -9,29 +9,26 @@ namespace quantities {
namespace internal_elementary_functions {

// Equivalent to |std::fma(x, y, z)|.
template<typename Q1, typename Q2,
typename = std::enable_if<is_quantity<Q1>::value>,
typename = std::enable_if<is_quantity<Q2>::value>>
template<typename Q1, typename Q2>
Product<Q1, Q2> FusedMultiplyAdd(Q1 const& x,
Q2 const& y,
Product<Q1, Q2> const& z);

// Equivalent to |std::abs(x)|.
template<typename Q, typename = std::enable_if<is_quantity<Q>::value>>
template<typename Q>
Q Abs(Q const& x);

// Equivalent to |std::sqrt(x)|.
template<typename Q, typename = std::enable_if<is_quantity<Q>::value>>
template<typename Q>
SquareRoot<Q> Sqrt(Q const& x);

// Equivalent to |std::cbrt(x)|.
template<typename Q, typename = std::enable_if<is_quantity<Q>::value>>
template<typename Q>
CubeRoot<Q> Cbrt(Q const& x);

// Equivalent to |std::pow(x, exponent)| unless -3 ≤ x ≤ 3, in which case
// explicit specialization yields multiplications statically.
template<int exponent, typename Q,
typename = std::enable_if<is_quantity<Q>::value>>
template<int exponent, typename Q>
constexpr Exponentiation<Q, exponent> Pow(Q const& x);

double Sin(Angle const& α);
10 changes: 5 additions & 5 deletions quantities/elementary_functions_body.hpp
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ namespace principia {
namespace quantities {
namespace internal_elementary_functions {

template<typename Q1, typename Q2, typename, typename>
template<typename Q1, typename Q2>
Product<Q1, Q2> FusedMultiplyAdd(Q1 const& x,
Q2 const& y,
Product<Q1, Q2> const& z) {
@@ -21,17 +21,17 @@ Product<Q1, Q2> FusedMultiplyAdd(Q1 const& x,
z / SIUnit<Product<Q1, Q2>>());
}

template<typename Q, typename>
template<typename Q>
FORCE_INLINE(inline) Q Abs(Q const& quantity) {
return SIUnit<Q>() * std::abs(quantity / SIUnit<Q>());
}

template<typename Q, typename>
template<typename Q>
SquareRoot<Q> Sqrt(Q const& x) {
return SIUnit<SquareRoot<Q>>() * std::sqrt(x / SIUnit<Q>());
}

template<typename Q, typename>
template<typename Q>
CubeRoot<Q> Cbrt(Q const& x) {
return SIUnit<CubeRoot<Q>>() * std::cbrt(x / SIUnit<Q>());
}
@@ -79,7 +79,7 @@ inline constexpr double Pow<3>(double x) {
return x * x * x;
}

template<int exponent, typename Q, typename>
template<int exponent, typename Q>
constexpr Exponentiation<Q, exponent> Pow(Q const& x) {
return SIUnit<Exponentiation<Q, exponent>>() * Pow<exponent>(x / SIUnit<Q>());
}
Loading