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

Commits on Oct 31, 2021

  1. Copy the full SHA
    1fd72c9 View commit details
  2. Copy the full SHA
    c7cb00c View commit details
  3. Copy the full SHA
    3115234 View commit details

Commits on Nov 1, 2021

  1. Copy the full SHA
    a2b0094 View commit details
  2. Try something.

    pleroy committed Nov 1, 2021
    Copy the full SHA
    b35fc82 View commit details
  3. Copy the full SHA
    4c84c5c View commit details
  4. Copy the full SHA
    ac4b218 View commit details
  5. Readying.

    pleroy committed Nov 1, 2021
    Copy the full SHA
    9f88ad2 View commit details
  6. Lint.

    pleroy committed Nov 1, 2021
    Copy the full SHA
    523b0c7 View commit details

Commits on Nov 2, 2021

  1. Merge pull request #3187 from pleroy/WriteRange

    Change WriteToMessage to be capable of writing only a range of the trajectory
    pleroy authored Nov 2, 2021
    Copy the full SHA
    d6c6c7c View commit details
12 changes: 12 additions & 0 deletions physics/discrete_traject0ry.hpp
Original file line number Diff line number Diff line change
@@ -112,10 +112,22 @@ class DiscreteTraject0ry : public Trajectory<Frame> {
DegreesOfFreedom<Frame> EvaluateDegreesOfFreedom(
Instant const& t) const override;

// The segments in |tracked| are restored at deserialization. The points
// denoted by |exact| are written and re-read exactly and are not affected by
// any errors introduced by zfp compression. The endpoints of each segment
// are always exact.
void WriteToMessage(
not_null<serialization::DiscreteTrajectory*> message,
std::vector<SegmentIterator> const& tracked,
std::vector<iterator> const& exact) const;
// Same as above, but only the points defined by [begin, end[ are written.
void WriteToMessage(
not_null<serialization::DiscreteTrajectory*> message,
iterator begin,
iterator end,
std::vector<SegmentIterator> const& tracked,
std::vector<iterator> const& exact) const;

template<typename F = Frame,
typename = std::enable_if_t<base::is_serializable_v<F>>>
static DiscreteTraject0ry ReadFromMessage(
72 changes: 66 additions & 6 deletions physics/discrete_traject0ry_body.hpp
Original file line number Diff line number Diff line change
@@ -2,9 +2,11 @@

#include "physics/discrete_traject0ry.hpp"

#include <algorithm>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/str_cat.h"
#include "astronomy/epoch.hpp"
#include "base/status_utilities.hpp"
@@ -14,6 +16,7 @@ namespace principia {
namespace physics {
namespace internal_discrete_traject0ry {

using astronomy::InfiniteFuture;
using astronomy::InfinitePast;
using base::make_not_null_unique;
using base::uninitialized;
@@ -303,11 +306,14 @@ void DiscreteTraject0ry<Frame>::ForgetBefore(Instant const& t) {
auto const sit = leit->second;
// This call may make the segment |*sit| empty if |t| is after the end of
// |*sit|.
// NOTE(phl): This declaration is necessary because MSVC corrupts |t| during
// the call below.
Instant const t_saved = t;
sit->ForgetBefore(t);
for (auto s = segments_->begin(); s != sit; ++s) {
// This call may either make the segment |*s| empty or leave it with a
// single point matching |sit->front()|.
s->ForgetBefore(t);
s->ForgetBefore(t_saved);
}

// Erase all the entries before and including |leit|. These are entries for
@@ -394,6 +400,16 @@ void DiscreteTraject0ry<Frame>::WriteToMessage(
not_null<serialization::DiscreteTrajectory*> message,
std::vector<SegmentIterator> const& tracked,
std::vector<iterator> const& exact) const {
WriteToMessage(message, begin(), end(), tracked, exact);
}

template<typename Frame>
void DiscreteTraject0ry<Frame>::WriteToMessage(
not_null<serialization::DiscreteTrajectory*> message,
iterator const begin,
iterator const end,
std::vector<SegmentIterator> const& tracked,
std::vector<iterator> const& exact) const {
// Construct a map to efficiently find if a segment must be tracked. The
// keys are pointers to segments in |tracked|, the values are the
// corresponding indices.
@@ -411,12 +427,49 @@ void DiscreteTraject0ry<Frame>::WriteToMessage(
tracked.size(),
serialization::DiscreteTrajectory::MISSING_TRACKED_POSITION);

// Convert to instants the iterators that define the range to write. This is
// necessary to do lookups in each segment to obtain segment-specific
// iterators.
Instant const begin_time = begin == this->end() ? InfiniteFuture
: begin->time;
Instant const end_time = end == this->end() ? InfiniteFuture
: end->time;

// The set of segments that intersect the range to write.
absl::flat_hash_set<
DiscreteTrajectorySegment<Frame> const*> intersecting_segments;
bool intersect_range = false;

// The position of a segment in the repeated field |segment|.
int segment_position = 0;
for (auto sit = segments_->begin();
sit != segments_->end();
++sit, ++segment_position) {
sit->WriteToMessage(message->add_segment(), exact);
// Look up in |*sit| the instants that define the range to write.
// |lower_bound| and |upper_bound| return the past-the-end-of-segment
// iterator if no point exists after the given time, i.e., for the segments
// that precede the intersection.
auto const begin_time_it = sit->lower_bound(begin_time);
auto const end_time_it = sit->lower_bound(end_time);

// If the above iterators determine an empty range, and we have already seen
// a segment that intersects the range to write, we are past the
// intersection. Skip all the remaining segments.
if (intersect_range && begin_time_it == end_time_it) {
break;
}

// If |*sit| contains a point at or after |begin_time|, it intersects the
// range to write.
intersect_range = begin_time_it != sit->end();
if (intersect_range) {
intersecting_segments.insert(&*sit);
}

// Note that we execute this call for the segments that precede the
// intersection in order to write the correct structure of (empty) segments.
sit->WriteToMessage(
message->add_segment(), begin_time_it, end_time_it, exact);

if (auto const position_it = segment_to_position.find(&*sit);
position_it != segment_to_position.end()) {
@@ -434,10 +487,17 @@ void DiscreteTraject0ry<Frame>::WriteToMessage(
++sit1;
++i;
}
auto* const segment_by_left_endpoint =
message->add_segment_by_left_endpoint();
t.WriteToMessage(segment_by_left_endpoint->mutable_left_endpoint());
segment_by_left_endpoint->set_segment(i);
// Skip the segments that don't intersect the range to write, as we pretend
// that they are empty. Adjust the left endpoint to account for the segment
// that may have been truncated on the left.
if (intersecting_segments.contains(&*sit2)) {
auto* const segment_by_left_endpoint =
message->add_segment_by_left_endpoint();
Instant const left_endpoint = std::max(t, begin_time);
left_endpoint.WriteToMessage(
segment_by_left_endpoint->mutable_left_endpoint());
segment_by_left_endpoint->set_segment(i);
}
}
}

24 changes: 24 additions & 0 deletions physics/discrete_traject0ry_test.cpp
Original file line number Diff line number Diff line change
@@ -674,6 +674,30 @@ TEST_F(DiscreteTraject0ryTest, SerializationExactEndpoints) {
IsNear(0.36_⑴ * Metre / Second)));
}

TEST_F(DiscreteTraject0ryTest, SerializationRange) {
auto const trajectory1 = MakeTrajectory();
auto trajectory2 = MakeTrajectory();

serialization::DiscreteTrajectory message1;
trajectory1.WriteToMessage(
&message1,
/*begin=*/trajectory1.upper_bound(t0_ + 6 * Second),
/*end=*/trajectory1.upper_bound(t0_ + 12 * Second),
/*tracked=*/{},
/*exact=*/{});

serialization::DiscreteTrajectory message2;
trajectory2.ForgetBefore(trajectory2.upper_bound(t0_ + 6 * Second));
trajectory2.ForgetAfter(trajectory2.upper_bound(t0_ + 12 * Second));
trajectory2.WriteToMessage(&message2,
/*tracked=*/{},
/*exact=*/{});

// Writing a range of the trajectory is equivalent to forgetting and writing
// the result.
EXPECT_THAT(message1, EqualsProto(message2));
}

TEST_F(DiscreteTraject0ryTest, DISABLED_SerializationPreΖήνωνCompatibility) {
StringLogSink log_warning(google::WARNING);
auto const serialized_message = ReadFromBinaryFile(
21 changes: 21 additions & 0 deletions physics/discrete_trajectory_segment.hpp
Original file line number Diff line number Diff line change
@@ -116,6 +116,14 @@ class DiscreteTrajectorySegment : public Trajectory<Frame> {
void WriteToMessage(
not_null<serialization::DiscreteTrajectorySegment*> message,
std::vector<iterator> const& exact) const;
// Same as above, but only the points defined by [begin, end[ are written.
// The iterators must have been obtained by operations on this segment.
void WriteToMessage(
not_null<serialization::DiscreteTrajectorySegment*> message,
iterator begin,
iterator end,
std::vector<iterator> const& exact) const;

template<typename F = Frame,
typename = std::enable_if_t<base::is_serializable_v<F>>>
static DiscreteTrajectorySegment ReadFromMessage(
@@ -167,6 +175,19 @@ class DiscreteTrajectorySegment : public Trajectory<Frame> {
typename Timeline::const_iterator timeline_end() const;
bool timeline_empty() const;

// Implementation of serialization. The caller is expected to pass consistent
// parameters. |timeline_begin| and |timeline_end| define the range to write.
// |timeline_size| is the distance from |timeline_begin| to |timeline_end|.
// |number_of_points_to_skip_at_end| is the distance between |timeline_end|
// and the true |end| of the timeline.
void WriteToMessage(
not_null<serialization::DiscreteTrajectorySegment*> message,
typename Timeline::const_iterator timeline_begin,
typename Timeline::const_iterator timeline_end,
std::int64_t timeline_size,
std::int64_t number_of_points_to_skip_at_end,
std::vector<iterator> const& exact) const;

std::optional<DownsamplingParameters> downsampling_parameters_;

// The number of points at the end of the segment that are part of a "dense"
Loading