19 template <
class T,
class solution_t >
20 gsAPALMData<T,solution_t>::gsAPALMData(
const std::vector<T> & times,
21 const std::vector<solution_t> & solutions)
26 GISMO_ASSERT(times.size()==solutions.size(),
"Sizes must agree");
28 setData(times,solutions);
33 template <
class T,
class solution_t >
34 gsAPALMData<T,solution_t>::gsAPALMData(
const std::vector<T> & times)
40 m_t = gsKnotVector<T>(times);
47 template <
class T,
class solution_t >
48 gsAPALMData<T,solution_t>::gsAPALMData()
54 m_t = gsKnotVector<T>(0);
57 template <
class T,
class solution_t >
58 void gsAPALMData<T,solution_t>::_defaultOptions()
63 m_options.addInt(
"MaxLevel",
"Sets the maximum level for hierarchical refinement",m_maxLevel);
64 m_options.addReal(
"Tolerance",
"Relative tolerance",m_tolerance);
65 m_options.addInt(
"Verbose",
"Verbosity; 0=none, 1=minimal, 2=full",m_verbose);
68 template <
class T,
class solution_t >
69 void gsAPALMData<T,solution_t>::_applyOptions()
71 m_maxLevel = m_options.getInt(
"MaxLevel");
72 m_tolerance = m_options.getReal(
"Tolerance");
73 m_verbose = m_options.getInt(
"Verbose");
77 template <
class T,
class solution_t >
78 void gsAPALMData<T,solution_t>::init()
80 this->_applyOptions();
82 std::deque<std::tuple<T,T,index_t>> queue;
86 for (
typename gsKnotVector<T>::const_iterator it = m_xi.begin(); it != std::prev(m_xi.end()); )
91 m_queue.push_back({low,upp,1});
99 template <
class T,
class solution_t >
100 void gsAPALMData<T,solution_t>::addStartPoint(
const T & time,
const solution_t & solution,
bool priority)
102 GISMO_ASSERT(m_t.size()==m_xi.size(),
"Sizes must be the same!");
103 GISMO_ASSERT(m_t.size()==0,
"Start point can only be added in a new branch");
104 this->_applyOptions();
109 auto sol = std::make_shared<solution_t>(solution);
110 m_solutions.insert({xi,sol});
111 m_levels.insert({xi,0});
113 auto prev = std::make_shared<solution_t>(*(m_solutions[xi]).
get());
114 m_prevs .insert({xi,prev});
118 m_queue.push_front({xi,xi,0});
120 m_queue.push_back({xi,xi,0});
121 m_initialized =
true;
124 template <
class T,
class solution_t >
125 void gsAPALMData<T,solution_t>::appendPoint(
bool priority)
129 m_queue.push_front({m_xi.last(),m_xi.last(),0});
131 m_queue.push_back({m_xi.last(),m_xi.last(),0});
132 m_initialized =
true;
135 template <
class T,
class solution_t >
136 void gsAPALMData<T,solution_t>::appendData(
const T & time,
const solution_t & solution,
bool priority)
139 GISMO_ASSERT(m_t.size()==m_xi.size(),
"Sizes must be the same!");
140 GISMO_ASSERT(m_t.size()==0 || time>m_t.last(),
"Time must be bigger than last stored time!");
144 else if (m_t.size()==1)
147 xi = (time-m_t.last()) * (m_xi.last()-m_xi.first()) / (m_t.last()-m_t.first()) + m_xi.last();
149 auto sol = std::make_shared<solution_t>(solution);
150 m_solutions.insert({xi,sol});
151 m_levels.insert({xi,0});
156 auto prev = std::make_shared<solution_t>(*(m_solutions[xi]).
get());
157 m_prevs .insert({xi,prev});
161 auto prev = std::make_shared<solution_t>(*(m_solutions[m_xi.last()]).
get());
162 m_prevs .insert({xi,prev});
164 m_queue.push_front({m_xi.last(),xi,1});
166 m_queue.push_back({m_xi.last(),xi,1});
167 m_initialized =
true;
177 template <
class T,
class solution_t >
178 void gsAPALMData<T,solution_t>::setData(
const std::vector<T> & times,
const std::vector<solution_t> & solutions)
181 m_t = gsKnotVector<T>(times);
185 auto sol0 = std::make_shared<solution_t>(solutions.at(0));
186 m_solutions.insert({m_xi.at(0),sol0});
187 m_levels.insert({m_xi.at(0),0});
188 auto prev0 = std::make_shared<solution_t>(*(m_solutions[m_xi.at(0)]).
get());
189 m_prevs .insert({m_xi.at(0),prev0});
190 for (
size_t k=1; k!=m_xi.size(); ++k)
192 auto solk = std::make_shared<solution_t>(solutions.at(k));
193 m_solutions.insert({m_xi.at(k),solk});
194 m_levels.insert({m_xi.at(k),0});
195 auto prevk = std::make_shared<solution_t>(*(m_solutions[m_xi.at(k-1)]).
get());
196 m_prevs .insert({m_xi.at(k),prevk});
207 template <
class T,
class solution_t >
208 void gsAPALMData<T,solution_t>::init(
const std::vector<T> & times,
const std::vector<solution_t> & solutions)
210 setData(times,solutions);
214 template <
class T,
class solution_t >
215 std::tuple<index_t, T , solution_t, solution_t> gsAPALMData<T,solution_t>::pop()
217 GISMO_ASSERT(m_initialized,
"Structure is not initialized");
218 GISMO_ASSERT(!m_queue.empty(),
"The queue is empty! Something went wrong.");
220 T xilow = std::get<0>(m_queue.front());
221 T xiupp = std::get<1>(m_queue.front());
222 index_t level = std::get<2>(m_queue.front());
225 T tlow = m_tmap[xilow];
226 T tupp = m_tmap[xiupp];
229 if (xilow==xiupp && level==0)
234 GISMO_ASSERT(m_solutions.count(xilow)!=0,
"Cannot find start point at tstart = "<<tlow<<
"\n");
235 GISMO_ASSERT(m_prevs .count(xilow)!=0,
"Cannot find previous solution for tstart = "<<tlow<<
"\n");
237 solution_t start = *(m_solutions[xilow].get());
239 solution_t prev = *(m_prevs[xilow].get());
242 m_jobs[m_ID++] = std::make_tuple(xilow,xiupp,level);
243 if (m_verbose==2)
gsInfo<<
"Got active job (ID="<<m_ID-1<<
") on interval = ["<<xilow<<
","<<xiupp<<
"] = ["<<tlow<<
","<<tupp<<
"] with level "<<level<<
"\n";
245 for (
typename std::map<
index_t,std::tuple<T,T,index_t>>::const_iterator it = m_jobs.begin(); it!=m_jobs.end(); it++)
247 std::tie(xilow,xiupp,level) = it->second;
248 gsDebug<<
"job "<<it->first<<
" on ["<<xilow<<
","<<xiupp<<
"] = ["<<tlow<<
","<<tupp<<
"] with level "<<level<<
"\n";
251 return std::make_tuple(m_ID-1, dt, start, prev);
254 template <
class T,
class solution_t >
255 bool gsAPALMData<T,solution_t>::getReferenceByTime(T time, solution_t & result)
257 if (m_solutions.count(m_ximap[time])!=0)
259 result = *(m_solutions[m_ximap[time]].get());
266 template <
class T,
class solution_t >
267 bool gsAPALMData<T,solution_t>::getReferenceByPar(T xi, solution_t & result)
269 if (m_solutions.count(xi)!=0)
271 result = *(m_solutions[xi].get());
278 template <
class T,
class solution_t >
279 bool gsAPALMData<T,solution_t>::getReferenceByID(
index_t ID, solution_t & result)
281 if (m_solutions.count(std::get<1>(m_jobs[ID]))!=0)
283 result = *(m_solutions[std::get<1>(m_jobs[ID])].
get());
290 template <
class T,
class solution_t >
291 void gsAPALMData<T,solution_t>::submit(
index_t ID,
const std::vector<T> & distances, std::vector<solution_t> solutions,
const T & upperDistance,
const T & lowerDistance)
293 GISMO_ASSERT(m_initialized,
"Structure is not initialized");
294 GISMO_ASSERT(distances.size()==solutions.size()+1,
"You must provide one more distance than solutions");
315 T tlow, tupp, xilow, xiupp, dxi, Dt, dt;
320 std::tie(xilow,xiupp,level) = m_jobs[ID];
321 tlow = m_tmap[xilow];
322 tupp = m_tmap[xiupp];
330 t.resize(distances.size()+1);
332 for (
size_t k=0; k!=distances.size(); k++)
333 t.at(k+1) = t.at(k) + distances.at(k);
336 T dt_tmp = std::accumulate(distances.begin(), std::prev(distances.end()), 0.0);
337 GISMO_ENSURE((Dt-dt_tmp)/Dt<1e-12,
"Total distance of the computed intervals should be equal to the original interval length ("<<dt_tmp<<
"!="<<Dt<<
")");
345 T totalError = dt-upperDistance;
346 T lowerError = Dt-lowerDistance;
347 T upperError = totalError-lowerError;
357 xi.resize(solutions.size()+2);
360 for (
size_t k=1; k!=xi.size()-1; k++)
361 xi.at(k) = xilow + dxi * ( t.at(k) - t.front() ) / dt;
368 gsInfo<<
"Relative errors:\n";
369 gsInfo<<
"\tlowerError/dt = "<<lowerError/dt<<
"\n";
370 gsInfo<<
"\tupperError/dt = "<<upperError/dt<<
"\n";
375 GISMO_ASSERT(lowerError/dt<m_tolerance,
"Lower error is larger than total error. How is this possible?");
376 t .erase(t .end()-2);
377 xi.erase(xi.end()-2);
378 solutions.erase(solutions.end()-1);
385 size_t kmax = xi.size();
386 if (lowerError/Dt<m_tolerance)
388 if (upperError/Dt<m_tolerance)
390 for (
size_t k = kmin; k!=kmax; k++)
392 if (level < m_maxLevel)
394 m_queue.push_back(std::make_tuple(xi.at(k-1),xi.at(k),level+1));
395 if (m_verbose==1)
gsInfo<<
"Interval ["<<xi.at(k-1)<<
","<<xi.at(k)<<
"] on level "<<level+1<<
" added to queue\n";
399 if (m_verbose==1)
gsInfo<<
"Interval ["<<xi.at(k-1)<<
","<<xi.at(k)<<
"] on level "<<level+1<<
" NOT added to queue (max level reached)\n";
410 m_t.addConstant(tupp,dt-Dt);
412 for (
size_t k=1; k!=t.size()-1; k++)
415 m_xi.insert(xi.at(k));
420 for (
size_t k=1; k!=xi.size()-1; k++)
422 if (m_verbose==2)
gsInfo<<
"Added a solution on time = "<<m_tmap[xi.at(k)]<<
" (parametric time = "<<xi.at(k)<<
")\n";
423 m_solutions[xi.at(k)] = std::make_shared<solution_t>(solutions.at(k-1));
424 m_levels[xi.at(k)] = level;
428 for (
size_t k=1; k!=xi.size()-1; k++)
430 if (m_verbose==2)
gsInfo<<
"Added a previous solution on time = "<<m_tmap[xi.at(k)]<<
" (parametric time = "<<xi.at(k)<<
")\n";
431 m_prevs[xi.at(k)] = std::make_shared<solution_t>(*(m_solutions[xi.at(k-1)].get()));
435 template <
class T,
class solution_t >
436 T gsAPALMData<T,solution_t>::jobStartTime(
index_t ID)
438 return m_tmap[std::get<0>(m_jobs[ID])];
441 template <
class T,
class solution_t >
442 T gsAPALMData<T,solution_t>::jobStartPar(
index_t ID)
444 return std::get<0>(m_jobs[ID]);
447 template <
class T,
class solution_t >
448 std::pair<T,T> gsAPALMData<T,solution_t>::jobTimes(
index_t ID)
451 std::tie(xilow,xiupp,std::ignore) = m_jobs[ID];
452 return std::make_pair(m_tmap[xilow],m_tmap[xiupp]);
456 template <
class T,
class solution_t >
457 std::pair<T,T> gsAPALMData<T,solution_t>::jobPars(
index_t ID)
460 std::tie(xilow,xiupp,std::ignore) = m_jobs[ID];
461 return std::make_pair(xilow,xiupp);
464 template <
class T,
class solution_t >
467 return std::get<2>(m_jobs[ID]);
470 template <
class T,
class solution_t >
471 void gsAPALMData<T,solution_t>::printActiveJobs()
473 for (
typename std::map<
index_t,std::tuple<T,T,index_t>>::const_iterator it = m_jobs.cbegin(); it!= m_jobs.cend(); it++)
475 gsInfo<<
"ID = "<<it->first<<
": xilow = "<<std::get<0>(it->second)<<
"; xiupp = "<<std::get<1>(it->second)<<
"; level = "<<std::get<2>(it->second)<<
"\n";
479 template <
class T,
class solution_t >
480 void gsAPALMData<T,solution_t>::finishJob(
index_t ID)
483 if (m_verbose==2)
gsInfo<<
"Erasing finished job on level = "<<std::get<0>(m_jobs[ID])
484 <<
"; time = "<<std::get<1>(m_jobs[ID])<<
"\n";
488 gsDebug<<
"Current active jobs\n";
489 for (
typename std::map<
index_t,std::tuple<T,T,index_t>>::const_iterator it = m_jobs.begin(); it!=m_jobs.end(); ++it)
490 gsDebug<<
"ID = "<<it->first<<
"; xilow = "<<std::get<0>(it->second)<<
"; xiupp = "<<std::get<1>(it->second)<<
"; level = "<<std::get<2>(it->second)<<
"\n";
494 template <
class T,
class solution_t >
495 bool gsAPALMData<T,solution_t>::empty()
497 return m_queue.empty();
500 template <
class T,
class solution_t >
501 std::tuple<std::vector<T>,std::vector<solution_t>,std::vector<index_t>> gsAPALMData<T,solution_t>::getFlatSolution(
index_t level)
503 std::vector<T> times;
504 std::vector<solution_t> solutions;
505 std::vector<index_t> levels;
507 for (
typename std::map<T,std::shared_ptr<solution_t>>::const_iterator
508 it = m_solutions.begin();
509 it!=m_solutions.end();
512 if (m_levels[it->first]==level || level==-1)
514 times.push_back(m_tmap[it->first]);
515 solutions.push_back(*(it->second.get()));
516 levels.push_back(m_levels[it->first]);
519 return std::make_tuple(times,solutions,levels);
522 template <
class T,
class solution_t >
523 void gsAPALMData<T,solution_t>::print()
525 for (
typename std::map<T,std::shared_ptr<solution_t>>::const_iterator
526 it = m_solutions.begin();
527 it!=m_solutions.end();
531 gsInfo<<
"time = "<<it->first<<
"\n";
535 template <
class T,
class solution_t >
536 void gsAPALMData<T,solution_t>::printQueue()
538 std::deque<std::tuple<T,T,index_t>> queue = m_queue;
539 gsInfo<<
"Queue has "<<queue.size()<<
" elements\n";
540 while (!queue.empty())
542 gsInfo<<
"Start time "<<std::get<0>(queue.front())
543 <<
"; end time = "<<std::get<1>(queue.front())
544 <<
"; level = "<<std::get<2>(queue.front())<<
"\n";
547 gsInfo<<
"Queue is empty\n";
550 template <
class T,
class solution_t >
551 void gsAPALMData<T,solution_t>::printKnots()
553 gsInfo<<
"xi = \n"<<m_xi.asMatrix()<<
"\n";
554 gsInfo<<
"t = \n"<<m_t.asMatrix()<<
"\n";
557 template <
class T,
class solution_t >
558 std::tuple<T,T,index_t> gsAPALMData<T,solution_t>::_activeJob(
index_t ID)
560 if (m_jobs.count(ID) == 1)
562 else if (m_jobs.count(ID) > 1)
564 gsWarn<<
"Multiple jobs with ID "<<ID<<
" exist! Did something go wrong?\n";
568 GISMO_ERROR(
"No job found with ID "<<ID<<
". Did something go wrong?");
571 template <
class T,
class solution_t >
572 void gsAPALMData<T,solution_t>::_buildMap()
574 GISMO_ASSERT(m_xi.size()==m_t.size(),
"Time and parametric time don't have equal length");
577 for (
size_t k=0; k!=m_xi.size(); k++)
579 m_tmap.insert({m_xi[k],m_t[k]});
580 m_ximap.insert({m_t[k],m_xi[k]});
#define gsDebug
Definition: gsDebug.h:61
#define index_t
Definition: gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
#define gsWarn
Definition: gsDebug.h:50
#define gsInfo
Definition: gsDebug.h:43
#define GISMO_ERROR(message)
Definition: gsDebug.h:118