Vertices<CoordType> SpatialModelMaximalRepulsion3D<CoordType>::drawSample(const int numPoints) { ENTER("Vertices<CoordType> SpatialModelMaximalRepulsion3D<CoordType>::drawSample(const int)"); const int outerSteps = getNumMonteCarloCycles(); const int innerSteps = numPoints; const CoordType beta = computeBeta(); const CoordType maxRadius = this->getTriMesh().equivalentRadius() / 50.0; Vertices<CoordType> vertices = SpatialModelHardcoreDistance3D<CoordType>::drawSample( numPoints ); RandomGenerator& randomGenerator = this->getRandomGenerator(); CoordType currentEnergy, newEnergy, deltaEnergy; Vector<CoordType> vertex; bool acceptTransition; int i, j, v; ConvergenceTest<CoordType> convergenceTest; CoordType sumEnergy; bool converged = false; _energyProfile.setZeros( outerSteps ); convergenceTest.setData( _energyProfile ); convergenceTest.setRange( 100 ); for (i = 0; !converged && i < outerSteps; ++i) { #if 0 if ( (i%20)==0 ) { string filename = "max-repulsion-vertices-" + StringTools::toString(i,4,'0') + ".vx"; vertices.save( filename, true ); } #endif for (j = 0, sumEnergy = 0.0; j < innerSteps; ++j) { v = randomGenerator.uniformL( numPoints ); vertex = vertices[v]; if ( j == 0 ) currentEnergy = energy( vertices ); moveVertex( vertices, v, maxRadius ); newEnergy = energy( vertices ); deltaEnergy = newEnergy - currentEnergy; acceptTransition = deltaEnergy <= .0 || randomGenerator.uniformLF() < exp( -beta*deltaEnergy ); if ( acceptTransition ) currentEnergy = newEnergy; else vertices[v] = vertex; sumEnergy += currentEnergy; } _energyProfile[i] = sumEnergy / innerSteps; converged = convergenceTest.isPositive( i ); } if ( !converged ) { Exception exception; exception.setWhere( "Vertices<CoordType> SpatialModelMaximalRepulsion3D<CoordType>::drawSample(const int)" ); exception.setWhat( "Convergence not reached after " + StringTools::toString(outerSteps) + " iterations" ); throw exception; } LEAVE(); return vertices; }