Skip to content

Commit

Permalink
Fix for #202
Browse files Browse the repository at this point in the history
  • Loading branch information
thouska committed Feb 22, 2019
1 parent 43660d9 commit 7525462
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 36 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name = 'spotpy',
version = '1.4.4',
version = '1.4.5',
description = 'A Statistical Parameter Optimization Tool',
long_description=open(os.path.join(os.path.dirname(__file__),
"README.rst")).read(),
Expand Down
2 changes: 1 addition & 1 deletion spotpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@
from . import describe # Contains some helper functions to describe smaplers and setups
from .hydrology import signatures # Quantifies goodness of fit between simulation and evaluation data with hydrological signatures

__version__ = '1.4.4'
__version__ = '1.4.5'
11 changes: 7 additions & 4 deletions spotpy/algorithms/_algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def __init__(self):
self.repetitions = None
self.stop = False

def __call__(self, objectivefunction, params):
def __call__(self, objectivefunction, params, block_print=False):
self.curparmeterset = params
self.rep+=1
if type(objectivefunction) == type([]):
Expand All @@ -67,7 +67,8 @@ def __call__(self, objectivefunction, params):
self.bestrep = self.rep
if self.rep == self.repetitions:
self.stop = True
self.print_status()
if not block_print:
self.print_status()

def print_status(self):
# get str showing approximate timeleft to end of simulation in H, M, S
Expand Down Expand Up @@ -320,19 +321,21 @@ def update_params(self, params):
return self.all_params


def postprocessing(self, rep, params, simulation, chains=1, save_run=True, negativlike=False): # TODO: rep not necessaray
def postprocessing(self, rep, params, simulation, chains=1, save_run=True, negativlike=False, block_print=False): # TODO: rep not necessaray

params = self.update_params(params)
if negativlike is True:
like = -self.getfitness(simulation=simulation, params=params)
else:
like = self.getfitness(simulation=simulation, params=params)

self.status(like, params)
# Save everything in the database, if save is True
# This is needed as some algorithms just want to know the fitness,
# before they actually save the run in a database (e.g. sce-ua)
self.status(like,params,block_print=block_print)

if save_run is True and simulation is not None:

self.save(like, params, simulations=simulation, chains=chains)
if type(like)==type([]):
return like[0]
Expand Down
53 changes: 23 additions & 30 deletions spotpy/algorithms/sceua.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def simulate(self, id_params_tuple):
return _algorithm.simulate(self, id_params_tuple)

else: # complex-evolution
igs, x, xf, icall, cx, cf, sce_vars = id_params_tuple
igs, x, xf, cx, cf, sce_vars = id_params_tuple
self.npg, self.nopt, self.ngs, self.nspl, self.nps, self.bl, self.bu, self.status, self.stochastic_parameters = sce_vars
# Partition the population into complexes (sub-populations);
k1 = np.arange(self.npg, dtype=int)
Expand Down Expand Up @@ -107,7 +107,7 @@ def simulate(self, id_params_tuple):
s = cx[lcs, :]
sf = cf[lcs]

