n-Dimensional Fast Methods  0.7
 All Classes Functions Variables Typedefs Pages
fsm.hpp
1 
31 #ifndef FSM_HPP_
32 #define FSM_HPP_
33 
34 #include <algorithm>
35 
36 #include <fast_methods/fm/eikonalsolver.hpp>
37 #include <fast_methods/utils/utils.h>
38 
39 
41 template < class grid_t > class FSM : public EikonalSolver<grid_t> {
42 
43  public:
44  FSM(unsigned maxSweeps = std::numeric_limits<unsigned>::max()) : EikonalSolver<grid_t>("FSM"),
45  sweeps_(0),
46  maxSweeps_(maxSweeps) {}
47 
48  FSM(const char * name, unsigned maxSweeps = std::numeric_limits<unsigned>::max()) : EikonalSolver<grid_t>(name),
49  sweeps_(0),
50  maxSweeps_(maxSweeps) {}
51 
54  virtual void setEnvironment
55  (grid_t * g) {
57  // Filling the size of the dimensions...
58  std::array<unsigned, grid_t::getNDims()> dimsize = g->getDimSizes();
59  size_t ncells = 1;
60  for (size_t i = 0; i < grid_t::getNDims(); ++i) {
61  dimsize_[i] = dimsize[i];
62  ncells *= dimsize[i];
63  d_[i] = ncells;
64  }
65 
66  Tvalues_.reserve(grid_t::getNDims());
67  }
68 
70  virtual void setup
71  () {
74  if (int(goal_idx_) != -1)
75  console::warning("Setting a goal point in FSM (and LSM) is experimental. It may lead to wrong results.");
76  }
77 
79  virtual void computeInternal
80  () {
81  if (!setup_)
82  setup();
83 
84  // Initialization
85  for (unsigned int i: init_points_) // For each initial point
86  grid_->getCell(i).setArrivalTime(0);
87 
88  keepSweeping_ = true;
89  stopPropagation_ = false;
90 
92  keepSweeping_ = false;
93  setSweep();
94  ++sweeps_;
95  recursiveIteration(grid_t::getNDims()-1);
96  }
97  }
98 
99  virtual void reset
100  () {
102  sweeps_ = 0;
104  }
105 
106  virtual void printRunInfo
107  () const {
108  console::info("Fast Sweeping Method");
109  std::cout << '\t' << name_ << '\n'
110  << '\t' << "Maximum sweeps: " << maxSweeps_ << '\n'
111  << '\t' << "Sweeps performed: " << sweeps_ << '\n'
112  << '\t' << "Elapsed time: " << time_ << " ms\n";
113  }
114 
115  protected:
118  void recursiveIteration
119  (size_t depth, int it = 0) {
120  if (depth > 0) {
121  for(int i = inits_[depth]; i != ends_[depth]; i += incs_[depth])
122  recursiveIteration(depth-1, it + i*d_[depth-1]);
123  }
124  else {
125  for(int i = inits_[0]; i != ends_[0]; i += incs_[0])
126  if (!grid_->getCell(it+i).isOccupied())
127  solveForIdx(it+i);
128  }
129  }
130 
132  virtual void solveForIdx
133  (unsigned idx) {
134  const double prevTime = grid_->getCell(idx).getArrivalTime();
135  const double newTime = solveEikonal(idx);
136  if(utils::isTimeBetterThan(newTime, prevTime)) {
137  grid_->getCell(idx).setArrivalTime(newTime);
138  keepSweeping_ = true;
139  }
140  // EXPERIMENTAL - Value not updated, it has converged
141  else if(!isnan(newTime) && !isinf(newTime) && (idx == goal_idx_))
142  stopPropagation_ = true;
143  }
144 
152  virtual void setSweep
153  () {
154  // Inspired in http://stackoverflow.com/a/17758788/2283531
155  for (size_t i = 0; i < grid_t::getNDims(); ++i)
156  {
157  if((incs_[i] += 2) <=1)
158  break;
159  else
160  incs_[i] = -1;
161  }
162 
163  // Setting inits and ends.
164  for (size_t i = 0; i < grid_t::getNDims(); ++i)
165  {
166  if (incs_[i] == 1)
167  {
168  inits_[i] = 0;
169  ends_[i] = dimsize_[i];
170  }
171  else
172  {
173  inits_[i] = dimsize_[i]-1;
174  ends_[i] = -1;
175  }
176  }
177  }
178 
180  virtual void initializeSweepArrays
181  () {
182  for (size_t i = 0; i < grid_t::getNDims(); ++i) {
183  incs_[i] = 1;
184  inits_[i] = 0;
185  ends_[i] = 1;
186  }
187  }
188 
197 
199  unsigned int sweeps_;
200 
202  unsigned maxSweeps_;
203 
206 
209 
211  std::array<int, grid_t::getNDims()> incs_;
212 
214  std::array<int, grid_t::getNDims()> inits_;
215 
217  std::array<int, grid_t::getNDims()> ends_;
218 
220  std::array<int, grid_t::getNDims()> dimsize_;
221 
224  std::array<int, grid_t::getNDims()> d_;
225 };
226 
227 #endif /* FSM_HPP_*/
Implements Fast Sweeping Method.
Definition: fsm.hpp:41
Abstract class that serves as interface for the actual EikonalSolvers implemented. It requires (at least) the computeInternal method to be implemented,.
std::array< int, grid_t::getNDims()> dimsize_
Size of each dimension, extended to the maximum size. Extended dimensions always 1.
Definition: fsm.hpp:220
std::array< int, grid_t::getNDims()> d_
Auxiliar array to speed up indexing generalization: stores parcial multiplications of dimensions size...
Definition: fsm.hpp:224
double time_
Time elapsed by the compute method.
Definition: solver.hpp:237
virtual void setEnvironment(grid_t *g)
Sets and cleans the grid in which operations will be performed.
Definition: solver.hpp:51
virtual void setup()
Checks that the solver is ready to run. Sets the grid unclean.
Definition: solver.hpp:94
std::array< int, grid_t::getNDims()> incs_
Sweep directions {-1,1} for each dimension. Extended dimensions always 1.
Definition: fsm.hpp:211
virtual void computeInternal()
Actual method that implements FSM.
Definition: fsm.hpp:80
virtual double solveEikonal(const int &idx)
Solves nD Eikonal equation for cell idx. If heuristics are activated, it will add the estimated trave...
virtual void setup()
Executes EikonalSolver setup and other checks.
Definition: fsm.hpp:71
virtual void solveForIdx(unsigned idx)
Actually executes one solving iteration of the FSM.
Definition: fsm.hpp:133
virtual void reset()
Clears temporal data, so it is ready to run again.
Definition: fsm.hpp:100
std::array< int, grid_t::getNDims()> ends_
Final indices for each dimension. Extended dimensions always 1.
Definition: fsm.hpp:217
grid_t * grid_
Grid container.
Definition: solver.hpp:219
bool stopPropagation_
Flag to stop sweeping (used when goal point has converged).
Definition: fsm.hpp:208
static void info(const std::string &val)
std::vector< unsigned int > init_points_
Initial index.
Definition: solver.hpp:228
virtual void setEnvironment(grid_t *g)
Sets and cleans the grid in which operations will be performed. Since a maximum number of dimensions ...
Definition: fsm.hpp:55
void recursiveIteration(size_t depth, int it=0)
Equivalent to nesting as many for loops as dimensions. For every most inner loop iteration, solveForIdx() is called for the corresponding idx.
Definition: fsm.hpp:119
std::string name_
Solver name.
Definition: solver.hpp:222
unsigned int sweeps_
Number of sweeps performed.
Definition: fsm.hpp:199
bool keepSweeping_
Flag to indicate that at least one more sweep is required.
Definition: fsm.hpp:205
static bool isTimeBetterThan(double t1, double t2)
Returns true if t1 is at least epsilon-lower than t2, provides robust comparions for doubles...
Definition: utils.h:32
virtual void setSweep()
Set the sweep variables: initial and final indices for iterations, and the increment of each iteratio...
Definition: fsm.hpp:153
std::vector< double > Tvalues_
Auxiliar vector with values T0,T1...Tn-1 variables in the Discretized Eikonal Equation.
bool setup_
Setup status.
Definition: solver.hpp:225
unsigned int goal_idx_
Goal index.
Definition: solver.hpp:231
virtual void initializeSweepArrays()
Initializes the internal arrays employed.
Definition: fsm.hpp:181
unsigned maxSweeps_
Number of maximum sweeps to perform.
Definition: fsm.hpp:202
static void warning(const std::string &val)
std::array< int, grid_t::getNDims()> inits_
Initial indices for each dimension. Extended dimensions always 0.
Definition: fsm.hpp:214
virtual void reset()
Clears temporal data, so it is ready to run again.
Definition: solver.hpp:176