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(); }
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; } } }
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; }