making sure that all matrix allocations happen at compile time when possible

This commit is contained in:
Konstantinos Katrioplas 2018-05-17 11:03:55 +02:00
parent 10c87d3326
commit 819e38d6a1
7 changed files with 52 additions and 75 deletions

View File

@ -1,7 +1,10 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h> #include <CGAL/Surface_mesh.h>
#include <CGAL/convex_hull_3.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Optimal_bounding_box/population.h> #include <CGAL/Optimal_bounding_box/population.h>
#include <CGAL/Optimal_bounding_box/obb.h> #include <CGAL/Optimal_bounding_box/obb.h>
#include <CGAL/Eigen_linear_algebra_traits.h>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
@ -41,6 +44,7 @@ void bench_finding_obb(std::string fname)
{ {
std::ifstream input(fname); std::ifstream input(fname);
CGAL::Eigen_linear_algebra_traits la_traits;
std::vector<K::Point_3> sm_points; std::vector<K::Point_3> sm_points;
// import a mesh // import a mesh
@ -53,26 +57,29 @@ void bench_finding_obb(std::string fname)
gather_mesh_points(mesh, sm_points); gather_mesh_points(mesh, sm_points);
CGAL::Timer timer; CGAL::Timer timer;
// 1) measure convex hull calculation
timer.start(); timer.start();
CGAL::Polyhedron_3<K> poly;
CGAL::Eigen_linear_algebra_traits la_traits; convex_hull_3(sm_points.begin(), sm_points.end(), poly);
std::vector<K::Point_3> ch_points(poly.points_begin(), poly.points_end());
// 1) using convex hull
std::vector<K::Point_3> obb_points1;
CGAL::Optimal_bounding_box::find_obb(sm_points, obb_points1, la_traits, true);
timer.stop(); timer.stop();
std::cout << "found obb with convex hull: " << timer.time() << " seconds\n"; std::cout << "takes : " << timer.time() << " seconds to find the convex hull\n";
// 2) using convex hull
timer.reset(); timer.reset();
timer.start(); timer.start();
std::vector<K::Point_3> obb_points1;
CGAL::Optimal_bounding_box::find_obb(sm_points, obb_points1, la_traits, true);
timer.stop();
std::cout << "found obb using convex hull: " << timer.time() << " seconds\n";
// 2) without convex hull // 3) without convex hull
timer.reset();
timer.start();
std::vector<K::Point_3> obb_points2; std::vector<K::Point_3> obb_points2;
CGAL::Optimal_bounding_box::find_obb(sm_points, obb_points2, la_traits, false); CGAL::Optimal_bounding_box::find_obb(sm_points, obb_points2, la_traits, false);
timer.stop(); timer.stop();
std::cout << "found obb without convex hull: " << timer.time() << " seconds\n"; std::cout << "found obb without convex hull: " << timer.time() << " seconds\n";
timer.reset(); timer.reset();

View File

@ -19,7 +19,6 @@
// //
// Author(s) : Konstantinos Katrioplas // Author(s) : Konstantinos Katrioplas
#ifndef CGAL_EVOLUTION_H #ifndef CGAL_EVOLUTION_H
#define CGAL_EVOLUTION_H #define CGAL_EVOLUTION_H
@ -34,7 +33,7 @@ namespace Optimal_bounding_box {
template <typename Linear_algebra_traits> template <typename Linear_algebra_traits>
class Evolution class Evolution
{ {
typedef typename Linear_algebra_traits::MatrixXd MatrixXd; typedef typename Linear_algebra_traits::MatrixX3d MatrixXd;
typedef typename Linear_algebra_traits::Matrix3d Matrix3d; typedef typename Linear_algebra_traits::Matrix3d Matrix3d;
typedef typename Linear_algebra_traits::Vector3d Vector3d; typedef typename Linear_algebra_traits::Vector3d Vector3d;
@ -280,14 +279,14 @@ public:
//std::cout << "pop after nelder mead: " << std::endl; //std::cout << "pop after nelder mead: " << std::endl;
//pop.show_population(); //pop.show_population();
//std::cout << std::endl; //std::cout << std::endl;
Fitness_map<Matrix3d, MatrixXd> fitness_map_debug(population, point_data); Fitness_map<Linear_algebra_traits, Matrix3d, MatrixXd> fitness_map_debug(population, point_data);
Matrix3d R_now = fitness_map_debug.get_best(); Matrix3d R_now = fitness_map_debug.get_best();
std::cout << "det= " << Linear_algebra_traits::determinant(R_now) << std::endl; std::cout << "det= " << Linear_algebra_traits::determinant(R_now) << std::endl;
#endif #endif
// stopping criteria // stopping criteria
Fitness_map<Matrix3d, MatrixXd> fitness_map(population, point_data); Fitness_map<Linear_algebra_traits, Matrix3d, MatrixXd> fitness_map(population, point_data);
new_fit_value = fitness_map.get_best_fitness_value(point_data); new_fit_value = fitness_map.get_best_fitness_value();
double difference = new_fit_value - prev_fit_value; double difference = new_fit_value - prev_fit_value;
if(abs(difference) < tolerance * new_fit_value) if(abs(difference) < tolerance * new_fit_value)
stale++; stale++;
@ -301,7 +300,7 @@ public:
const Matrix3d get_best() const Matrix3d get_best()
{ {
Fitness_map<Matrix3d, MatrixXd> fitness_map(population, point_data); Fitness_map<Linear_algebra_traits, Matrix3d, MatrixXd> fitness_map(population, point_data);
return fitness_map.get_best(); return fitness_map.get_best();
} }

View File

@ -27,14 +27,11 @@
#include <CGAL/Optimal_bounding_box/population.h> #include <CGAL/Optimal_bounding_box/population.h>
#include <limits> #include <limits>
#include <CGAL/Eigen_linear_algebra_traits.h>
namespace CGAL { namespace CGAL {
namespace Optimal_bounding_box { namespace Optimal_bounding_box {
template <typename Linear_algebra_traits> template <typename Linear_algebra_traits, typename Vertex, typename Matrix>
double compute_fitness(const typename Linear_algebra_traits::Matrix3d& R, double compute_fitness(const Vertex& R, const Matrix& data)
typename Linear_algebra_traits::MatrixXd& data)
{ {
// R: rotation matrix // R: rotation matrix
CGAL_assertion(R.cols() == 3); CGAL_assertion(R.cols() == 3);
@ -73,11 +70,9 @@ double compute_fitness(const typename Linear_algebra_traits::Matrix3d& R,
return ((xmax - xmin) * (ymax - ymin) * (zmax - zmin)); return ((xmax - xmin) * (ymax - ymin) * (zmax - zmin));
} }
template <typename Vertex, typename Matrix> template <typename Linear_algebra_traits, typename Vertex, typename Matrix>
struct Fitness_map struct Fitness_map
{ {
typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits; // to be added as a parameter
Fitness_map(Population<Vertex>& p, Matrix& points) : pop(p), points(points) Fitness_map(Population<Vertex>& p, Matrix& points) : pop(p), points(points)
{} {}
@ -103,14 +98,14 @@ struct Fitness_map
return pop[simplex_id][vertex_id]; return pop[simplex_id][vertex_id];
} }
double get_best_fitness_value(Matrix& data) double get_best_fitness_value()
{ {
const Vertex best_mat = get_best(); const Vertex best_mat = get_best();
return compute_fitness<Linear_algebra_traits>(best_mat, data); return compute_fitness<Linear_algebra_traits>(best_mat, points);
} }
Population<Vertex>& pop; Population<Vertex>& pop;
Matrix& points; const Matrix& points;
}; };
}} // end namespaces }} // end namespaces

View File

@ -38,26 +38,6 @@ namespace Optimal_bounding_box {
typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits; typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits;
#endif #endif
/*
template<typename Matrix>
void qr_factorization(Matrix& A, Matrix& Q)
{
Eigen::HouseholderQR<Matrix> qr(A);
Q = qr.householderQ();
}
template<typename Matrix>
void qr_factorization(std::vector<Matrix>& Simplex)
{
for(int i = 0; i < Simplex.size(); ++i)
{
Eigen::HouseholderQR<Matrix> qr(Simplex[i]);
Matrix Q = qr.householderQ();
Simplex[i] = Q;
}
}
*/
template <typename Matrix> template <typename Matrix>
const Matrix reflection(const Matrix& S_centroid, const Matrix& S_worst) const Matrix reflection(const Matrix& S_centroid, const Matrix& S_worst)
{ {
@ -92,19 +72,15 @@ Matrix mean(const Matrix& m1, const Matrix& m2)
CGAL_assertion(m2.cols() == 3); CGAL_assertion(m2.cols() == 3);
Matrix reduction = 0.5 * m1 + 0.5 * m2; Matrix reduction = 0.5 * m1 + 0.5 * m2;
//Matrix Q;
//reduction.qr_factorization(Q);
Matrix Q = Linear_algebra_traits::qr_factorization(reduction); Matrix Q = Linear_algebra_traits::qr_factorization(reduction);
double det = Linear_algebra_traits::determinant(Q); double det = Linear_algebra_traits::determinant(Q);
return Q / det; return Q / det;
} }
template <typename Matrix> template <typename Matrix>
const Matrix centroid(Matrix& S1, Matrix& S2, Matrix& S3) // const? const Matrix centroid(const Matrix& S1, const Matrix& S2, const Matrix& S3)
{ {
Matrix mean = (S1 + S2 + S3) / 3.0; Matrix mean = (S1 + S2 + S3) / 3.0;
//Matrix Q;
//mean.qr_factorization(Q);
Matrix Q = Linear_algebra_traits::qr_factorization(mean); Matrix Q = Linear_algebra_traits::qr_factorization(mean);
double det = Linear_algebra_traits::determinant(Q); double det = Linear_algebra_traits::determinant(Q);
return Q / det; return Q / det;

View File

@ -49,8 +49,8 @@ typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits;
// works on matrices only // works on matrices only
template <typename Vertex, typename Matrix_dynamic, typename Matrix_fixed> template <typename Vertex, typename Matrix>
void post_processing(const Matrix_dynamic& points, Vertex& R, Matrix_fixed& obb) void post_processing(const Matrix& points, Vertex& R, Matrix& obb)
{ {
CGAL_assertion(points.cols() == 3); CGAL_assertion(points.cols() == 3);
CGAL_assertion(R.rows() == 3); CGAL_assertion(R.rows() == 3);
@ -59,7 +59,7 @@ void post_processing(const Matrix_dynamic& points, Vertex& R, Matrix_fixed& obb)
CGAL_assertion(obb.cols() == 3); CGAL_assertion(obb.cols() == 3);
// 1) rotate points with R // 1) rotate points with R
Matrix_dynamic rotated_points(points.rows(), points.cols()); Matrix rotated_points(points.rows(), points.cols());
rotated_points = points * Linear_algebra_traits::transpose(R); rotated_points = points * Linear_algebra_traits::transpose(R);
// 2) get AABB from rotated points // 2) get AABB from rotated points
@ -75,10 +75,8 @@ void post_processing(const Matrix_dynamic& points, Vertex& R, Matrix_fixed& obb)
bbox = bbox_3(v_points.begin(), v_points.end()); bbox = bbox_3(v_points.begin(), v_points.end());
K::Iso_cuboid_3 ic(bbox); K::Iso_cuboid_3 ic(bbox);
Matrix_fixed aabb; // Matrix is [dynamic, 3] at compile time, so it needs allocation of rows at run time.
// preallocate sanity: if Matrix is not preallocated in compile time Matrix aabb(8, 3);
if(aabb.cols() != 3 && aabb.rows() != 8)
aabb.resize(8, 3);
for(std::size_t i = 0; i < 8; ++i) for(std::size_t i = 0; i < 8; ++i)
{ {
@ -104,7 +102,7 @@ void find_obb(std::vector<Point>& points,
CGAL_assertion(obb_points.size() == 8); CGAL_assertion(obb_points.size() == 8);
// eigen linear algebra traits // eigen linear algebra traits
typedef typename LinearAlgebraTraits::MatrixXd MatrixXd; typedef typename LinearAlgebraTraits::MatrixX3d MatrixXd;
typedef typename LinearAlgebraTraits::Matrix3d Matrix3d; typedef typename LinearAlgebraTraits::Matrix3d Matrix3d;
MatrixXd points_mat; MatrixXd points_mat;

View File

@ -20,7 +20,7 @@ void test_nelder_mead()
{ {
typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits; typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits;
typedef Linear_algebra_traits::Matrix3d Matrix3d; typedef Linear_algebra_traits::Matrix3d Matrix3d;
typedef Linear_algebra_traits::MatrixXd MatrixXd; typedef Linear_algebra_traits::MatrixX3d MatrixXd;
MatrixXd data_points(4,3); MatrixXd data_points(4,3);
data_points(0,0) = 0.866802; data_points(0,0) = 0.866802;
@ -143,7 +143,7 @@ void test_nelder_mead()
void test_genetic_algorithm() void test_genetic_algorithm()
{ {
CGAL::Eigen_dense_matrix<double> data_points(4, 3); CGAL::Eigen_dense_matrix<double, -1, 3> data_points(4, 3); // -1 : dynamic size at run time
data_points(0,0) = 0.866802; data_points(0,0) = 0.866802;
data_points(0,1) = 0.740808, data_points(0,1) = 0.740808,
data_points(0,2) = 0.895304, data_points(0,2) = 0.895304,
@ -170,7 +170,7 @@ void test_genetic_algorithm()
void test_random_unit_tetra() void test_random_unit_tetra()
{ {
// this is dynamic at run times // this is dynamic at run times
CGAL::Eigen_dense_matrix<double> data_points(4, 3); CGAL::Eigen_dense_matrix<double, -1, 3> data_points(4, 3);
// points are on their convex hull // points are on their convex hull
data_points(0,0) = 0.866802; data_points(0,0) = 0.866802;
@ -244,7 +244,7 @@ void test_reference_tetrahedron(const char* fname)
} }
typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits; typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits;
typedef Linear_algebra_traits::MatrixXd MatrixXd; typedef Linear_algebra_traits::MatrixX3d MatrixXd;
typedef Linear_algebra_traits::Matrix3d Matrix3d; typedef Linear_algebra_traits::Matrix3d Matrix3d;
// points in a matrix // points in a matrix
@ -279,7 +279,7 @@ void test_long_tetrahedron(std::string fname)
} }
typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits; typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits;
typedef Linear_algebra_traits::MatrixXd MatrixXd; typedef Linear_algebra_traits::MatrixX3d MatrixXd;
typedef Linear_algebra_traits::Matrix3d Matrix3d; typedef Linear_algebra_traits::Matrix3d Matrix3d;
// points in a matrix // points in a matrix

View File

@ -38,7 +38,6 @@ class Eigen_dense_matrix
{ {
public: public:
typedef Eigen::Matrix<T, D1, D2> EigenType; typedef Eigen::Matrix<T, D1, D2> EigenType;
typedef Eigen::Matrix<T, 3, 3> EigenType3;
Eigen_dense_matrix(std::size_t nrows, std::size_t ncols) Eigen_dense_matrix(std::size_t nrows, std::size_t ncols)
: m_matrix(static_cast<int>(nrows), static_cast<int>(ncols)) : m_matrix(static_cast<int>(nrows), static_cast<int>(ncols))
@ -94,7 +93,6 @@ template <typename T, int D = Eigen::Dynamic>
class Eigen_dense_vector class Eigen_dense_vector
{ {
private: private:
//typedef Eigen::Vector3d EigenType;
typedef Eigen::Matrix<T, D, 1> EigenType; typedef Eigen::Matrix<T, D, 1> EigenType;
public: public:
@ -119,11 +117,14 @@ public:
// dynamic size at run time // dynamic size at run time
typedef CGAL::Eigen_dense_matrix<NT> MatrixXd; typedef CGAL::Eigen_dense_matrix<NT> MatrixXd;
// dynamic rows in run time, fixed cols in compile time
typedef CGAL::Eigen_dense_matrix<NT, Eigen::Dynamic, 3> MatrixX3d;
// fixed at compile time // fixed at compile time
typedef CGAL::Eigen_dense_matrix<NT, 3, 3> Matrix3d; typedef CGAL::Eigen_dense_matrix<NT, 3, 3> Matrix3d;
// fixed at compile time // fixed at compile time
typedef CGAL::Eigen_dense_vector<NT> Vector3d; typedef CGAL::Eigen_dense_vector<NT, 3> Vector3d;
template <class Matrix> template <class Matrix>
static Matrix transpose(const Matrix& mat) static Matrix transpose(const Matrix& mat)
@ -155,11 +156,11 @@ public:
} }
template <class NT, int D1, int D2> template <class NT, int D1, int D2>
static CGAL::Eigen_dense_vector<NT, D1> row(CGAL::Eigen_dense_matrix<NT, D1, D2>& A, int i_) static CGAL::Eigen_dense_vector<NT, 3> row(const CGAL::Eigen_dense_matrix<NT, D1, D2>& A,
int i)
{ {
return CGAL::Eigen_dense_vector<NT, D1>(A.m_matrix.row(i_)); return CGAL::Eigen_dense_vector<NT, 3>(A.m_matrix.row(i));
} }
}; };
@ -214,7 +215,7 @@ const CGAL::Eigen_dense_matrix<NT, D1, D2> operator/ (const double& scalar,
return CGAL::Eigen_dense_matrix<NT, D1, D2> (scalar / A.m_matrix); return CGAL::Eigen_dense_matrix<NT, D1, D2> (scalar / A.m_matrix);
} }
// addition - subtraction // addition
template <class NT, int D1, int D2> template <class NT, int D1, int D2>
const CGAL::Eigen_dense_matrix<NT, D1, D2> operator+ (const CGAL::Eigen_dense_matrix<NT, D1, D2> & A, const CGAL::Eigen_dense_matrix<NT, D1, D2> operator+ (const CGAL::Eigen_dense_matrix<NT, D1, D2> & A,
const CGAL::Eigen_dense_matrix<NT, D1, D2> & B) const CGAL::Eigen_dense_matrix<NT, D1, D2> & B)
@ -224,9 +225,10 @@ const CGAL::Eigen_dense_matrix<NT, D1, D2> operator+ (const CGAL::Eigen_dense_ma
// vector - matrix multiplication // vector - matrix multiplication
template <class NT, int D1, int D2> template <class NT, int D1, int D2>
const Eigen_dense_vector<NT> operator* (const CGAL::Eigen_dense_matrix<NT, D1, D2>& A, CGAL::Eigen_dense_vector<NT>& V) const Eigen_dense_vector<NT, D1> operator* (const CGAL::Eigen_dense_matrix<NT, D1, D2>& A,
const CGAL::Eigen_dense_vector<NT, D2>& V)
{ {
return Eigen_dense_vector<NT>(A.m_matrix * V.m_vector); return Eigen_dense_vector<NT, D1>(A.m_matrix * V.m_vector);
} }