Beispiel #1
0
bool doBCDOpt( OptimizableFunction & func, SubspaceOptimizer & ssopt,
		const po::variables_map & options, const State & xinit,
		Clock::time_point timeout, Clock::time_point starttime,
		State & xopt, Numeric & fopt ) {

	size_t blksize = std::ceil( (Numeric) func.getNumVars() / 5.0 );
	if ( options.count( "AVblksz" ) ) {
		blksize = options["AVblksz"].as< size_t >();
	} else if ( options.count( "AVblkpct" ) ) {
		blksize = round( options["AVblkpct"].as< Numeric >() *
				(Numeric) func.getNumVars() );
	}

	Numeric tol = 1e-6;
	if ( options.count( "steptol" ) ) tol = options["steptol"].as< Numeric >();

	size_t cgmaxit = 100;
	if ( options.count( "SSmaxit" ) ) cgmaxit = options["SSmaxit"].as< VariableCount >();

	size_t nRR = 0;
	if ( options.count( "nRRatTop" ) ) nRR = options["nRRatTop"].as< size_t >();

	std::cout << "BCD OPTIMIZATION" << std::endl;

	BCDOptimizer bcdopt( func, ssopt, blksize, tol );

	fopt = bcdopt.optimize( cgmaxit, 100000, &xinit, true, timeout, nRR,
			starttime );

	xopt = bcdopt.getOptState();
	std::cout << "BCD opt eval " << fopt << " in " << bcdopt.getRuntime() << std::endl;

	return bcdopt.getTimedOut();
}
Beispiel #2
0
void optimize_sinusoid( BOOSTNS::random::mt19937 & rng,
						const po::variables_map & options ) {

	Numeric regionwidth = 1.0;
	Numeric eps = 0.1, lipsch = 20;
	RDISOptimizer * popt = NULL;

	const string domain =
			BOOSTNS::str( BOOSTNS::format( "%1%:%2%" ) %
					( -regionwidth/2.0 ) % ( regionwidth/2.0 ) );
//					( regionwidth / 4.0 ) % ( 5.0*regionwidth/4.0 ) );

	eps = options.count( "epsilon" ) ? options[ "epsilon" ].as< Numeric >() : eps;
	lipsch = options.count( "lipschitz" ) ? options[ "lipschitz" ].as< Numeric >() : lipsch;

	if ( options.count( "timeAsSeed" ) && options[ "timeAsSeed" ].as< bool >() ) {
		rng.seed( std::time(NULL) + getpid() );
		if ( options[ "sampleOffset"].as< size_t >() > 0 ) {
			std::cout << "WARNING: sampleOffset and timeAsSeed should not both be set" << std::endl;
		}
	}

	const bool isBCD = ( options.count( "opttype" ) &&
			options[ "opttype" ].as< string >() == "bcd" );

	size_t h = options[ "sinHeight" ].as< size_t >();
	size_t bf = options[ "sinBF" ].as< size_t >();
	size_t arity = options[ "sinArity" ].as< size_t >();
	bool oddArity = options[ "sinOddArity" ].as< bool >();

	OptimizableFunctionSP funcsp =
			OptimizableFunctionGenerator::makeHighDimSinusoid( h, bf, arity, oddArity );

	OptimizableFunction & fsinusoid = *funcsp;

	std::cout << fsinusoid << std::endl;

	CGDSubspaceOptimizer ssopt( fsinusoid );
	ssopt.setParameters( options );

	// create the optimizer
	popt = new RDISOptimizer( fsinusoid, ssopt, options );

	RDISOptimizer & opt = *popt;
	setSignalHandler( &opt );

	opt.setApproxFactors( options[ "approxfactors" ].as< bool >() );
	opt.setUseCache( false );
//	opt.setUseExactCaching( false );

	const Numeric MaxVal = std::numeric_limits< Numeric >::max();

	size_t sampleOffset = options[ "sampleOffset" ].as< size_t >();
	size_t nsamples = options[ "nsamples" ].as< size_t >() + sampleOffset;

	const NumericInterval dom = fsinusoid.getVariables()[0]->getDomain().interval();

	BOOSTNS::random::uniform_real_distribution<> unif( dom.lower(), dom.upper() );
	std::vector< State > initialStates( nsamples );

	// create all the random initial states up front (so they're consistent
	// across runs if the seed doesn't change)
	for ( size_t i = 0; i < nsamples; ++i ) {
		for ( VariableID vid = 0; vid < fsinusoid.getNumVars(); ++vid ) {
			initialStates[i].push_back( unif( rng ) );
		}
	}

	const Clock::time_point start = Clock::now();
	Clock::time_point timeout = Clock::time_point::max();

	if ( options.count( "timeout" ) ) {
		size_t ms = 1000.0 * options[ "timeout" ].as< Numeric >();
		timeout = Clock::now() + bc::milliseconds( ms );
	}

	Numeric bestfopt = NumericMAX;
	State bestx;

	size_t i = sampleOffset;
	for ( ; i < nsamples; ) {

		Numeric finit = MaxVal;
		const State & xinit = initialStates[i];

		std::cout << "[" << i << "] optimization starting -- bounds: " <<
				fsinusoid.computeBounds() << std::endl;
		std::cout << "eps: " << eps << ", lipschitz: " << lipsch <<
				", step: " << eps / lipsch <<
				", finit: " << finit << std::endl << "xinit: " << xinit << std::endl;

		std::cout << "initial eval: " << eval( fsinusoid, xinit ) << std::endl;

		++i;

		if ( options.count( "useDA" ) ) {
			throw "deterministic annealing not yet supported";
		} else if ( options.count( "useCP" ) ) {
			throw "cutting plane not yet supported";
		}

		State xopt;
		Numeric result = MaxVal;
		bool timedOut = false;

		if ( !isBCD ) {
			result = opt.optimize( &xinit, finit, timeout, true, start );
			xopt = opt.getOptState();
			opt.printStats();
			timedOut = ( opt.wasStopped() || opt.timedOut() );
		} else {
			timedOut = doBCDOpt( fsinusoid, ssopt, options, xinit, timeout, start,
					xopt, result );
		}

		const Duration elapsed = Clock::now() - start;

		assert( !xopt.empty() );
		std::cout << "sinusoid opt. result: " << result << std::endl <<
					"\tat " << xopt << std::endl;
		Numeric actual = eval( fsinusoid, xopt );
		std::cout << "actual eval: " << actual << " after " << elapsed.count()
				<< " seconds " << std::endl;

		if ( actual < bestfopt ) {
			bestfopt = actual;
			bestx = xopt;
		}

		if ( timedOut ) {
			std::cout << "timeout detected..." << std::endl;
			break; break;
		}
	}
}
Beispiel #3
0
void optimize_BA( BOOSTNS::random::mt19937 & rng,
		const po::variables_map & options, const string & bafile ) {

	// get optimization type from command line
	const string opttype = options[ "opttype" ].as< string >();

	const bool isRDIS = ( opttype == "rdis" );
	const bool isBCD = ( opttype == "bcd" );
//	const bool isDisc = ( opttype == "discrete" );
//	const bool isGrid = ( opttype == "grid" );

	Numeric eps = 1.0, lipsch = 20;
	RDISOptimizer * popt = NULL;

	assert( isRDIS || isBCD /*|| isDisc || isGrid*/ );

	eps = options.count( "epsilon" ) ? options[ "epsilon" ].as< Numeric >() : eps;
	lipsch = options.count( "lipschitz" ) ? options[ "lipschitz" ].as< Numeric >() : lipsch;

	if ( options.count( "timeAsSeed" ) && options[ "timeAsSeed" ].as< bool >() ) {
		rng.seed( std::time(NULL) + getpid() );
		if ( options[ "sampleOffset"].as< size_t >() > 0 ) {
			std::cout << "WARNING: sampleOffset and timeAsSeed should not both be set" << std::endl;
		}
	}

	VariableCount ncams = options.count( "ncams" ) ?
						  options["ncams"].as< size_t >() : 0;
	VariableCount npts = options.count( "npts" ) ?
						 options["npts"].as< size_t >() : 0;

	// load and initialize the BA problem we'll optimize
	BundleAdjustmentFunction bafunc;
	if ( !bafunc.load( bafile, ncams, npts ) ) {
		std::cout << "loading file " << bafile << " failed -- exiting" << std::endl;
		return;
	}

	SubspaceOptimizer * pssopt;
	if ( options["useCGD"].as< bool >() ) {
		pssopt = new CGDSubspaceOptimizer( bafunc );
	} else {
		pssopt = new LMSubspaceOptimizer( bafunc );
	}
	SubspaceOptimizer & ssopt = *pssopt;
////	CGDSubspaceOptimizer ssopt( bafunc );
//	LMSubspaceOptimizer ssopt( bafunc );
	ssopt.setParameters( options );

	// create the optimizer and initialize it properly
//	popt = ( isRDIS ?
//			new OptimizerISGD( bafunc, ssopt, options ) :
//			new OptimizerDG( bafunc, options ) );
	popt = new RDISOptimizer( bafunc, ssopt, options );

	RDISOptimizer & opt = *popt;
	setSignalHandler( &opt );

//	opt.setOptType( 3 );
//	opt.setUseFiniteDiffs( true );
//	opt.setUseLinearLB( false );

	opt.setApproxFactors( options[ "approxfactors" ].as< bool >() );
	opt.setUseCache( !isRDIS );
//	opt.setUseExactCaching( isDisc );

	const Numeric MaxVal = std::numeric_limits< Numeric >::max();

	size_t sampleOffset = options[ "sampleOffset" ].as< size_t >();
	size_t nsamples = options[ "nsamples" ].as< size_t >() + sampleOffset;

	std::vector< State > initialStates( nsamples );

	if ( options.count( "randinit" ) && !options["randinit"].as< bool >() ) {
		sampleOffset = 0;
		nsamples = 1;
		initialStates.clear();
		initialStates.push_back( bafunc.getInitialState() );

	} else {
		// create all the random initial states up front (so they're consistent
		// across runs if the seed doesn't change)
		for ( size_t i = 0; i < nsamples; ++i ) {
			for ( VariableID vid = 0; vid < bafunc.getNumVars(); ++vid ) {
				NumericInterval si =
						bafunc.getVariables()[vid]->getDomain().getSamplingInterval();
				BOOSTNS::random::uniform_real_distribution<> unif(
						si.lower(), si.upper() );
				initialStates[i].push_back( unif( rng ) );
			}

//			if ( i >= sampleOffset ) {
//				std::cout << "state " << i << ": " << initialStates[i] << std::endl;
//			}
		}
	}

	const Clock::time_point start = Clock::now();
	Clock::time_point timeout = Clock::time_point::max();

	if ( options.count( "timeout" ) ) {
		size_t ms = 1000.0 * options[ "timeout" ].as< Numeric >();
		timeout = Clock::now() + bc::milliseconds( ms );
	}

	Numeric bestfopt = NumericMAX;
	State bestx;

	size_t i = sampleOffset;
	for ( ; i < nsamples; ) {

		Numeric finit = MaxVal;
		const State & xinit = initialStates[i];

		std::cout << "[" << i << "] optimization starting -- bounds: " <<
				bafunc.computeBounds() << std::endl;
		std::cout << "eps: " << eps << ", lipschitz: " << lipsch <<
				", step: " << eps / lipsch <<
				", finit: " << finit << std::endl << "xinit: " << xinit << std::endl;

		std::cout << "initial eval: " << bafunc.eval( xinit ) << std::endl;

		if ( options.count( "useDA" ) ) {
			throw "deterministic annealing not yet supported";
		} else if ( options.count( "useCP" ) ) {
			throw "cutting plane not yet supported";
		}

		++i;

		State xopt;
		Numeric result = MaxVal;
		bool timedOut = false;

		if ( !isBCD ) {
			if ( options["ignoreCamVars"].as< bool >() ) {
				for ( Variable * v : bafunc.getVariables() ) {
					if ( bafunc.getVarType( v->getID() ) == BundleAdjust::CAM_FOCAL ||
							bafunc.getVarType( v->getID() ) == BundleAdjust::CAM_RDL_K1 ||
							bafunc.getVarType( v->getID() ) == BundleAdjust::CAM_RDL_K2 ) {
						bafunc.getVariables()[i]->assign( bafunc.getInitialState()[i] );
					}
				}
			}
			result = opt.optimize( &xinit, finit, timeout, true, start );
			xopt = opt.getOptState();
			opt.printStats();
			timedOut = ( opt.wasStopped() || opt.timedOut() );
		} else {
			if ( options["ignoreCamVars"].as< bool >() ) {
				std::cout << "IGNORECAMVARS OPTION NOT SUPPORTED FOR BCD" << std::endl;
			}
			timedOut = doBCDOpt( bafunc, ssopt, options, xinit, timeout, start,
					xopt, result );
		}

		assert( !xopt.empty() );

		const Duration elapsed = Clock::now() - start;

		std::cout << "bundle adjustment opt. result: " << result << std::endl
				<< "\tat " << xopt << std::endl;
		Numeric actual = bafunc.eval( xopt );
		std::cout << "actual eval: " << actual << " after "
				<< elapsed.count() << " seconds" << std::endl;

		if ( actual < bestfopt ) {
			bestfopt = actual;
			bestx = xopt;
		}

		if ( timedOut ) {
			std::cout << "timeout detected..." << std::endl;
			break;
		}
	}

	const Duration elapsed = Clock::now() - start;
	std::cout << "----------------" << std::endl;
	std::cout << "best: " << bestfopt << " in " << ( i - sampleOffset ) <<
			" samples after " << elapsed.count() << " seconds at state " <<
			std::endl << bestx << std::endl;
}