mirror of https://github.com/CGAL/cgal
207 lines
6.4 KiB
C++
207 lines
6.4 KiB
C++
// Copyright (c) 2004 Max-Planck-Institute Saarbruecken (Germany).
|
|
// All rights reserved.
|
|
//
|
|
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
|
// the terms of the Q Public License version 1.0.
|
|
// See the file LICENSE.QPL distributed with CGAL.
|
|
//
|
|
// Licensees holding a valid commercial license may use this file in
|
|
// accordance with the commercial license agreement provided with the software.
|
|
//
|
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
//
|
|
// $URL$
|
|
// $Id$
|
|
//
|
|
//
|
|
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
|
// Andreas Meyer <ameyer@mpi-sb.mpg.de>
|
|
|
|
|
|
// enable invariant checking
|
|
#define CGAL_SEGMENT_TREE_CHECK_INVARIANTS 1
|
|
#include <CGAL/box_intersection_d.h>
|
|
#include <CGAL/Timer.h>
|
|
#include <iostream>
|
|
#include <iterator>
|
|
#include <fstream>
|
|
#include <cstdlib>
|
|
|
|
#include "util.h"
|
|
|
|
static unsigned int failed = 0;
|
|
|
|
template< class NT, unsigned int DIM, bool CLOSED >
|
|
struct _test {
|
|
typedef Util< NT, DIM, CLOSED > Uti1;
|
|
|
|
|
|
|
|
static void
|
|
test_n( unsigned int n, std::ostream& outfile )
|
|
{
|
|
typename Uti1::Box_container boxes1, boxes2;
|
|
//Result_container result_allpairs, result_scanner, result_tree;
|
|
std::cout << "generating random box sets with size "
|
|
<< n << " ... " << std::flush;
|
|
Uti1::fill_boxes( n, boxes1 );
|
|
Uti1::fill_boxes( n, boxes2 );
|
|
std::cout << std::endl;
|
|
typename Uti1::Counter_callback callback1, callback2;
|
|
CGAL::Timer timer, timer_scan;
|
|
double time, time_scan;
|
|
std::size_t problemsize = boxes1.size() + boxes2.size();
|
|
unsigned int cutoff = 0;
|
|
unsigned int stepsize = 500;
|
|
double last_time = 1e30;
|
|
|
|
std::cout << "one way scan ... " << std::flush;
|
|
timer_scan.start();
|
|
unsigned int repetitions = 1;
|
|
if( problemsize < 20 )
|
|
repetitions = 1000;
|
|
else if( problemsize < 50 )
|
|
repetitions = 500;
|
|
else if( problemsize < 90 )
|
|
repetitions = 100;
|
|
else if( problemsize < 300 )
|
|
repetitions = 50;
|
|
else if( problemsize < 1000 )
|
|
repetitions = 10;
|
|
else if( problemsize < 10000 )
|
|
repetitions = 4;
|
|
else
|
|
repetitions = 1;
|
|
|
|
for( unsigned int i = repetitions; i; --i ) {
|
|
CGAL::Box_intersection_d::one_way_scan( boxes1.begin(), boxes1.end(),
|
|
boxes2.begin(), boxes2.end(),
|
|
callback1,
|
|
typename Uti1::Traits(),
|
|
DIM - 1 );
|
|
CGAL::Box_intersection_d::one_way_scan( boxes2.begin(), boxes2.end(),
|
|
boxes1.begin(), boxes1.end(),
|
|
callback1,
|
|
typename Uti1::Traits(),
|
|
DIM - 1 );
|
|
}
|
|
timer_scan.stop();
|
|
time_scan = timer_scan.time() / repetitions;
|
|
const unsigned int scan_counter = callback1.get_counter()/repetitions;
|
|
|
|
std::cout << "got " << scan_counter << " intersections in "
|
|
<< time_scan << " seconds."
|
|
<< std::endl;
|
|
|
|
std::cout << "segment tree ... " << std::endl;
|
|
if( problemsize > 3000 )
|
|
cutoff = 500;
|
|
while( true )
|
|
{
|
|
timer.reset();
|
|
timer.start();
|
|
for( unsigned int i = repetitions; i; --i ) {
|
|
CGAL::box_intersection_d( boxes1.begin(), boxes1.end(),
|
|
boxes2.begin(), boxes2.end(),
|
|
callback2, cutoff,
|
|
CGAL::Box_intersection_d::CLOSED,
|
|
CGAL::Box_intersection_d::BIPARTITE);
|
|
}
|
|
timer.stop();
|
|
time = timer.time() / repetitions;
|
|
const unsigned int stream_counter = callback2.get_counter()/repetitions;
|
|
callback2.reset_counter();
|
|
if( stream_counter != scan_counter ) {
|
|
std::cout << "!! different number of intersections! got "
|
|
<< stream_counter << "intersections!" << std::endl;
|
|
std::exit(-1);
|
|
}
|
|
std::cout << "cutoff = " << cutoff << " -> t = " << time << std::endl;
|
|
if( last_time < time || time < 1e-4) {
|
|
if( cutoff > stepsize )
|
|
cutoff -= stepsize;
|
|
else
|
|
cutoff = 0;
|
|
if( ( problemsize < 2000 && problemsize/stepsize > 10 ) ||
|
|
problemsize/stepsize > 50 )
|
|
break;
|
|
if( cutoff > stepsize )
|
|
cutoff -= stepsize;
|
|
else
|
|
cutoff = 0;
|
|
stepsize /= 2;
|
|
last_time = 1e30;
|
|
} else {
|
|
last_time = time;
|
|
//stepsize *= 2;
|
|
}
|
|
cutoff += stepsize;
|
|
}
|
|
|
|
std::cout << "optimal cutoff = " << cutoff << std::endl;
|
|
outfile << problemsize << " " << last_time << " " << time_scan << std::endl;
|
|
}
|
|
|
|
void operator()() {
|
|
std::cout << "-------------------------" << std::endl;
|
|
std::cout << "DIM = " << DIM << std::endl;
|
|
std::cout << "-------------------------" << std::endl;
|
|
std::ofstream outfile( "benchmark.data" );
|
|
outfile << "# problemsize streamingtime scanningtime" << std::endl;
|
|
outfile.precision(9);
|
|
// correct for >= g++3.0 , but g++2.95 does not conform to the standard
|
|
//outfile << std::fixed;
|
|
// workaround for g++2.95: (does not work for >= 3.0)
|
|
//outfile << setiosflags( ios::fixed );
|
|
for( unsigned int n = 1024; n < 200000; n = (int)(n * 4)) {
|
|
test_n( n, outfile );
|
|
}
|
|
}
|
|
|
|
}; // end struct test
|
|
|
|
template< class NT >
|
|
struct test
|
|
{
|
|
//_test< NT, 1, true > t0;
|
|
//_test< NT, 2, true > t1;
|
|
_test< NT, 3, true > t2;
|
|
/*_test< NT, 4, true > t3;
|
|
_test< NT, 10, true > t4;
|
|
_test< NT, 1, false > t5;
|
|
_test< NT, 2, false > t6;
|
|
_test< NT, 3, false > t7;
|
|
_test< NT, 4, false > t8;
|
|
_test< NT, 10, false > t9;*/
|
|
|
|
void operator()() {
|
|
//t0();
|
|
//t1();
|
|
t2();
|
|
/*t3();
|
|
t4();
|
|
t5();
|
|
t6();
|
|
t7();
|
|
t8();
|
|
t9();*/
|
|
}
|
|
};
|
|
|
|
|
|
|
|
int main() {
|
|
test<float> c;
|
|
c();
|
|
|
|
if( failed != 0 ) {
|
|
std::cout << "a total number of " << failed << " tests failed!"
|
|
<< std::endl;
|
|
return 1;
|
|
}
|
|
std::cout << "all tests passed." << std::endl;
|
|
return 0;
|
|
}
|
|
|