Using two simulators in ARVineyard (one for simplices and one for trajectories) ar
authorDmitriy Morozov <morozov@cs.duke.edu>
Fri, 29 Feb 2008 15:46:12 -0500
branchar
changeset 80 f236c7d659d0
parent 79 e48a7036cd88
child 81 abba2950aced
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
.issues/c664b2f69b5f6ea3
examples/ar-vineyard/ar-vineyard.h
examples/ar-vineyard/ar-vineyard.hpp
include/geometry/simulator.h
include/geometry/simulator.hpp
--- /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_);