//-------------------------------------------------------------------------------------------------------- // Public: ZeroTemperatureOptimization //-------------------------------------------------------------------------------------------------------- boost::tuple<SMatrix3x3, Float, Float> COrientationMC::ZeroTemperatureOptimizationWithVariance( const SMatrix3x3 & oInitialOrientation, Float fAngularRadius, COverlapFunction & oObjectiveFunction, Int nMaxMCStep ) { SMatrix3x3 oOptimalState = oInitialOrientation; COverlapFunction::ValueType fMinimizedCost = oObjectiveFunction( oInitialOrientation ); Float Average = fMinimizedCost; // Running variance calculation due to Knuth, via Wikipedia int NumSampledPoints = 1; Float Variance = 0; //----------------- // Converting fRadius -- an angular // distance to a radius in R^3 of the // interpolation parameter space //----------------- Float fRadius = tan( fAngularRadius ) / sqrt( 12.0 ); // sqrt(12) = 2 * sqrt(3) for ( Int i = 0; i < nMaxMCStep; i ++ ) { Float fX = GetRandomVariable( -fRadius, fRadius ); Float fY = GetRandomVariable( -fRadius, fRadius ); Float fZ = GetRandomVariable( -fRadius, fRadius ); SQuaternion q = oUniformGridGen.GetNearIdentityPoint( fX, fY, fZ ); SMatrix3x3 oDelta = q.GetRotationMatrix3x3(); SMatrix3x3 oCurrentState = oDelta * oOptimalState; COverlapFunction::ValueType fCurrentCost = oObjectiveFunction( oCurrentState ); if( fCurrentCost < fMinimizedCost ) { oOptimalState = oCurrentState; fMinimizedCost = fCurrentCost; } //---------------- // variance calculation // - calculate teh variance of the sampled region //---------------- NumSampledPoints ++; Float Delta = fCurrentCost - Average; Average = Average + Delta / Float( NumSampledPoints ); Variance += Delta * ( fCurrentCost - Average ); } if( NumSampledPoints > 1 ) Variance = Variance / Float( NumSampledPoints - 1); else Variance = -1.0; // Named return value optimization boost::tuple<SMatrix3x3, Float, Float> oRes = boost::make_tuple( oOptimalState, fMinimizedCost, Variance ); return oRes; }
void MacroCellUrbanAreaChannelRealization::UpdateModels () { #ifdef TEST_PROPAGATION_LOSS_MODEL std::cout << "\t --> UpdateModels" << std::endl; #endif //update shadowing m_shadowing = 0; double probability = GetRandomVariable (101) / 100.0; for (int i = 0; i < 201; i++) { if (probability <= shadowing_probability[i]) { m_shadowing = shadowing_value[i]; break; } } #ifdef TEST_PROPAGATION_LOSS_MODEL std::cout << "\t\t new shadowing" << m_shadowing << std::endl; #endif UpdateFastFading (); SetLastUpdate (); }
//-------------------------------------------------------------------------------------------------------- // Public: ZeroTemperatureOptimization //-------------------------------------------------------------------------------------------------------- std::pair<SMatrix3x3, Float> COrientationMC::ZeroTemperatureOptimization( const SMatrix3x3 & oInitialOrientation, Float fAngularRadius, COverlapFunction & oObjectiveFunction, Int nMaxMCStep ) { SMatrix3x3 oOptimalState = oInitialOrientation; COverlapFunction::ValueType fMinimizedCost = oObjectiveFunction( oInitialOrientation ); //----------------- // Converting fRadius -- an angular // distance to a radius in R^3 of the // interpolation parameter space //----------------- Float fRadius = tan( fAngularRadius ) / sqrt( 12.0 ); // sqrt(12) = 2 * sqrt(3) for ( Int i = 0; i < nMaxMCStep; i ++ ) { Float fX = GetRandomVariable( -fRadius, fRadius ); Float fY = GetRandomVariable( -fRadius, fRadius ); Float fZ = GetRandomVariable( -fRadius, fRadius ); SQuaternion q = oUniformGridGen.GetNearIdentityPoint( fX, fY, fZ ); SMatrix3x3 oDelta = q.GetRotationMatrix3x3(); SMatrix3x3 oCurrentState = oDelta * oOptimalState; COverlapFunction::ValueType fCurrentCost = oObjectiveFunction( oCurrentState ); if( fCurrentCost < fMinimizedCost ) { oOptimalState = oCurrentState; fMinimizedCost = fCurrentCost; } } // Named return value optimization std::pair<SMatrix3x3, Float> oRes = std::make_pair( oOptimalState, fMinimizedCost ); return oRes; }
//-------------------------------------------------------------------------------------------------------- // Public: RandomRestartZeroTemp // // Parameter: fDriftDistance is the side of the box of the local search space. // //-------------------------------------------------------------------------------------------------------- std::pair<SMatrix3x3, Float> COrientationMC::RandomRestartZeroTemp( const SMatrix3x3 & oInitialOrientation, Float fAngularStepSize, Float fAngularBoxSideLength, COverlapFunction & oObjectiveFunction, Int nMaxMCStep, Int nMaxFailedRestarts, Float fMaxConvergenceCost ) { SMatrix3x3 oGlobalOptimalState = oInitialOrientation; SMatrix3x3 oCurrentState = oInitialOrientation; COverlapFunction::ValueType fGlobalMinCost = oObjectiveFunction( oInitialOrientation ); Float fCurAngularStepSize = fAngularStepSize; Int nTotalStepTaken = 0; Int nSuccessiveRestarts = 0; Int nMinErgodicSteps = 2 * pow( fAngularBoxSideLength / fCurAngularStepSize, 3 ); // Number of steps required to be ergodic Int nOptimizationSteps = nMinErgodicSteps; while( nTotalStepTaken < nMaxMCStep ) { nOptimizationSteps = std::min( nOptimizationSteps, ( nMaxMCStep - nTotalStepTaken ) ); nOptimizationSteps = std::max( nOptimizationSteps, 0 ); Float fCurrentCost; SMatrix3x3 oTmpResOrient; boost::tie( oTmpResOrient, fCurrentCost ) = ZeroTemperatureOptimization( oCurrentState, fCurAngularStepSize, oObjectiveFunction, nOptimizationSteps ); nTotalStepTaken += nOptimizationSteps; if( fCurrentCost >= fGlobalMinCost ) // restart with new position { Float fRadius = tan( fAngularBoxSideLength ) / sqrt( 48.0 ); // sqrt(48) = 4 * sqrt(3) ( random start radius ) Float fX = GetRandomVariable( -fRadius, fRadius ); Float fY = GetRandomVariable( -fRadius, fRadius ); Float fZ = GetRandomVariable( -fRadius, fRadius ); SQuaternion q = oUniformGridGen.GetNearIdentityPoint( fX, fY, fZ ); SMatrix3x3 oDelta = q.GetRotationMatrix3x3(); oCurrentState = oDelta * oInitialOrientation; //---------- // Reset search parameters //---------- fCurAngularStepSize = fAngularStepSize; nSuccessiveRestarts ++; nOptimizationSteps = nMinErgodicSteps; } else // continuation of search, with narrowing of steps size { nSuccessiveRestarts = 0; fGlobalMinCost = fCurrentCost; oGlobalOptimalState = oTmpResOrient; oCurrentState = oTmpResOrient; fCurAngularStepSize *= Float( 0.5 ); // reduce step size } if( fGlobalMinCost < fMaxConvergenceCost ) // convergence -- move criterion to user defined break; // cheating -- should really allow convergence instead if( nSuccessiveRestarts > nMaxFailedRestarts ) // search failed change this to user defined break; } // Named return value optimization std::pair<SMatrix3x3, Float> oRes = std::make_pair( oGlobalOptimalState, fGlobalMinCost ); return oRes; }
//-------------------------------------------------------------------------------------------------------- // Public: AdaptiveSamplingZeroTemp // // This is essetially depth first search, non-recursive // //-------------------------------------------------------------------------------------------------------- std::pair<SMatrix3x3, Float> COrientationMC::AdaptiveSamplingZeroTemp( const SMatrix3x3 & oInitialOrientation, Float fCostFnAngularResolution, Float fSearchRegionAngularSideLength, COverlapFunction & oObjectiveFunction, Int nMaxMCStep, Int NumMaxStratifiedSamples, Float fConvergenceVariance, Float fMaxConvergenceCost ) { SMatrix3x3 oGlobalOptimalState = oInitialOrientation; SMatrix3x3 oCurrentState = oInitialOrientation; COverlapFunction::ValueType fGlobalMinCost = oObjectiveFunction( oInitialOrientation ); Float InitialSubregionRadius = tan( fSearchRegionAngularSideLength ) / sqrt( 48.0 ); // sqrt(48) = 4 * sqrt(3) ( random start radius ) Int nTotalStepTaken = 0; Int NumGlobalPointsTaken = 0; Float fCurrentVariance; Float SubregionRadius = InitialSubregionRadius; while( nTotalStepTaken < nMaxMCStep ) { Int NumSubregionSteps = Int( pow( ceil(SubregionRadius / fCostFnAngularResolution), 2.7 ) ); // Number of steps it takes to adequately // sample each subregions without missing // a cost function (giving it less more steps) NumSubregionSteps = std::max( NumSubregionSteps, 10 ); // at least 20 steps Float fCurrentCost; SMatrix3x3 oTmpResOrient; boost::tie( oTmpResOrient, fCurrentCost, fCurrentVariance ) = ZeroTemperatureOptimizationWithVariance( oCurrentState, SubregionRadius, oObjectiveFunction, NumSubregionSteps ); if( fCurrentVariance > fConvergenceVariance ) nMaxMCStep += NumSubregionSteps; nTotalStepTaken += NumSubregionSteps; if( fCurrentCost >= fGlobalMinCost ) // restart with new position { //---------- // Backtrack/Reset search parameters //---------- SubregionRadius = std::min( static_cast<Float>( 2.0 * SubregionRadius), fSearchRegionAngularSideLength ); NumGlobalPointsTaken ++; Float fX = GetRandomVariable( -SubregionRadius, SubregionRadius ); Float fY = GetRandomVariable( -SubregionRadius, SubregionRadius ); Float fZ = GetRandomVariable( -SubregionRadius, SubregionRadius ); SQuaternion q = oUniformGridGen.GetNearIdentityPoint( fX, fY, fZ ); SMatrix3x3 oDelta = q.GetRotationMatrix3x3(); oCurrentState = oDelta * oInitialOrientation; } else // continuation of search, with narrowing of steps size { fGlobalMinCost = fCurrentCost; oGlobalOptimalState = oTmpResOrient; oCurrentState = oTmpResOrient; SubregionRadius *= Float( 0.5 ); // reduce step size } if( (fGlobalMinCost < fMaxConvergenceCost) && fabs( fCurrentVariance ) < fConvergenceVariance ) // convergence -- move criterion to user defined break; } std::cout << RADIAN_TO_DEGREE( LatticeSymmetry::GetMisorientation( LatticeSymmetry::CCubicSymmetry::Get(), oGlobalOptimalState, oInitialOrientation ) ) << "\t|R_0| " << RADIAN_TO_DEGREE( InitialSubregionRadius ) << "\t|Step | " << nTotalStepTaken << "\t|GlbPts| " << NumGlobalPointsTaken << "\t|R_c| " << RADIAN_TO_DEGREE( SubregionRadius ) << "\t|MCS| " << nMaxMCStep << "\t|Var| " << fCurrentVariance << "\t|C_i| " << oObjectiveFunction( oInitialOrientation ) << "\t|C_f|" << fGlobalMinCost << "\t[ " << RadianToDegree( oInitialOrientation.GetEulerAngles() ) << "]" << std::endl; // Named return value optimization std::pair<SMatrix3x3, Float> oRes = std::make_pair( oGlobalOptimalState, fGlobalMinCost ); return oRes; }