snew, fnew, icall, simulation = self._cceua(s, sf, icall)
snew, fnew, simulation = self._cceua(s, sf)
likes.append(fnew)
pars.append(snew)
sims.append(simulation)
Expand Down Expand Up @@ -188,7 +188,7 @@ def sample(self, repetitions, ngs=20, kstop=100, pcento=0.0000001, peps=0.000000
# Calculate the objective function
like = self.postprocessing(icall, randompar, simulations,chains=0)
xf[rep] = like
icall += 1
icall+=1
if self.status.stop:
print('Stopping samplig. Maximum number of repetitions reached already during burn-in')
proceed = False
Expand All @@ -206,19 +206,18 @@ def sample(self, repetitions, ngs=20, kstop=100, pcento=0.0000001, peps=0.000000

BESTF = bestf
BESTX = bestx
ICALL = icall

# Computes the normalized geometric range of the parameters
gnrng = np.exp(
np.mean(np.log((np.max(x[:, self.stochastic_parameters], axis=0) - np.min(x[:, self.stochastic_parameters], axis=0)) / bound[self.stochastic_parameters])))

# Check for convergency;
if icall >= repetitions:
if self.status.rep >= repetitions:
print('*** OPTIMIZATION SEARCH TERMINATED BECAUSE THE LIMIT')
print('ON THE MAXIMUM NUMBER OF TRIALS ')
print(repetitions)
print('HAS BEEN EXCEEDED. SEARCH WAS STOPPED AT TRIAL NUMBER:')
print(icall)
print(self.status.rep)
print('OF THE INITIAL LOOP!')

if gnrng < peps:
Expand All @@ -233,7 +232,6 @@ def sample(self, repetitions, ngs=20, kstop=100, pcento=0.0000001, peps=0.000000
criter_change_pcent = 1e+5

self.repeat.setphase('ComplexEvo')

print ('ComplexEvo started...')
proceed = True
while icall < repetitions and gnrng > peps and criter_change_pcent > pcento and proceed == True:
Expand All @@ -246,26 +244,26 @@ def sample(self, repetitions, ngs=20, kstop=100, pcento=0.0000001, peps=0.000000
if remaining_runs <= self.ngs:
self.ngs = remaining_runs-1
proceed = False

sce_vars = [self.npg, self.nopt, self.ngs, self.nspl,
self.nps, self.bl, self.bu, self.status, self.stochastic_parameters]
param_generator = ((rep, x, xf, icall, cx, cf, sce_vars)
param_generator = ((rep, x, xf, cx, cf, sce_vars)
for rep in range(int(self.ngs)))
for igs, likes, pars, sims, cx, cf, k1, k2 in self.repeat(param_generator):
icall += len(likes)
x[k2, :] = cx[k1, :]
xf[k2] = cf[k1]
for i in range(len(likes)):
if not self.status.stop:
like = self.postprocessing(icall+i, pars[i], sims[i], chains=i+1)
like = self.postprocessing(i, pars[i], sims[i], chains=i+1)
else:
#Collect data from all slaves but do not save
proceed=False
like = self.postprocessing(icall+i, pars[i], sims[i], chains=i+1, save_run=False)
like = self.postprocessing(i, pars[i], sims[i], chains=i+1, save_run=False)
print('Skipping saving')

if self.breakpoint == 'write' or self.breakpoint == 'readandwrite'\
and icall >= self.backup_every_rep:
work = (icall, (x, xf), gnrng)
and self.status.rep >= self.backup_every_rep:
work = (self.status.rep, (x, xf), gnrng)
self.write_breakdata(self.dbname, work)

# End of Loop on Complex Evolution;
Expand All @@ -282,7 +280,6 @@ def sample(self, repetitions, ngs=20, kstop=100, pcento=0.0000001, peps=0.000000
# appenden en op einde reshapen!!
BESTX = np.append(BESTX, bestx, axis=0)
BESTF = np.append(BESTF, bestf)
ICALL = np.append(ICALL, icall)

# Computes the normalized geometric range of the parameters
gnrng = np.exp(
Expand All @@ -291,7 +288,7 @@ def sample(self, repetitions, ngs=20, kstop=100, pcento=0.0000001, peps=0.000000
criter = np.append(criter, bestf)

# Check for convergency;
if icall >= repetitions:
if self.status.rep >= repetitions:
print('*** OPTIMIZATION SEARCH TERMINATED BECAUSE THE LIMIT')
print('ON THE MAXIMUM NUMBER OF TRIALS ')
print(repetitions)
Expand Down Expand Up @@ -323,7 +320,7 @@ def sample(self, repetitions, ngs=20, kstop=100, pcento=0.0000001, peps=0.000000
break

# End of the Outer Loops
text = 'SEARCH WAS STOPPED AT TRIAL NUMBER: %d' % icall
text = 'SEARCH WAS STOPPED AT TRIAL NUMBER: %d' % self.status.rep
print(text)
text = 'NORMALIZED GEOMETRIC RANGE = %f' % gnrng
print(text)
Expand All @@ -336,7 +333,7 @@ def sample(self, repetitions, ngs=20, kstop=100, pcento=0.0000001, peps=0.000000
self.final_call()


def _cceua(self, s, sf, icall):
def _cceua(self, s, sf):
# This is the subroutine for generating a new point in a simplex
#
# s(.,.) = the sorted simplex in order of increasing function values
Expand Down Expand Up @@ -383,38 +380,34 @@ def _cceua(self, s, sf, icall):
snew = self._sampleinputmatrix(1, self.nopt)[0]

## fnew = functn(self.nopt,snew);
_, _, simulations = _algorithm.simulate(self, (icall, snew))
like = self.postprocessing(icall, snew, simulations, save_run=False)
_, _, simulations = _algorithm.simulate(self, (1, snew))
like = self.postprocessing(1, snew, simulations, save_run=False, block_print=True)
fnew = like
icall += 1
if self.status.stop:
print('Stopping complex evolution')
return snew, fnew, icall, simulations
return snew, fnew, simulations

# Reflection failed; now attempt a contraction point:
if fnew > fw:
snew = sw + beta * (ce - sw)
snew[constant_parameters] = sw[constant_parameters]

_, _, simulations = _algorithm.simulate(self, (icall, snew))
like = self.postprocessing(icall, snew, simulations, save_run=False)
_, _, simulations = _algorithm.simulate(self, (2, snew))
like = self.postprocessing(2, snew, simulations, save_run=False, block_print=True)
fnew = like
icall += 1
if self.status.stop:
print('Stopping complex evolution')
return snew, fnew, icall, simulations
return snew, fnew, simulations


# Both reflection and contraction have failed, attempt a random point;
if fnew > fw:
snew = self._sampleinputmatrix(1, self.nopt)[0]
_, _, simulations = _algorithm.simulate(self, (icall, snew))
like = self.postprocessing(icall, snew, simulations, save_run=False)
_, _, simulations = _algorithm.simulate(self, (3, snew))
like = self.postprocessing(3, snew, simulations, save_run=False, block_print=True)
fnew = like
icall += 1

# END OF CCE
return snew, fnew, icall, simulations
return snew, fnew, simulations

def _sampleinputmatrix(self, nrows, npars):
'''
Expand Down

0 comments on commit 7525462

Please sign in to comment.