#!/usr/bin/env python
"""
Simulated Annealing

The pythonic version of the simple example from the gsl reference document.
"""
# Author: Pierre Schnizer
# Date  : December 2003
import pygsl._numobj as Numeric
import pygsl.siman as siman
import pygsl.rng   as rng

# how many points do we try before stepping
N_TRIES = 200             
     
# how many iterations for each T? 
ITERS_FIXED_T = 10        
     
# max step size in random walk 
STEP_SIZE = 10            

# Boltzmann constant
K = 1.0                   
     
# initial temperature
T_INITIAL = 0.002         

# damping factor for temperature 
MU_T = 1.005              
T_MIN = 2.0e-6
     

class MySiman(siman.NumericEnsemble):       
    def EFunc(self):
        x = self._data
        t = x-1.0
        t2 = t*t
        # Necessary as my python does not handle the exp of big numbers
        # correctly
        if t2 > 700:
            tmp = 0
        else:
            tmp = Numeric.exp(-t2)
        return tmp*Numeric.sin(8*x)
     
    def Metric(self, outer):     
        return Numeric.absolute(self._data - outher.GetData())

    def Step(self, rng, step_size):
        old_x = self._data
        
        u = rng.uniform();
        new_x = u * 2 * step_size - step_size + old_x;
        self._data = new_x


    def Print(self):
        print "%12g" % self._data,

m = MySiman()
m.SetData(15.5)

r = rng.rng()

result = siman.solve(r, m, do_print=0)
#result = siman.solve(r, m, do_print=1, n_tries=N_TRIES, iters_fixed_T=ITERS_FIXED_T,
#                     step_size=STEP_SIZE, k=K, t_initial=T_INITIAL, mu_t = MU_T,
#                     t_min=T_MIN)
print "# Found minimum at %f" % result.GetData()
