def initializeParticlesInsideBox( self, lfBoxLower, lfBoxUpper, random01=DREAM.RandomGenerator(sType="default")): ''' Initialize the particle swarm state with randomized particles (determined by gen_random01) inside a box bounded by the parameters box_lower and box_upper. The i-th entry in these parameters respectively represent the lower and upper bounds on the particle position values for the i-th dimension. The parameter random01 controls the distribution of the particles. lfBoxLower : a one-dimensional NumPy array with lfBoxLower.shape[0] = self.getNumDimensions() lfBoxUpper : a one-dimensional NumPy array with lfBoxLower.shape[0] = self.getNumDimensions() random01 : a DREAM.RandomGenerator instance that produces floats in [0,1] ''' iNumDims = self.getNumDimensions() if (lfBoxLower.shape != (iNumDims, )): raise InputError( "lfBoxLower", "lfBoxLower.shape should be (self.getNumDimensions(),)") if (lfBoxUpper.shape != (iNumDims, )): raise InputError( "lfBoxUpper", "lfBoxUpper.shape should be (self.getNumDimensions(),)") pLibDTSG.tsgParticleSwarmState_InitializeParticlesInsideBox( self.pStatePntr, as_ctypes(lfBoxLower), as_ctypes(lfBoxUpper), c_char_p(random01.sType), c_int(random01.iSeed), type_dream_random(random01.pCallable))
def genGaussianSamples(lfMean, lfDeviation, iNumSamples, random01=RandomGenerator(sType="default")): ''' Wrapper around TasDREAM::tsgGenGaussianSamples() Using the one dimensional numpy.ndarrays lfMean and lfVariance, which describe the mean and standard deviation of a Gaussian distribution, generate iNumSamples from a normal (Gaussian) distribution using the random01 engine. The lengths of lfMean and lfDeviation must match. Returns a two dimensional numpy.ndarray of shape = (iNumSamples, len(lfLower)), ''' if len(lfMean) != len(lfDeviation): raise InputError("lfDeviation", "The length of lfMean and lfDeviation do not match.") aMean = np.array(lfMean) aDeviation = np.array(lfDeviation) iNumDims = len(lfMean) aResult = np.empty((iNumDims * iNumSamples, ), np.float64) pLibDTSG.tsgGenGaussianSamples(iNumDims, iNumSamples, np.ctypeslib.as_ctypes(aMean), np.ctypeslib.as_ctypes(aDeviation), c_char_p(random01.sType), random01.iSeed, random01.pCallable, np.ctypeslib.as_ctypes(aResult)) return aResult.reshape((iNumSamples, iNumDims))
def genUniformSamples(lfLower, lfUpper, iNumSamples, random01=RandomGenerator(sType="default")): ''' Wrapper around TasDREAM::genUniformSamples() Using the one dimensional numpy.ndarrays lfLower and lfUpper, which describe the upper and lower bounds of a hypercube, generate iNumSamples from a uniform distribution using the random01 engine. The lengths of lfLower and lfUpper must match. Returns a two dimensional numpy.ndarray of shape = (iNumSamples, len(lfLower)), ''' if len(lfLower) != len(lfUpper): raise InputError("lfUpper", "The length of lfLower and lfUpper do not match.") aLower = np.array(lfLower) aUpper = np.array(lfUpper) iNumDims = len(lfLower) aResult = np.empty((iNumDims * iNumSamples, ), np.float64) pLibDTSG.tsgGenUniformSamples(iNumDims, iNumSamples, np.ctypeslib.as_ctypes(aLower), np.ctypeslib.as_ctypes(aUpper), c_char_p(random01.sType), random01.iSeed, random01.pCallable, np.ctypeslib.as_ctypes(aResult)) return aResult.reshape((iNumSamples, iNumDims))
def __init__(self, sType, callableOrMagnitude=0.0): ''' Constructor that translates the input arguments into inputs to the internal Tasmanian API. See help(Tasmanian.DREAM.IndependentUpdate) ''' self.TasmanianDreamIndependentUpdate = True if not ( (sys.version_info.major == 3 and isinstance(sType, str)) or (sys.version_info.major == 2 and isinstance(sType, basestring))): if not callable(sType): raise InputError( "sType", "DREAM.IndependentUpdate() the sType must be either a string or a callable object" ) self.sType = "null" self.fMagnitude = 0.0 self.pCallable = type_dream_iupdate( lambda n, x, err: iupdateWrapper(sType, n, x, err)) else: self.sType = sType self.fMagnitude = callableOrMagnitude self.pCallable = type_dream_iupdate(lambda: 1) if (sys.version_info.major == 3): self.sType = bytes(self.sType, encoding='utf8')
def __init__(self, sType, *args): ''' Constructor that translates the input arguments into inputs to the internal Tasmanian API. See help(Tasmanian.DREAM.Domain) ''' self.TasmanianDreamDomain = True if hasattr(sType, "TasmanianSparseGridObject"): self.pGrid = sType.pGrid self.pLower = None self.pUpper = None self.pCallable = type_dream_domain(lambda: 1) elif sType == "hypercube": self.pGrid = None self.pLower = np.ctypeslib.as_ctypes(args[0]) self.pUpper = np.ctypeslib.as_ctypes(args[1]) self.pCallable = type_dream_domain(lambda: 1) elif sType == "unbounded": self.pGrid = None self.pLower = None self.pUpper = None self.pCallable = type_dream_domain( lambda n, x: domainWrapper(lambda x: True, n, x)) elif sType == "custom": self.pGrid = None self.pLower = None self.pUpper = None self.pCallable = type_dream_domain( lambda n, x: domainWrapper(args[0], n, x)) else: raise InputError( "Domain", "DREAM.Domain() was given an unknown domain type")
def setState(self, llfNewState): ''' Set a new state for the DREAM chains. llfNewState: is a two dimensional numpy.ndarray with .shape[0] = .getNumChains() .shape[1] = .getNumDimensions() ''' iNumChains = self.getNumChains() iNumDims = self.getNumDimensions() if (llfNewState.shape[0] != iNumChains): raise InputError("llfNewState", "llfNewState.shape[0] should match the number of chains") if (llfNewState.shape[1] != iNumDims): raise InputError("llfNewState", "llfNewState.shape[1] should match the number of dimensions") pLibDTSG.tsgDreamStateSet(self.pStatePntr, np.ctypeslib.as_ctypes(llfNewState.reshape((iNumChains * iNumDims,))))
def __init__(self, model, likelihood, prior, typeForm=typeRegform): ''' Constructor that translates the input arguments into inputs to the internal Tasmanian API. See help(Tasmanian.DREAM.Posterior) ''' self.TasmanianPosterior = True self.typeForm = typeForm if self.typeForm not in [typeRegform, typeLogform]: raise InputError( "typeForm", "unknown sampling form, must use typeRegform or typeLogform") self.model = model if hasattr(self.model, "TasmanianSparseGridObject"): self.bUseSparsegrid = True elif callable(self.model): self.bUseSparsegrid = False else: raise InputError( "model", "model should be either an instance of Tasmanian.SparseGrid() or a callable object." ) self.likelihood = likelihood if hasattr(self.likelihood, "TasmanianLikelihood"): self.bUseTasLikely = True elif callable(self.likelihood): self.bUseTasLikely = False else: raise InputError( "likelihood", "likelihood should be either derived from TasmanianLikelihood() or a callable object." ) if prior == "uniform": self.typePrior = typePriorUniform elif callable(prior): self.typePrior = typePriorCallable self.prior = prior else: raise InputError( "prior", "prior should be either 'uniform' or a callable object.")
def __init__(self, sType="default", iSeed=-1, callableRNG=lambda: 1): ''' Constructor that translates the input arguments into inputs to the internal Tasmanian API. See help(Tasmanian.DREAM.RandomGenerator) ''' if sType not in ["default", "minstd_rand"]: raise InputError("sType", "DREAM.RandomGenerator() the sType is invalid") if not callable(callableRNG): raise InputError( "callableRNG", "DREAM.RandomGenerator() the callableRNG must be a callable object" ) self.TasmanianDreamRandomGenerator = True self.sType = sType if (sys.version_info.major == 3): self.sType = bytes(self.sType, encoding='utf8') self.iSeed = iSeed self.pCallable = type_dream_random(callableRNG)
def setParticleVelocities(self, llfNewPVelcs): ''' Set new particle velocities from a NumPy array. llfNewPVelcs : a two-dimensional numpy.ndarray with llfNewPVelcs.shape[0] = self.getNumParticles() llfNewPVelcs.shape[1] = self.getNumDimensions() ''' iNumPart = self.getNumParticles() iNumDims = self.getNumDimensions() if (llfNewPVelcs.shape[0] != iNumPart): raise InputError( "llfNewPVelcs", "llfNewPVelcs.shape[0] should match the number of particles") if (llfNewPVelcs.shape[1] != iNumDims): raise InputError( "llfNewPVelcs", "llfNewPVelcs.shape[1] should match the number of dimensions") llfNewPVelcs.resize((iNumDims * iNumPart, )) pLibDTSG.tsgParticleSwarmState_SetParticleVelocities( self.pStatePntr, as_ctypes(llfNewPVelcs))
def setBestParticlePositions(self, llfNewBPPosns): ''' Set new best particle positions from a NumPy array. llfNewBPPosns : a two-dimensional numpy.ndarray with llfNewPVelcs.shape[0] = self.getNumParticles() + 1 llfNewPVelcs.shape[1] = self.getNumDimensions() ''' iNumPart = self.getNumParticles() iNumDims = self.getNumDimensions() if (llfNewBPPosns.shape[0] != iNumPart + 1): raise InputError( "llfNewBPPosns", "llfNewBPPosns.shape[0] should match the number of particles + 1" ) if (llfNewBPPosns.shape[1] != iNumDims): raise InputError( "llfNewBPPosns", "llfNewBPPosns.shape[1] should match the number of dimensions") llfNewBPPosns.resize(((iNumPart + 1) * iNumDims, )) pLibDTSG.tsgParticleSwarmState_SetBestParticlePositions( self.pStatePntr, as_ctypes(llfNewBPPosns))
def __init__(self, lfVariance, lfData, iNumSamples=1): ''' Make a new likelihood with the given data. lfVariance: one dimensional ndarray with the data variance lfData: one dimensional ndarray with the data iNumSamples: number of samples used for the data ''' super(LikelihoodGaussAnisotropic, self).__init__() if (len(lfVariance) != len(lfData)): raise InputError("lfVariance", "Mismatch in size of variance and data vectors.") iNumOutputs = len(lfData) self.pClassPntr = pLibDTSG.tsgMakeLikelihoodGaussAnisotropic( iNumOutputs, np.ctypeslib.as_ctypes(lfVariance), np.ctypeslib.as_ctypes(lfData), iNumSamples)
def __init__(self, callableOrMagnitude): ''' Constructor that translates the input arguments into inputs to the internal Tasmanian API. See help(Tasmanian.DREAM.DifferentialUpdate) ''' self.TasmanianDreamDifferentialUpdate = True if (((sys.version_info.major == 3) and isinstance(callableOrMagnitude, int)) or ((sys.version_info.major == 2) and isinstance(callableOrMagnitude, (int, long)))): self.iPercent = callableOrMagnitude self.pCallable = type_dream_dupdate(lambda: 1) else: if not callable(callableOrMagnitude): raise InputError( "callableOrMagnitude", "DREAM.DifferentialUpdate() the callableOrMagnitude must be either an integer or a callable object" ) self.iPercent = -1 self.pCallable = type_dream_dupdate(callableOrMagnitude)
def Sample(iNumBurnup, iNumCollect, probability_distibution, domain_description, dream_state, independent_update=IndependentUpdate("none"), differential_update=DifferentialUpdate(100), random01=RandomGenerator(sType="default"), typeForm=typeRegform): ''' Wrapper to TasDREAM::SampleDREAM(). The Markov Chain Monte Carlo algorithms generate chains of samples with distribution that converges to the target probability density. The current state of the chains (i.e., the last vector) is updated by first generating a set of proposals and then accepting/rejecting randomly but with the constraint that the only accepted vectors belong to the specified domain. The proposals are constructed from two components, the independent component that is iid random with zero mean and the differential component that is takes from the scaled difference between the state of two randomly selected chains. iNumBurnup: is a non-negative integer that indicates the number of iterations to discard, i.e., samples that have no statistical significance because the chain state has not converged to the target probability distribution. iNumCollect: is a non-negative integer that indicates the number of iterations to store in the state history. probability_distibution: is either an instance of DREAM.Posterior() or a callable object that accepts a two dimensional numpy.ndarray and then returns a one dimensional numpy.ndarray. See help(Tasmanian.DREAM.Posterior) Can also use a lambda to capture a Tasmanian sparse grid, i.e., lambda x : grid.evaluateBatch(x).reshape((x.shape[0],)) domain_description: is an instance of DREAM.Domain() See help(Tasmanian.DREAM.Domain) dream_state: is an instance of DREAM.State() with number of dimensions that match the dimensions used by the probability_distibution. See help(Tasmanian.DREAM.State) On input the state chains have to be initialized, on output the history will be populated with the iNumCollect samples. (if the history is not empty, the new samples will be appended) independent_update: is an instance of DREAM.IndependentUpdate() See help(Tasmanian.DREAM.IndependentUpdate) differential_update: is an instance of DREAM.DifferentialUpdate() See help(Tasmanian.DREAM.DifferentialUpdate) random01: is an instance of DREAM.RandomGenerator() See help(Tasmanian.DREAM.RandomGenerator) typeForm: is either DREAM.typeRegform or DREAM.typeLogform The form modifies the accept/reject criteria based on whether the probability_distibution returns the actual distribution of interest or the logarithm of that (which is sometimes more stable and/or easier to approximate with a sparse grid). Note: the typeForm must match the return of the probability_distibution. ''' if not hasattr(domain_description, "TasmanianDreamDomain"): raise InputError( "domain_description", "domain_description must be an instance of DREAM.Domain()") if not hasattr(dream_state, "TasmanainDreamState"): raise InputError("dream_state", "dream_state must be an instance of DREAM.State()") if not hasattr(independent_update, "TasmanianDreamIndependentUpdate"): raise InputError( "independent_update", "independent_update must be an instance of DREAM.IndependentUpdate()" ) if not hasattr(differential_update, "TasmanianDreamDifferentialUpdate"): raise InputError( "differential_update", "differential_update must be an instance of DREAM.DifferentialUpdate()" ) if not hasattr(random01, "TasmanianDreamRandomGenerator"): raise InputError( "random01", "random01 must be an instance of DREAM.RandomGenerator()") if typeForm not in [typeRegform, typeLogform]: raise InputError( "typeForm", "unknown sampling form, must use typeRegform or typeLogform") pErrorCode = (c_int * 1)() if hasattr(probability_distibution, "TasmanianPosterior"): pLibDTSG.tsgDreamSample( typeForm, c_int(iNumBurnup), c_int(iNumCollect), type_dream_pdf(lambda m, n, x, y, err: pdfWrapper( probability_distibution.distribution(), m, n, x, y, err)), dream_state.pStatePntr, domain_description.pGrid, domain_description.pLower, domain_description.pUpper, domain_description.pCallable, c_char_p(independent_update.sType), independent_update.fMagnitude, independent_update.pCallable, differential_update.iPercent, differential_update.pCallable, c_char_p(random01.sType), random01.iSeed, random01.pCallable, pErrorCode) elif callable(probability_distibution): pLibDTSG.tsgDreamSample( typeForm, c_int(iNumBurnup), c_int(iNumCollect), type_dream_pdf(lambda m, n, x, y, err: pdfWrapper( probability_distibution, m, n, x, y, err)), dream_state.pStatePntr, domain_description.pGrid, domain_description.pLower, domain_description.pUpper, domain_description.pCallable, c_char_p(independent_update.sType), independent_update.fMagnitude, independent_update.pCallable, differential_update.iPercent, differential_update.pCallable, c_char_p(random01.sType), random01.iSeed, random01.pCallable, pErrorCode) else: raise InputError( "probability_distibution", "probability_distibution must be a callable object that takes a 2D numpy.ndarray and returns a 1D ndarray" ) if pErrorCode[0] != 0: raise InputError("Sample", "An error occurred during the call to Tasmanian.")