Source code for pymcmcstat.procedures.SumOfSquares

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Wed Jan 17 16:21:48 2018

@author: prmiles
"""

# Import required packages
import numpy as np
import sys


[docs]class SumOfSquares: ''' Sum-of-squares function evaluation. **Description:** Sum-of-squares (sos) class intended for used in MCMC simulator. Each instance will contain the sos function. If the user did not specify a sos-function, then the user supplied model function will be used in the default mcmc sos-function. Attributes: * :meth:`evaluate_sos_function` * :meth:`mcmc_sos_function` ''' def __init__(self, model, data, parameters): # check if sos function and model function are defined if model.sos_function is None: # isempty(ssfun) if model.model_function is None: # isempty(modelfun) sys.exit('No ssfun or modelfun specified!') sos_style = 4 else: sos_style = 1 self.sos_function = model.sos_function self.sos_style = sos_style self.model_function = model.model_function self.parind = parameters._parind self.value = parameters._initial_value self.local = parameters._local self.data = data self.nbatch = model.nbatch
[docs] def evaluate_sos_function(self, theta, custom=None): ''' Evaluate sum-of-squares function. Args: * **theta** (:class:`~numpy.ndarray`): Parameter values. Returns: * **ss** (:class:`~numpy.ndarray`): Sum-of-squares error(s) ''' # evaluate sum-of-squares function self.value[self.parind] = theta if self.sos_style == 1: try: ss = self.sos_function(self.value, self.data, custom=custom) except TypeError: ss = self.sos_function(self.value, self.data) elif self.sos_style == 4: ss = self.mcmc_sos_function(self.value, self.data, self.nbatch, self.model_function) else: ss = self.sos_function(self.value, self.data, self.local) # make sure sos is a numpy array if not isinstance(ss, np.ndarray): ss = np.array([ss]) return ss
[docs] @classmethod def mcmc_sos_function(cls, theta, data, nbatch, model_function): ''' Default sum-of-squares function. .. note:: This method requires specifying a model function instead of a sum of squares function. Not recommended for most applications. Basic formulation: .. math:: SS_{q,i} = \\sum [w_i(y^{data}_i-y^{model}_i)^2] where :math:`w_i` is the weight of a particular data set, and :math:`SS_{q,i}` is the sum-of-squares error for the `i`-th data set. Args: * **theta** (:class:`~numpy.ndarray`): Parameter values. Returns: * **ss** (:class:`~numpy.ndarray`): Sum-of-squares error(s) ''' # initialize ss = np.zeros(nbatch) for ibatch in range(nbatch): xdata = data.xdata[ibatch] ydata = data.ydata[ibatch] weight = data.weight[ibatch] # evaluate model ymodel = model_function(xdata, theta) # calculate sum-of-squares error ss[ibatch] += sum(weight*(ydata-ymodel)**2) return ss