Skip to content

Commit

Permalink
cleanup seeding by target error drop
Browse files Browse the repository at this point in the history
  • Loading branch information
aboudev committed Aug 28, 2017
1 parent 3b8f17b commit a62cc65
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 68 deletions.
Expand Up @@ -28,7 +28,7 @@ typedef CGAL::Timer Timer;
*/
int main(int argc, char *argv[])
{
if (argc < 4)
if (argc < 5)
return 1;

Polyhedron mesh;
Expand All @@ -52,13 +52,18 @@ int main(int argc, char *argv[])
if (init < 0 || init > 2)
return 1;
const FT tol(std::atof(argv[3]));
int iterations = std::atoi(argv[4]);
std::cerr << "#init " << init << std::endl;
std::cerr << "#tolerance " << tol << std::endl;
std::cerr << "#iterations " << iterations << std::endl;

Timer t;
std::cerr << "start initialization" << std::endl;
t.start();
l21_vsa.init_proxies_error(tol, static_cast<L21VSA::Initialization>(init));
l21_vsa.seeding_error(
static_cast<L21VSA::Initialization>(init),
tol,
iterations);
t.stop();
std::cerr << "initialization time " << t.time() << " sec." << std::endl;
std::cerr << "#proxies " << l21_vsa.get_proxies_size() << std::endl;
Expand Down
194 changes: 131 additions & 63 deletions Surface_mesh_approximation/include/CGAL/VSA_approximation.h
Expand Up @@ -334,12 +334,12 @@ class VSA_approximation {
/*!
* @brief Incremental initialize proxies.
* @param num_seed number of proxies seed
* @param inner_iteration number of iterations of coarse re-fitting
* @param num_iterations number of iterations of coarse re-fitting
* before each incremental proxy insertion
* @return number of proxies initialized
*/
std::size_t seed_incremental(const std::size_t num_seed,
const std::size_t inner_iteration = 5) {
const std::size_t num_iterations = 5) {
proxies.clear();
if (num_faces(*m_pmesh) < num_seed)
return 0;
Expand All @@ -349,19 +349,19 @@ class VSA_approximation {
BOOST_FOREACH(face_descriptor f, faces(*m_pmesh))
fproxy_map[f] = 0;

insert_proxy_furthest(num_seed - 1, inner_iteration);
insert_proxy_furthest(num_seed - 1, num_iterations);
return proxies.size();
}

/*!
* @brief Hierarchical initialize proxies.
* @param num_seed number of proxies seed
* @param inner_iteration number of iterations of coarse re-fitting
* @param num_iterations number of iterations of coarse re-fitting
* before each hierarchical proxy insertion
* @return number of proxies initialized
*/
std::size_t seed_hierarchical(const std::size_t num_seed,
const std::size_t inner_iteration = 5) {
const std::size_t num_iterations = 5) {
proxies.clear();
if (num_faces(*m_pmesh) < num_seed)
return 0;
Expand All @@ -373,7 +373,7 @@ class VSA_approximation {
proxies.push_back(fit_new_proxy(*(++fitr)));

while (proxies.size() < num_seed) {
for (std::size_t i = 0; i < inner_iteration; ++i) {
for (std::size_t i = 0; i < num_iterations; ++i) {
partition();
fit();
}
Expand All @@ -388,66 +388,26 @@ class VSA_approximation {
}

/*!
* @brief Initialize by targeted error drop.
* @brief Seeding by targeted error drop.
* @param method seeding method
* @param target_drop targeted error drop to initial state, usually in range (0, 1)
* @param seeding_method select one of the seeding method: random, hierarchical, incremental
* @param num_iterations number of iterations of coarse re-fitting
* @return number of proxies initialized
*/
std::size_t init_proxies_error(const FT &target_drop, const Initialization &seeding_method) {
proxies.clear();
// initialize a proxy and the proxy map to prepare for the insertion
proxies.push_back(fit_new_proxy(*(faces(*m_pmesh).first)));
BOOST_FOREACH(face_descriptor f, faces(*m_pmesh))
fproxy_map[f] = 0;
const FT initial_err = compute_fitting_error();

// maximum allowed number of proxies
const std::size_t max_proxies = num_faces(*m_pmesh) / 3;
if (max_proxies < 1)
return 0;

FT sum_err(0);
FT drop(0);
if (seeding_method == RandomInit) {
std::size_t target_px = 2;
do {
proxies.clear();
seed_random(target_px);
for (std::size_t i = 0; i < 5; ++i) {
partition();
fit();
}
sum_err = compute_fitting_error();
target_px *= 2;
drop = sum_err / initial_err;
} while(drop > target_drop && proxies.size() < max_proxies);
}
else if (seeding_method == IncrementalInit) {
do {
insert_proxy_furthest();
for (std::size_t i = 0; i < 5; ++i) {
partition();
fit();
}
sum_err = compute_fitting_error();
drop = sum_err / initial_err;
} while (drop > target_drop && proxies.size() < max_proxies);
}
else {
std::size_t target_px = 1;
do {
insert_proxy_hierarchical(target_px);
for (std::size_t i = 0; i < 5; ++i) {
partition();
fit();
}
sum_err = compute_fitting_error();
target_px *= 2;
drop = sum_err / initial_err;
} while(drop > target_drop && proxies.size() < max_proxies);
std::size_t seeding_error(
const Initialization method,
const FT target_drop,
const std::size_t num_iterations) {
switch (method) {
case RandomInit:
return seed_error_random(target_drop, num_iterations);
case IncrementalInit:
return seed_error_incremental(target_drop, num_iterations);
case HierarchicalInit:
return seed_error_hierarchical(target_drop, num_iterations);
default:
return 0;
}

return proxies.size();
}

/*!
Expand Down Expand Up @@ -902,7 +862,115 @@ class VSA_approximation {

// private member functions
private:

/*!
* @brief Initialize by targeted error drop.
* @param target_drop targeted error drop to initial state, usually in range (0, 1)
* @param num_iterations number of iterations of coarse re-fitting
* @return number of proxies initialized
*/
std::size_t seed_error_random(const FT target_drop,
const std::size_t num_iterations) {
// maximum allowed number of proxies
const std::size_t max_proxies = num_faces(*m_pmesh) / 3;
if (max_proxies < 1)
return 0;

// initialize a proxy and the proxy map to prepare for the insertion
proxies.clear();
proxies.push_back(fit_new_proxy(*(faces(*m_pmesh).first)));
BOOST_FOREACH(face_descriptor f, faces(*m_pmesh))
fproxy_map[f] = 0;
const FT initial_err = compute_fitting_error();

FT sum_err(0);
FT drop(0);
std::size_t target_px = 2;
do {
proxies.clear();
seed_random(target_px);
for (std::size_t i = 0; i < num_iterations; ++i) {
partition();
fit();
}
sum_err = compute_fitting_error();
target_px *= 2;
drop = sum_err / initial_err;
} while(drop > target_drop && proxies.size() < max_proxies);

return proxies.size();
}

/*!
* @brief Initialize by targeted error drop.
* @param target_drop targeted error drop to initial state, usually in range (0, 1)
* @param num_iterations number of iterations of coarse re-fitting
* @return number of proxies initialized
*/
std::size_t seed_error_incremental(const FT target_drop,
const std::size_t num_iterations) {
// maximum allowed number of proxies
const std::size_t max_proxies = num_faces(*m_pmesh) / 3;
if (max_proxies < 1)
return 0;

// initialize a proxy and the proxy map to prepare for the insertion
proxies.clear();
proxies.push_back(fit_new_proxy(*(faces(*m_pmesh).first)));
BOOST_FOREACH(face_descriptor f, faces(*m_pmesh))
fproxy_map[f] = 0;
const FT initial_err = compute_fitting_error();

FT sum_err(0);
FT drop(0);
do {
insert_proxy_furthest();
for (std::size_t i = 0; i < num_iterations; ++i) {
partition();
fit();
}
sum_err = compute_fitting_error();
drop = sum_err / initial_err;
} while (drop > target_drop && proxies.size() < max_proxies);

return proxies.size();
}

/*!
* @brief Initialize by targeted error drop.
* @param target_drop targeted error drop to initial state, usually in range (0, 1)
* @param num_iterations number of iterations of coarse re-fitting
* @return number of proxies initialized
*/
std::size_t seed_error_hierarchical(const FT target_drop,
const std::size_t num_iterations) {
// maximum allowed number of proxies
const std::size_t max_proxies = num_faces(*m_pmesh) / 3;
if (max_proxies < 1)
return 0;

// initialize a proxy and the proxy map to prepare for the insertion
proxies.clear();
proxies.push_back(fit_new_proxy(*(faces(*m_pmesh).first)));
BOOST_FOREACH(face_descriptor f, faces(*m_pmesh))
fproxy_map[f] = 0;
const FT initial_err = compute_fitting_error();

FT sum_err(0);
FT drop(0);
std::size_t target_px = 1;
do {
insert_proxy_hierarchical(target_px);
for (std::size_t i = 0; i < num_iterations; ++i) {
partition();
fit();
}
sum_err = compute_fitting_error();
target_px *= 2;
drop = sum_err / initial_err;
} while(drop > target_drop && proxies.size() < max_proxies);

return proxies.size();
}

/*!
* @brief Inserts a proxy at the furthest facet of the region with the maximum fitting error.
Expand Down
Expand Up @@ -119,11 +119,12 @@ int main()
boundary = l2_approx.get_indexed_boundary_polygons();

const FT drop(0.001);
const std::size_t iterations = 5;
std::cout << "rebuild and hierarchical init" << std::endl;
l2_approx.rebuild();
if (l2_approx.get_proxies_size() != 0)
return EXIT_FAILURE;
l2_approx.init_proxies_error(drop, L2VSA::HierarchicalInit);
l2_approx.seeding_error(L2VSA::HierarchicalInit, drop, iterations);
for (std::size_t i = 0; i < 10; ++i)
l2_approx.run_one_step();
std::cout << "#proxies " << l2_approx.get_proxies_size() << std::endl;
Expand All @@ -132,7 +133,7 @@ int main()
l2_approx.rebuild();
if (l2_approx.get_proxies_size() != 0)
return EXIT_FAILURE;
l2_approx.init_proxies_error(drop, L2VSA::IncrementalInit);
l2_approx.seeding_error(L2VSA::IncrementalInit, drop, iterations);
for (std::size_t i = 0; i < 10; ++i)
l2_approx.run_one_step();
std::cout << "#proxies " << l2_approx.get_proxies_size() << std::endl;
Expand Down
Expand Up @@ -38,7 +38,8 @@ bool test_shape(const char *file_name, const std::size_t target_num_proxies)
// should reach targeted number of proxies gradually
const FT drop(1e-8);
const std::size_t num_iterations = 20;
vsa_l21.init_proxies_error(drop, L21VSA::IncrementalInit);
const std::size_t inner_iterations = 10;
vsa_l21.seeding_error(L21VSA::IncrementalInit, drop, inner_iterations);
for (std::size_t i = 0; i < num_iterations; ++i)
vsa_l21.run_one_step();
if (vsa_l21.get_proxies_size() != target_num_proxies) {
Expand Down

0 comments on commit a62cc65

Please sign in to comment.