Skip to content

Commit

Permalink
Merge pull request #227 from bees4ever/PADDS_v05
Browse files Browse the repository at this point in the history
Padds v05
  • Loading branch information
thouska authored Aug 12, 2019
2 parents 269a5a7 + 67a8131 commit dac4df0
Show file tree
Hide file tree
Showing 26 changed files with 1,442 additions and 70 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ install:
- pip install pandas
- pip install scipy
- pip install click
- pip install deap
# Need to force pytest-cov to v2.6 as current version (2.6.1) is deprecated
- pip install pytest pytest-pep8 pytest-cov==2.6
- pip install pytest==3.10.1 pytest-pep8 pytest-cov==2.6
# Use docutils to generate html describe
- pip install docutils
- pip install numba
Expand Down
2 changes: 1 addition & 1 deletion spotpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@
from . import examples # Contains tutorials how to use SPOTPY
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

from . import unittests
__version__ = '1.5.2'
3 changes: 2 additions & 1 deletion spotpy/algorithms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@
from .fscabc import fscabc # Fitness Scaling Artificial Bee Colony
from .dream import dream # DiffeRential Evolution Adaptive Metropolis
from .list_sampler import list_sampler # Samples from given spotpy database
from .dds import dds # Dynamically Dimensioned Search algorithm by Bryan Tolson.
from .dds import dds # Dynamically Dimensioned Search algorithm by Bryan Tolson.
from .padds import padds
82 changes: 49 additions & 33 deletions spotpy/algorithms/_algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import numpy as np
import time
import threading
import inspect
import sys


try:
Expand Down Expand Up @@ -49,7 +51,7 @@ def __init__(self, repetitions, algorithm_name, optimization_direction, parnames
self.compare = self.maximizer
print('The objective function will be minimized')
if optimization_direction == 'grid':
self.compare = self.grid
self.compare = self.grid

self.rep = 0
self.parnames = parnames
Expand All @@ -66,9 +68,9 @@ def __init__(self, repetitions, algorithm_name, optimization_direction, parnames

def minimizer(self, objval, params):
if objval < self.objectivefunction_min:
self.objectivefunction_min = objval
self.objectivefunction_min = objval
self.params_min = list(params)

def maximizer(self, objval, params):
if objval > self.objectivefunction_max:
self.objectivefunction_max = objval
Expand All @@ -87,14 +89,15 @@ def __call__(self, objectivefunction, params, block_print=False):
self.rep+=1
if type(objectivefunction) == type([]): #TODO: change to iterable
self.compare(objectivefunction[0], params)

elif type(objectivefunction) == type(np.array([])):
pass
else:
self.compare(objectivefunction, params)


if self.rep == self.repetitions:
self.stop = True

if not block_print:
self.print_status()

Expand All @@ -107,38 +110,38 @@ def print_status(self):
timestr = time.strftime("%H:%M:%S", time.gmtime(round(avg_time_per_run * (self.repetitions - (self.rep + 1)))))
if self.optimization_direction == 'minimize':
text = '%i of %i, minimal objective function=%g, time remaining: %s' % (
self.rep, self.repetitions, self.objectivefunction_min, timestr)
self.rep, self.repetitions, self.objectivefunction_min, timestr)

if self.optimization_direction == 'maximize':
text = '%i of %i, maximal objective function=%g, time remaining: %s' % (
self.rep, self.repetitions, self.objectivefunction_max, timestr)
self.rep, self.repetitions, self.objectivefunction_max, timestr)

if self.optimization_direction == 'grid':
text = '%i of %i, min objf=%g, max objf=%g, time remaining: %s' % (
self.rep, self.repetitions, self.objectivefunction_min, self.objectivefunction_max, timestr)

print(text)
self.last_print = time.time()

def print_status_final(self):
print('\n*** Final SPOTPY summary ***')
print('Total Duration: ' + str(round((time.time() - self.starttime), 2)) + ' seconds')
print('Total Repetitions:', self.rep)

if self.optimization_direction == 'minimize':
if self.optimization_direction == 'minimize':
print('Minimal objective value: %g' % (self.objectivefunction_min))
print('Corresponding parameter setting:')
for i in range(self.parameters):
text = '%s: %g' % (self.parnames[i], self.params_min[i])
print(text)

if self.optimization_direction == 'maximize':
print('Maximal objective value: %g' % (self.objectivefunction_max))
print('Corresponding parameter setting:')
for i in range(self.parameters):
text = '%s: %g' % (self.parnames[i], self.params_max[i])
print(text)

if self.optimization_direction == 'grid':
print('Minimal objective value: %g' % (self.objectivefunction_min))
print('Corresponding parameter setting:')
Expand All @@ -151,10 +154,10 @@ def print_status_final(self):
for i in range(self.parameters):
text = '%s: %g' % (self.parnames[i], self.params_max[i])
print(text)

print('******************************\n')


