Using two simulators in ARVineyard (one for simplices and one for trajectories)
- Fixes #c66
- Simulator::reached_infinity() examines the queue instead of
keeping state in a variable
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/.issues/c664b2f69b5f6ea3 Fri Feb 29 15:46:12 2008 -0500
@@ -0,0 +1,9 @@
+From artemis Thu Feb 28 10:34:23 2008
+From: Dmitriy Morozov <morozov@cs.duke.edu>
+Date: Thu, 28 Feb 2008 05:33:34 -0500
+State: new
+Subject: Two simulators
+Message-Id: <c664b2f69b5f6ea3-0-artemis@metatron>
+
+Consider using two simulators instead of one to make sure that trajectory
+changes are processed before simplex swaps.
--- a/examples/ar-vineyard/ar-vineyard.h Fri Feb 29 14:39:48 2008 -0500
+++ b/examples/ar-vineyard/ar-vineyard.h Fri Feb 29 15:46:12 2008 -0500
@@ -163,12 +163,13 @@
class ARVineyard::ThresholdChangeSlot
{
public:
- ThresholdChangeSlot(SimplexSortIterator iter, SimplexSort* sort, Vineyard* vineyard):
- iter_(iter), sort_(sort), vineyard_(vineyard) { iter_->element->new_max_signal().connect(*this); }
+ ThresholdChangeSlot(SimplexSortIterator iter, SimplexSort* sort,
+ Vineyard* vineyard, Simulator* sort_simulator):
+ iter_(iter), sort_(sort), vineyard_(vineyard), sort_simulator_(sort_simulator) { iter_->element->new_max_signal().connect(*this); }
void operator()(Simulator* simulator)
{
Count(cARVineyardTrajectoryKnee);
- sort_->update_trajectory(iter_, simulator);
+ sort_->update_trajectory(iter_, sort_simulator_);
if (iter_->element->sign())
vineyard_->record_knee(iter_->element);
else
@@ -181,6 +182,7 @@
Vineyard* vineyard_; // currently inefficient since there is
// only one SimplexSort and one Vineyard,
// but each is stored in every slot
+ Simulator* sort_simulator_;
};
class ARVineyard::StaticEvaluator: public Evaluator
--- a/examples/ar-vineyard/ar-vineyard.hpp Fri Feb 29 14:39:48 2008 -0500
+++ b/examples/ar-vineyard/ar-vineyard.hpp Fri Feb 29 15:46:12 2008 -0500
@@ -38,10 +38,9 @@
{
thresholds_.push_back(Function(Function::phi, this));
thresholds_.push_back(Function(Function::rho, this));
+ thresholds_sort_.initialize(thresholds_.begin(), thresholds_.end(),
+ boost::bind(&ARConeSimplex3D::swap_thresholds, this, _1, _2), simulator);
}
-
- thresholds_sort_.initialize(thresholds_.begin(), thresholds_.end(),
- boost::bind(&ARConeSimplex3D::swap_thresholds, this, _1, _2), simulator);
}
@@ -91,31 +90,42 @@
{
AssertMsg(filtration_->is_paired(), "Simplices must be paired for a vineyard to be computed");
- Simulator simulator;
+ Simulator simplex_sort_simulator, trajectory_sort_simulator;
SimplexSort simplex_sort;
// Schedule thresholds
for (Index cur = filtration_->begin(); cur != filtration_->end(); ++cur)
- cur->schedule_thresholds(&simulator);
+ cur->schedule_thresholds(&trajectory_sort_simulator);
// Once thresholds are scheduled, we can initialize the simplex_sort
simplex_sort.initialize(filtration_->begin(), filtration_->end(),
- boost::bind(&ARVineyard::swap, this, _1, _2), &simulator);
+ boost::bind(&ARVineyard::swap, this, _1, _2), &simplex_sort_simulator);
rLog(rlARVineyardComputing, "SimplexSort initialized");
// Connect signals and slots
std::vector<ThresholdChangeSlot> slots;
slots.reserve(filtration_->size());
for (SimplexSortIterator cur = simplex_sort.begin(); cur != simplex_sort.end(); ++cur)
- slots.push_back(ThresholdChangeSlot(cur, &simplex_sort, vineyard_));
+ slots.push_back(ThresholdChangeSlot(cur, &simplex_sort, vineyard_, &simplex_sort_simulator));
rLog(rlARVineyardComputing, "Signals and slots connected");
+ rLog(rlARVineyardComputing, "SimplexSort size: %i", simplex_sort_simulator.size());
+ rLog(rlARVineyardComputing, "TrajectorySort size: %i", trajectory_sort_simulator.size());
// Simulate
- change_evaluator(new KineticEvaluator(&simulator));
- while(!simulator.reached_infinity())
+ change_evaluator(new KineticEvaluator(&simplex_sort_simulator));
+ while(!simplex_sort_simulator.reached_infinity() || !trajectory_sort_simulator.reached_infinity())
{
- rLog(rlARVineyardComputing, "Current time before: %lf", simulator.current_time());
- simulator.process();
+ if (*(simplex_sort_simulator.top()) < *(trajectory_sort_simulator.top()))
+ {
+ rLog(rlARVineyardComputing, "Current time before: %lf (simplex sort)", simplex_sort_simulator.current_time());
+ rLog(rlARVineyardComputing, "Top event: %s (simplex sort)", intostring(*(simplex_sort_simulator.top())).c_str());
+ simplex_sort_simulator.process();
+ } else
+ {
+ rLog(rlARVineyardComputing, "Current time before: %lf (trajectory sort)", trajectory_sort_simulator.current_time());
+ rLog(rlARVineyardComputing, "Top event: %s (trajectory sort)", intostring(*(trajectory_sort_simulator.top())).c_str());
+ trajectory_sort_simulator.process();
+ }
}
vineyard_->record_diagram(filtration_->begin(), filtration_->end());
--- a/include/geometry/simulator.h Fri Feb 29 14:39:48 2008 -0500
+++ b/include/geometry/simulator.h Fri Feb 29 15:46:12 2008 -0500
@@ -33,8 +33,7 @@
Simulator(Time start = FunctionKernel::root(0)):
- current_(start),
- reached_infinity_(false) {}
+ current_(start) {}
template<class Event_>
@@ -49,7 +48,10 @@
Time current_time() const { return current_; }
Time audit_time() const;
- bool reached_infinity() const { return reached_infinity_; }
+ bool reached_infinity() const { return queue_.empty() || (*queue_.top())->root_stack().empty(); }
+
+ Event* top() const { return *(queue_.top()); }
+ unsigned size() const { return queue_.size(); }
std::ostream& operator<<(std::ostream& out) const;
@@ -59,7 +61,6 @@
private:
Time current_;
EventQueue queue_;
- bool reached_infinity_;
};
--- a/include/geometry/simulator.hpp Fri Feb 29 14:39:48 2008 -0500
+++ b/include/geometry/simulator.hpp Fri Feb 29 15:46:12 2008 -0500
@@ -29,7 +29,7 @@
{
Event* ee = new Event_(e);
rLog(rlSimulator, "Solving: %s", tostring(f).c_str());
- int sign = FunctionKernel::sign_at_negative_infinity(f);
+ int sign = FunctionKernel::sign_at_negative_infinity(f); // going to be sign after current time
rLog(rlSimulator, "Sign at -infinity: %i", sign);
if (sign != 0)
{
@@ -44,8 +44,9 @@
}
if (sign == -1)
{
- AssertMsg(ee->root_stack().top() == current_time(),
- "If sign is negative, we must be in the degenerate case");
+ //AssertMsg(ee->root_stack().top() == current_time(),
+ // "If sign is negative, we must be in the degenerate case");
+ rLog(rlSimulator, "Popping the root because of negative sign (degeneracy)");
ee->root_stack().pop();
}
@@ -78,13 +79,13 @@
process()
{
Count(cSimulatorProcess);
+ if (reached_infinity()) return;
rLog(rlSimulator, "Queue size: %i", queue_.size());
Key top = queue_.top();
Event* e = *top;
rLog(rlSimulator, "Processing event: %s", intostring(*e).c_str());
- if (e->root_stack().empty()) { reached_infinity_ = true; return; }
- else { current_ = e->root_stack().top(); e->root_stack().pop(); }
+ current_ = e->root_stack().top(); e->root_stack().pop();
// Get the top element out of the queue, put it back depending on what process() says
EventQueue tmp; tmp.prepend(top, queue_);