11 #include <QApplication>
13 #include "DECExamplesCommon.h"
16 #include "DGtal/math/linalg/EigenSupport.h"
17 #include "DGtal/dec/DiscreteExteriorCalculus.h"
18 #include "DGtal/dec/DiscreteExteriorCalculusSolver.h"
19 #include "DGtal/dec/DiscreteExteriorCalculusFactory.h"
21 #include "DGtal/io/viewers/Viewer3D.h"
22 #include "DGtal/io/boards/Board2D.h"
23 #include "DGtal/io/readers/GenericReader.h"
25 using namespace DGtal;
28 void solve2d_laplace()
38 Calculus calculus = CalculusFactory::createFromDigitalSet(generateRingSet(domain));
43 Calculus::DualIdentity0 laplace = calculus.laplace<
DUAL>() + 0.01 * calculus.identity<0,
DUAL>();
45 trace.
info() <<
"laplace = " << laplace << endl;
48 Calculus::DualForm0 dirac(calculus);
49 dirac.myContainer(calculus.getCellIndex( calculus.myKSpace.uSpel(
Z2i::Point(2,5))) ) = 1;
56 board.
saveSVG(
"solve_laplace_calculus.svg");
68 Calculus::DualForm0 solution = solver.
solve(dirac);
70 trace.
info() << solver.isValid() <<
" " << solver.myLinearAlgebraSolver.info() << endl;
78 board.
saveSVG(
"solve_laplace_simplicial_llt.svg");
90 Calculus::DualForm0 solution = solver.
solve(dirac);
92 trace.
info() << solver.isValid() <<
" " << solver.myLinearAlgebraSolver.info() << endl;
100 board.
saveSVG(
"solve_laplace_simplicial_ldlt.svg");
112 Calculus::DualForm0 solution = solver.
solve(dirac);
115 trace.
info() << solver.isValid() <<
" " << solver.myLinearAlgebraSolver.info() << endl;
122 board.
saveSVG(
"solve_laplace_conjugate_gradient.svg");
134 Calculus::DualForm0 solution = solver.
solve(dirac);
137 trace.
info() << solver.isValid() <<
" " << solver.myLinearAlgebraSolver.info() << endl;
144 board.
saveSVG(
"solve_laplace_bicgstab.svg");
156 Calculus::DualForm0 solution = solver.
solve(dirac);
159 trace.
info() << solver.isValid() <<
" " << solver.myLinearAlgebraSolver.info() << endl;
166 board.
saveSVG(
"solve_laplace_sparse_lu.svg");
178 Calculus::DualForm0 solution = -solver.
solve(dirac);
181 trace.
info() << solver.isValid() <<
" " << solver.myLinearAlgebraSolver.info() << endl;
188 board.
saveSVG(
"solve_laplace_sparse_qr.svg");
194 void solve2d_dual_decomposition()
196 trace.
beginBlock(
"2d discrete exterior calculus solve dual helmoltz decomposition");
203 Calculus calculus = CalculusFactory::createFromDigitalSet(generateDoubleRingSet(domain));
210 const Calculus::DualDerivative0 d0 = calculus.derivative<0,
DUAL>();
211 const Calculus::DualDerivative1 d1 = calculus.derivative<1,
DUAL>();
212 const Calculus::PrimalDerivative0 d0p = calculus.derivative<0,
PRIMAL>();
213 const Calculus::PrimalDerivative1 d1p = calculus.derivative<1,
PRIMAL>();
214 const Calculus::DualHodge1 h1 = calculus.hodge<1,
DUAL>();
215 const Calculus::DualHodge2 h2 = calculus.hodge<2,
DUAL>();
216 const Calculus::PrimalHodge1 h1p = calculus.hodge<1,
PRIMAL>();
217 const Calculus::PrimalHodge2 h2p = calculus.hodge<2,
PRIMAL>();
223 Calculus::DualVectorField input_vector_field(calculus);
224 for (Calculus::Index ii=0; ii<input_vector_field.length(); ii++)
227 input_vector_field.myCoordinates(ii, 0) = cos(-.5*cell_center[0]+ .3*cell_center[1]);
228 input_vector_field.myCoordinates(ii, 1) = cos(.4*cell_center[0]+ .8*cell_center[1]);
230 trace.
info() << input_vector_field << endl;
232 const Calculus::DualForm1 input_one_form = calculus.flat(input_vector_field);
233 const Calculus::DualForm0 input_one_form_anti_derivated = ad1 * input_one_form;
234 const Calculus::DualForm2 input_one_form_derivated = d1 * input_one_form;
241 board <<
CustomStyle(
"KForm",
new KFormStyle2D(-1, 1));
242 board << input_one_form;
243 board <<
CustomStyle(
"VectorField",
new VectorFieldStyle2D(.75));
244 board << input_vector_field;
245 board.
saveSVG(
"solve_2d_dual_decomposition_calculus.svg");
249 Calculus::DualForm0 solution_curl_free(calculus);
257 solution_curl_free = solver.
solve(input_one_form_anti_derivated);
260 trace.
info() << solver.isValid() <<
" " << solver.myLinearAlgebraSolver.info() << endl;
261 trace.
info() <<
"min=" << solution_curl_free.myContainer.minCoeff() <<
" max=" << solution_curl_free.myContainer.maxCoeff() << endl;
269 board << solution_curl_free;
270 board <<
CustomStyle(
"VectorField",
new VectorFieldStyle2D(.75));
271 board << calculus.sharp(d0*solution_curl_free);
272 board.
saveSVG(
"solve_2d_dual_decomposition_curl_free.svg");
275 Calculus::DualForm2 solution_div_free(calculus);
283 solution_div_free = solver.
solve(input_one_form_derivated);
286 trace.
info() << solver.isValid() <<
" " << solver.myLinearAlgebraSolver.info() << endl;
287 trace.
info() <<
"min=" << solution_div_free.myContainer.minCoeff() <<
" max=" << solution_div_free.myContainer.maxCoeff() << endl;
295 board << solution_div_free;
296 board <<
CustomStyle(
"VectorField",
new VectorFieldStyle2D(1.5));
297 board << calculus.sharp(ad2*solution_div_free);
298 board.
saveSVG(
"solve_2d_dual_decomposition_div_free.svg");
302 const Calculus::DualForm1 solution_harmonic = input_one_form - d0*solution_curl_free - ad2*solution_div_free;
304 trace.
info() <<
"min=" << solution_harmonic.myContainer.minCoeff() <<
" max=" << solution_harmonic.myContainer.maxCoeff() << endl;
310 board << solution_harmonic;
311 board <<
CustomStyle(
"VectorField",
new VectorFieldStyle2D(20));
312 board << calculus.sharp(solution_harmonic);
313 board.
saveSVG(
"solve_2d_dual_decomposition_harmonic.svg");
319 void solve2d_primal_decomposition()
321 trace.
beginBlock(
"2d discrete exterior calculus solve primal helmoltz decomposition");
328 Calculus calculus = CalculusFactory::createFromDigitalSet(generateDoubleRingSet(domain));
335 const Calculus::PrimalDerivative0 d0 = calculus.derivative<0,
PRIMAL>();
336 const Calculus::PrimalDerivative1 d1 = calculus.derivative<1,
PRIMAL>();
337 const Calculus::DualDerivative0 d0p = calculus.derivative<0,
DUAL>();
338 const Calculus::DualDerivative1 d1p = calculus.derivative<1,
DUAL>();
339 const Calculus::PrimalHodge1 h1 = calculus.hodge<1,
PRIMAL>();
340 const Calculus::PrimalHodge2 h2 = calculus.hodge<2,
PRIMAL>();
341 const Calculus::DualHodge1 h1p = calculus.hodge<1,
DUAL>();
342 const Calculus::DualHodge2 h2p = calculus.hodge<2,
DUAL>();
348 Calculus::PrimalVectorField input_vector_field(calculus);
349 for (Calculus::Index ii=0; ii<input_vector_field.length(); ii++)
352 input_vector_field.myCoordinates(ii, 0) = cos(-.5*cell_center[0]+ .3*cell_center[1]);
353 input_vector_field.myCoordinates(ii, 1) = cos(.4*cell_center[0]+ .8*cell_center[1]);
355 trace.
info() << input_vector_field << endl;
357 const Calculus::PrimalForm1 input_one_form = calculus.flat(input_vector_field);
358 const Calculus::PrimalForm0 input_one_form_anti_derivated = ad1 * input_one_form;
359 const Calculus::PrimalForm2 input_one_form_derivated = d1 * input_one_form;
366 board << input_one_form;
367 board <<
CustomStyle(
"VectorField",
new VectorFieldStyle2D(.75));
368 board << input_vector_field;
369 board.
saveSVG(
"solve_2d_primal_decomposition_calculus.svg");
373 Calculus::PrimalForm0 solution_curl_free(calculus);
381 solution_curl_free = solver.
solve(input_one_form_anti_derivated);
384 trace.
info() << solver.isValid() <<
" " << solver.myLinearAlgebraSolver.info() << endl;
385 trace.
info() <<
"min=" << solution_curl_free.myContainer.minCoeff() <<
" max=" << solution_curl_free.myContainer.maxCoeff() << endl;
393 board << solution_curl_free;
394 board <<
CustomStyle(
"VectorField",
new VectorFieldStyle2D(.75));
395 board << calculus.sharp(d0*solution_curl_free);
396 board.
saveSVG(
"solve_2d_primal_decomposition_curl_free.svg");
399 Calculus::PrimalForm2 solution_div_free(calculus);
407 solution_div_free = solver.
solve(input_one_form_derivated);
410 trace.
info() << solver.isValid() <<
" " << solver.myLinearAlgebraSolver.info() << endl;
411 trace.
info() <<
"min=" << solution_div_free.myContainer.minCoeff() <<
" max=" << solution_div_free.myContainer.maxCoeff() << endl;
419 board << solution_div_free;
420 board <<
CustomStyle(
"VectorField",
new VectorFieldStyle2D(1.5));
421 board << calculus.sharp(ad2*solution_div_free);
422 board.
saveSVG(
"solve_2d_primal_decomposition_div_free.svg");
426 const Calculus::PrimalForm1 solution_harmonic = input_one_form - d0*solution_curl_free - ad2*solution_div_free;
428 trace.
info() <<
"min=" << solution_harmonic.myContainer.minCoeff() <<
" max=" << solution_harmonic.myContainer.maxCoeff() << endl;
434 board << solution_harmonic;
435 board <<
CustomStyle(
"VectorField",
new VectorFieldStyle2D(30));
436 board << calculus.sharp(solution_harmonic);
437 board.
saveSVG(
"solve_2d_primal_decomposition_harmonic.svg");
443 void solve3d_decomposition()
445 trace.
beginBlock(
"3d discrete exterior calculus solve helmoltz decomposition");
459 for (
int kk=2; kk<=18; kk++)
460 for (
int ll=4; ll<=36; ll++)
463 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(ll,4,kk));
464 const Dimension dim = calculus.myKSpace.uDim(cell);
465 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
469 sign = Calculus::KSpace::POS;
472 sign = Calculus::KSpace::NEG;
475 sign = Calculus::KSpace::NEG;
480 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
484 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(ll,36,kk));
485 const Dimension dim = calculus.myKSpace.uDim(cell);
486 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
490 sign = Calculus::KSpace::POS;
493 sign = Calculus::KSpace::POS;
496 sign = Calculus::KSpace::POS;
501 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
505 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(4,ll,kk));
506 const Dimension dim = calculus.myKSpace.uDim(cell);
507 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
511 sign = Calculus::KSpace::POS;
514 sign = ( *calculus.myKSpace.uDirs(cell) == 2 ? Calculus::KSpace::NEG : Calculus::KSpace::POS );
517 sign = Calculus::KSpace::NEG;
522 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
526 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(36,ll,kk));
527 const Dimension dim = calculus.myKSpace.uDim(cell);
528 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
532 sign = Calculus::KSpace::POS;
535 sign = ( *calculus.myKSpace.uDirs(cell) == 2 ? Calculus::KSpace::POS : Calculus::KSpace::NEG );
538 sign = Calculus::KSpace::POS;
543 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
549 for (
int kk=2; kk<=18; kk++)
550 for (
int ll=16; ll<=24; ll++)
553 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(ll,16,kk));
554 const Dimension dim = calculus.myKSpace.uDim(cell);
555 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
559 sign = Calculus::KSpace::POS;
562 sign = ( *calculus.myKSpace.uDirs(cell) == 0 ? Calculus::KSpace::NEG : Calculus::KSpace::POS );
565 sign = Calculus::KSpace::POS;
570 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
574 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(ll,24,kk));
575 const Dimension dim = calculus.myKSpace.uDim(cell);
576 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
580 sign = Calculus::KSpace::POS;
583 sign = ( *calculus.myKSpace.uDirs(cell) == 0 ? Calculus::KSpace::POS : Calculus::KSpace::NEG );
586 sign = Calculus::KSpace::NEG;
591 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
595 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(16,ll,kk));
596 const Dimension dim = calculus.myKSpace.uDim(cell);
597 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
601 sign = Calculus::KSpace::POS;
604 sign = Calculus::KSpace::POS;
607 sign = Calculus::KSpace::POS;
612 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
616 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(24,ll,kk));
617 const Dimension dim = calculus.myKSpace.uDim(cell);
618 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
622 sign = Calculus::KSpace::POS;
625 sign = Calculus::KSpace::NEG;
628 sign = Calculus::KSpace::NEG;
633 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
638 for (
int kk=4; kk<=36; kk++)
639 for (
int ll=0; ll<=12; ll++)
642 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(4+ll,kk,2));
643 const Dimension dim = calculus.myKSpace.uDim(cell);
644 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
648 sign = Calculus::KSpace::POS;
651 sign = Calculus::KSpace::POS;
654 sign = Calculus::KSpace::NEG;
659 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
663 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(4+ll,kk,18));
664 const Dimension dim = calculus.myKSpace.uDim(cell);
665 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
669 sign = Calculus::KSpace::POS;
672 sign = Calculus::KSpace::NEG;
675 sign = Calculus::KSpace::POS;
680 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
684 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(24+ll,kk,2));
685 const Dimension dim = calculus.myKSpace.uDim(cell);
686 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
690 sign = Calculus::KSpace::POS;
693 sign = Calculus::KSpace::POS;
696 sign = Calculus::KSpace::NEG;
701 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
705 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(24+ll,kk,18));
706 const Dimension dim = calculus.myKSpace.uDim(cell);
707 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
711 sign = Calculus::KSpace::POS;
714 sign = Calculus::KSpace::NEG;
717 sign = Calculus::KSpace::POS;
722 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
727 for (
int kk=0; kk<=12; kk++)
728 for (
int ll=16; ll<=24; ll++)
731 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(ll,4+kk,2));
732 const Dimension dim = calculus.myKSpace.uDim(cell);
733 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
737 sign = Calculus::KSpace::POS;
740 sign = Calculus::KSpace::POS;
743 sign = Calculus::KSpace::NEG;
748 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
752 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(ll,4+kk,18));
753 const Dimension dim = calculus.myKSpace.uDim(cell);
754 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
758 sign = Calculus::KSpace::POS;
761 sign = Calculus::KSpace::NEG;
764 sign = Calculus::KSpace::POS;
769 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
773 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(ll,24+kk,2));
774 const Dimension dim = calculus.myKSpace.uDim(cell);
775 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
779 sign = Calculus::KSpace::POS;
782 sign = Calculus::KSpace::POS;
785 sign = Calculus::KSpace::NEG;
790 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
794 const Calculus::Cell cell = calculus.myKSpace.uCell(
Z3i::Point(ll,24+kk,18));
795 const Dimension dim = calculus.myKSpace.uDim(cell);
796 Calculus::KSpace::Sign sign = Calculus::KSpace::POS;
800 sign = Calculus::KSpace::POS;
803 sign = Calculus::KSpace::NEG;
806 sign = Calculus::KSpace::POS;
811 calculus.insertSCell( calculus.myKSpace.signs(cell, sign) );
815 calculus.updateIndexes();
822 Viewer* viewer =
new Viewer(calculus.myKSpace);
824 viewer->setWindowTitle(
"structure");
832 const Calculus::PrimalDerivative0 d0 = calculus.derivative<0,
PRIMAL>();
833 const Calculus::PrimalDerivative1 d1 = calculus.derivative<1,
PRIMAL>();
834 const Calculus::DualDerivative1 d1p = calculus.derivative<1,
DUAL>();
835 const Calculus::DualDerivative2 d2p = calculus.derivative<2,
DUAL>();
836 const Calculus::PrimalHodge1 h1 = calculus.hodge<1,
PRIMAL>();
837 const Calculus::PrimalHodge2 h2 = calculus.hodge<2,
PRIMAL>();
838 const Calculus::DualHodge2 h2p = calculus.hodge<2,
DUAL>();
839 const Calculus::DualHodge3 h3p = calculus.hodge<3,
DUAL>();
845 const Calculus::PrimalIdentity0 laplace = calculus.laplace<
PRIMAL>();
846 const Eigen::VectorXd laplace_diag = laplace.myContainer.diagonal();
848 boost::array<int, 7> degrees;
849 std::fill(degrees.begin(), degrees.end(), 0);
850 for (
int kk=0; kk<laplace_diag.rows(); kk++)
852 const int degree = laplace_diag[kk];
853 ASSERT( degree >= 0 );
854 ASSERT( static_cast<unsigned int>(degree) < degrees.size() );
859 for (
int kk=0; kk<7; kk++)
860 trace.
info() << kk <<
" " << degrees[kk] << endl;
864 Calculus::PrimalVectorField input_vector_field(calculus);
865 for (Calculus::Index ii=0; ii<input_vector_field.length(); ii++)
868 input_vector_field.myCoordinates(ii, 0) = -cos(-.3*cell_center[0] + .6*cell_center[1] + .8*cell_center[2]);
869 input_vector_field.myCoordinates(ii, 1) = sin(.8*cell_center[0] + .3*cell_center[1] - .4*cell_center[2]);
870 input_vector_field.myCoordinates(ii, 2) = -cos(cell_center[2]*.5);
872 trace.
info() << input_vector_field << endl;
874 const Calculus::PrimalForm1 input_one_form = calculus.flat(input_vector_field);
876 const Calculus::PrimalForm0 input_one_form_anti_derivated = ad1 * input_one_form;
877 const Calculus::PrimalForm2 input_one_form_derivated = d1 * input_one_form;
881 Viewer* viewer =
new Viewer(calculus.myKSpace);
883 viewer->setWindowTitle(
"input vector field");
891 Calculus::PrimalForm0 solution_curl_free(calculus);
899 solution_curl_free = solver.
solve(input_one_form_anti_derivated);
902 trace.
info() << solver.isValid() <<
" " << solver.myLinearAlgebraSolver.info() << endl;
903 trace.
info() <<
"min=" << solution_curl_free.myContainer.minCoeff() <<
" max=" << solution_curl_free.myContainer.maxCoeff() << endl;
909 Viewer* viewer =
new Viewer(calculus.myKSpace);
911 viewer->setWindowTitle(
"curl free solution");
917 Calculus::PrimalForm2 solution_div_free(calculus);
925 solution_div_free = solver.
solve(input_one_form_derivated);
928 trace.
info() << solver.isValid() <<
" " << solver.myLinearAlgebraSolver.info() << endl;
929 trace.
info() <<
"min=" << solution_div_free.myContainer.minCoeff() <<
" max=" << solution_div_free.myContainer.maxCoeff() << endl;
935 Viewer* viewer =
new Viewer(calculus.myKSpace);
937 viewer->setWindowTitle(
"div free solution");
944 const Calculus::PrimalForm1 solution_harmonic = input_one_form - d0*solution_curl_free - ad2*solution_div_free;
946 trace.
info() <<
"min=" << solution_harmonic.myContainer.minCoeff() <<
" max=" << solution_harmonic.myContainer.maxCoeff() << endl;
950 Viewer* viewer =
new Viewer(calculus.myKSpace);
952 viewer->setWindowTitle(
"harmonic");
961 int main(
int argc,
char* argv[])
963 QApplication app(argc,argv);
966 solve2d_dual_decomposition();
967 solve2d_primal_decomposition();
968 solve3d_decomposition();
void beginBlock(const std::string &keyword="")
Aim: DiscreteExteriorCalculus represents a calculus in the dec package. This is the main structure in...
SolutionKForm solve(const InputKForm &input_kform) const
DGtal::uint32_t Dimension
Eigen::SparseQR< SparseMatrix, Eigen::COLAMDOrdering< SparseMatrix::Index > > SolverSparseQR
Eigen::ConjugateGradient< SparseMatrix > SolverConjugateGradient
static void draw(Display3D< Space, KSpace > &display, const DGtal::DiscreteExteriorCalculus< dimEmbedded, dimAmbient, TLinearAlgebraBackend, TInteger > &calculus)
DiscreteExteriorCalculusSolver & compute(const Operator &linear_operator)
Eigen::SimplicialLLT< SparseMatrix > SolverSimplicialLLT
Aim: This class provides static members to create DEC structures from various other DGtal structures...
Eigen::BiCGSTAB< SparseMatrix > SolverBiCGSTAB
Aim: LinearOperator represents discrete linear operator between discrete kforms in the DEC package...
DGtal is the top-level namespace which contains all DGtal functions and types.
void saveSVG(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Eigen::SimplicialLDLT< SparseMatrix > SolverSimplicialLDLT
void initKSpace(ConstAlias< TDomain > domain)
Structure representing an RGB triple with alpha component.
Space::RealPoint RealPoint
Aim: This wraps a linear algebra solver around a discrete exterior calculus.
virtual void show()
Overload QWidget method in order to add a call to updateList() method (to ensure that the lists are w...
Space::RealPoint RealPoint
Aim: This class specializes a 'Board' class so as to display DGtal objects more naturally (with <<)...
Eigen::SparseLU< SparseMatrix > SolverSparseLU