def __repr__(self):
return 'Min objectivefunction: %g \n Max objectivefunction: %g' % (
self.objectivefunction_min, self.objectivefunction_max)
Expand Down Expand Up @@ -206,10 +209,10 @@ class _algorithm(object):
_unaccepted_parameter_types = (parameter.List, )

def __init__(self, spot_setup, dbname=None, dbformat=None, dbinit=True,
dbappend=False, parallel='seq', save_sim=True, breakpoint=None,
backup_every_rep=100, save_threshold=-np.inf, db_precision=np.float16,
dbappend=False, parallel='seq', save_sim=True, breakpoint=None,
backup_every_rep=100, save_threshold=-np.inf, db_precision=np.float16,
sim_timeout=None, random_state=None, optimization_direction='grid', algorithm_name=''):

# Initialize the user defined setup class
self.setup = spot_setup
param_info = parameter.get_parameters_array(self.setup, unaccepted_parameter_types=self._unaccepted_parameter_types)
Expand Down Expand Up @@ -290,6 +293,12 @@ def __init__(self, spot_setup, dbname=None, dbformat=None, dbinit=True,
self.repeat = ForEach(self.simulate)


# method "save" needs to know whether objective function result is list or float, default is float
self.like_struct_typ = type(1.1)




def __str__(self):
return '{type}({mtype}())->{dbname}'.format(
type=type(self).__name__,
Expand All @@ -307,7 +316,7 @@ def get_parameters(self):
return pars[self.non_constant_positions]

def set_repetiton(self, repetitions):
self.status = _RunStatistic(repetitions, self.algorithm_name,
self.status = _RunStatistic(repetitions, self.algorithm_name,
self.optimization_direction, self.parnames)
# In MPI, this command will do nothing on the master process
# but the worker processes are going to wait for jobs.
Expand Down Expand Up @@ -336,22 +345,29 @@ def _init_database(self, like, randompar, simulations):

self.dbinit = False


def __is_list_type(self, data):
if type(data) == type:
return data == list or data == type(np.array([]))
else:
return type(data) == list or type(data) == type(np.array([]))

def save(self, like, randompar, simulations, chains=1):
# Initialize the database if no run was performed so far
self._init_database(like, randompar, simulations)

#try if like is a list of values compare it with save threshold setting
try:
if self.__is_list_type(self.like_struct_typ) and self.__is_list_type(self.save_threshold):
if all(i > j for i, j in zip(like, self.save_threshold)): #Compares list/list
self.datawriter.save(like, randompar, simulations, chains=chains)
#If like value is not a iterable, it is assumed to be a float
except TypeError: # This is also used if not threshold was set
try:
if like>self.save_threshold: #Compares float/float
self.datawriter.save(like, randompar, simulations, chains=chains)
except TypeError:# float/list would result in an error, because it does not make sense
if like[0]>self.save_threshold: #Compares list/float
self.datawriter.save(like, randompar, simulations, chains=chains)
if not self.__is_list_type(self.like_struct_typ) and not self.__is_list_type(self.save_threshold):
if like>self.save_threshold: #Compares float/float
self.datawriter.save(like, randompar, simulations, chains=chains)
if self.__is_list_type(self.like_struct_typ) and not self.__is_list_type(self.save_threshold):
if like[0]>self.save_threshold: #Compares list/float
self.datawriter.save(like, randompar, simulations, chains=chains)
if not self.__is_list_type(self.like_struct_typ) and self.__is_list_type(self.save_threshold): #Compares float/list
if (like > self.save_threshold).all:
self.datawriter.save(like, randompar, simulations, chains=chains)

def read_breakdata(self, dbname):
''' Read data from a pickle file if a breakpoint is set.
Expand Down Expand Up @@ -392,7 +408,7 @@ def postprocessing(self, rep, params, simulation, chains=1, save_run=True, negat
# 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:
Expand Down
24 changes: 0 additions & 24 deletions spotpy/algorithms/demcz.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,30 +555,6 @@ def _dream_proposals(currentVectors, history, dimensions, nChains, DEpairs, gamm
return proposalVectors


def _dream2_proposals(currentVectors, history, dimensions, nChains, DEpairs,

gamma, jitter, eps):
"""
generates and returns proposal vectors given the current states
NOT USED ATM
"""

sampleRange = history.ncombined_history
currentIndex = np.arange(sampleRange - nChains, sampleRange)[:, np.newaxis]
combined_history = history.combined_history

# choose some chains without replacement to combine
chains = _random_no_replace(1, sampleRange - 1, nChains)

# makes sure we have already selected the current chain so it is not replaced
# this ensures that the the two chosen chains cannot be the same as the
# chain for which the jump is
chains += (chains >= currentIndex)

proposalVectors = combined_history[chains[:, 0], :]
return proposalVectors


class _GRConvergence:
"""
Gelman Rubin convergence diagnostic calculator class. It currently only calculates the naive
Expand Down
Loading

0 comments on commit dac4df0

Please sign in to comment.