示例#1
0
    def setState(self, state):
        '''
        Set the current value for the states and match it to the corresponding symbol

        Parameters
        ----------
        state: tuple
            tuple of two elements, (string, numeric)

        '''
        if state is not None:
            if isinstance(state, (list, tuple)):
                if isinstance(state[0], tuple):
                    stateOut = list()
                    for i in range(0, len(state)):
                        stateOut.append((self._extractStateSymbol(state[i][0]),
                                         state[i][1]))

                    self._state = stateOut
                else:
                    self._state = self._unrollState(state)
            elif isinstance(state, numpy.ndarray):
                self._state = self._unrollState(state)
            elif ode_utils.isNumeric(state):
                self._state = self._unrollState(state)
            else:
                raise InputError("Input state is of an unexpected type - " +
                                 type(state))
        else:
            raise InputError("Input state is of an unexpected type - " +
                             type(state))

        return self
示例#2
0
    def setState(self, state):
        '''
        Set the current value for the states and match it to the corresponding symbol

        Parameters
        ----------
        state: tuple
            tuple of two elements, (string, numeric)

        '''
        if state is not None:
            if isinstance(state, (list, tuple)):
                if isinstance(state[0], tuple):
                    stateOut = list()
                    for i in range(0, len(state)):
                        stateOut.append((self._extractStateSymbol(state[i][0]), state[i][1]))

                    self._state = stateOut
                else:
                    self._state = self._unrollState(state)
            elif isinstance(state, numpy.ndarray):
                self._state = self._unrollState(state)
            elif ode_utils.isNumeric(state):
                self._state = self._unrollState(state)
            else:
                raise InputError("Input state is of an unexpected type - "
                                 +type(state))
        else:
            raise InputError("Input state is of an unexpected type - "
                             +type(state))

        return self
示例#3
0
    def setStateValue(self, state):
        '''
        Set the current value for the states and match it to the corresponding symbol

        Parameters
        ----------
        state: array like
            either a vector of numeric value of a
            tuple of two elements, (string, numeric)

        '''
        if state is not None:
            if isinstance(state, (list, tuple)):
                if isinstance(state[0], tuple):
                    self._state = [self._extractStateSymbol(s[0], s[1]) for s in state]
                else:
                    self._state = self._unrollState(state)
            elif isinstance(state, numpy.ndarray):
                self._state = self._unrollState(state)
            elif ode_utils.isNumeric(state):
                self._state = self._unrollState(state)
            else:
                raise InputError("Input state is of an unexpected type - "
                                 +type(state))
        else:
            raise InputError("Input state is of an unexpected type - "
                             +type(state))

        return self
示例#4
0
    def _unrollState(self, state):
        '''
        Information unrolling from vector to sympy in state
        '''
        stateOut = list()
        if self._stateList == 1:
            if ode_utils.isNumeric(state):
                stateOut.append((self._stateList[0], state))
            else:
                raise InputError("Number of input state not as expected")
        else:
            if len(state) == len(self._stateList):
                for i in range(0, self._numState):
                    stateOut.append((self._stateList[i], state[i]))
            else:
                raise InputError("Number of input state not as expected")

        return stateOut
示例#5
0
    def _unrollState(self, state):
        '''
        Information unrolling from vector to sympy in state
        '''
        stateOut = list()
        if self._stateList == 1:
            if ode_utils.isNumeric(state):
                stateOut.append((self._stateList[0], state))
            else:
                raise InputError("Number of input state not as expected")
        else:
            if len(state) == len(self._stateList):
                for i in range(0, self._numState):
                    stateOut.append((self._stateList[i], state[i]))
            else:
                raise InputError("Number of input state not as expected")

        return stateOut
示例#6
0
    def simulateJump(self, t, iteration, full_output=False):
        '''
        Simulate the ode using stochastic simulation.  It switches
        between a first reaction method and a :math:`\tau`-leap
        algorithm internally.

        Parameters
        ----------
        t: array like
            the range of time points which we want to see the result of
            or the final time point
        iteration: int
            number of iterations you wish to simulate
        full_output: bool,optional
            if we want additional information, simT

        Returns
        -------
        simX: list
            of length iteration each with (len(t),len(state)) if t is a vector,
            else it outputs unequal shape that was record of all the jumps
        simT: list or :class:`numpy.ndarray`
            if t is a single value, it outputs unequal shape that was
            record of all the jumps.  if t is a vector, it outputs t so that
            it is a :class:`numpy.ndarray` instead

        '''

        assert len(self._odeList) == 0, "Currently only able to simulate when only transitions are present"
        assert numpy.all(numpy.mod(self._x0, 1) == 0), "Can only simulate a jump process with integer initial values"
        
        # this determines what type of output we want
        timePoint = False

        if ode_utils.isNumeric(t):#, (int, float, numpy.int64, numpy.float64)):
            finalT = t
        elif isinstance(t, (list, tuple)):
            t = numpy.array(t)
            if len(t) == 1:
                finalT = t
            else:
                finalT = t[-1:]
                timePoint = True
        elif isinstance(t, numpy.ndarray):
            finalT = t[-1:]
            timePoint = True
        else:
            raise InputError("Unknown data type for time")

        if self._transitionVectorCompile is None:
            self._compileTransitionVector()

        # we are going to try the parallel option
        try:
            # check the type of parameter we have as input
            dview, canParallel = self._setupParallel(finalT, iteration, self._paramValue)
            print "Success in creating parallel environment"
            if canParallel:
                #print "Parallel"
                dview.execute('YList = [ode._jump(t,full_output=True) for i in range(iteration)]')
                # unroll information
                simXList = list()
                simTList = list()
                for Y in dview['YList']:
                    for simOut in Y:
                        simXList.append(simOut[0])
                        simTList.append(simOut[1])
                #print "Finished"
            else:
                print "Failed somewhere"
                raise SimulationError("Cannot run this in parallel")

        except Exception as e:
            #print "Serial"
            simXList = list()
            simTList = list()
            for _i in range(iteration):
                # now we simulate the jumps
                simX, simT = self._jump(finalT, full_output=True)
                # add to list :)
                simXList.append(simX)
                simTList.append(simT)

        # now we want to fix our simulation, if they need fixing that is
        # print timePoint
        if timePoint:
            for _i in range(len(simXList)):
                # unroll, always the first element
                # it is easy to remember that we are accessing the first
                # element because pop is spelt similar to poop and we
                # all know that your execute first in first out when you
                # poop!
                simX = simXList.pop(0)
                simT = simTList.pop(0)

                x = self._extractObservationAtTime(simX, simT, t)
                simTList.append(t)
                simXList.append(x)
        # note that we have to remain in list form because the number of
        # simulation will be different if we are not dealing with
        # a specific set of time points

        if full_output:
            if timePoint:
                return simXList, t
            else:
                return simXList, simTList
        else:
            return simXList
示例#7
0
    def setParameters(self, parameters):
        '''
        Set the values for the parameters already defined.  Note that unless
        the parameters are entered via a dictionary or a two element list,tuple
        we assume that it is in the order of :meth:`.getParamList`

        Parameters
        ----------
        parameters: list or equivalent
            A list which contains two elements (string, numeric value) or
            just a single array like object

        '''

        # A stupid and complicated type checking procedure.  Someone please kill me
        # when you read this.
        if parameters is not None:
            # currently only accept 3 main types here, obviously apart from the
            # dict type below
            if isinstance(parameters, (list, tuple, numpy.ndarray)):
                # length checking, we are assuming here that we always set the full
                # set of parameters
                if len(parameters) == self._numParam:
                    if type(parameters) is numpy.ndarray:
                        if parameters.size == self._numParam:
                            parameters = parameters.ravel()
                        else:
                            raise InputError("The number of input parameters is "
                                             +str(parameters.size)+ " but "
                                             +str(self._numParam)+  " expected")

                    paramOut = dict()
                else:
                    raise InputError("The number of input parameters is "
                                     +str(len(parameters))+ " but "
                                     +str(self._numParam)+  " expected")

                # type checking, making sure that all the different type are accepted
                if isinstance(parameters[0], tuple):
                    if len(parameters) == self._numParam:
                        for i in range(0, len(parameters)):
                            indexTemp = self._extractParamSymbol(parameters[i][0])
                            valueTemp = parameters[i][1]
                            paramOut[indexTemp] = valueTemp
                # we are happy... I guess
                elif ode_utils.isNumeric(parameters[0]):
                    for i in range(0, len(parameters)):
                        paramOut[self._paramList[i]] = parameters[i]
                else:
                    raise InputError("Input type should either be a list of tuple with "
                                     +"elements (str,numeric) or a list of numeric value")
            elif isinstance(parameters, dict):
                # we assume that the key of the dictionary is a string and
                # the value can be a single value or a distribution
                if len(parameters) > self._numParam:
                    raise Exception("Too many input parameters")

                # holder
                # TODO: change this properly so that there are two different types of parameter
                # input.  One is when we initialize and another when we set new ones
                if self._parameters is None:
                    paramOut = dict()
                else:
                    paramOut = self._parameters

                # extra the key from the parameters dictionary
                for inParam in parameters:
                    value = parameters[inParam]
                    if ode_utils.isNumeric(value):
                        # get index
                        if isinstance(inParam, sympy.Symbol):
                            paramOut[self._extractParamSymbol(str(inParam))] = value
                        else:
                            paramOut[self._extractParamSymbol(inParam)] = value
                        # and replace only that specific one
                    elif isinstance(value, scipy.stats._distn_infrastructure.rv_frozen):
                        # we always assume that we have a frozen distribution
                        paramOut[self._extractParamSymbol(inParam)] = value.rvs(1)[0]
                        # output of the rv from a frozen distribution is a numpy.ndarray even when
                        # the number of sample is one
                        ## Now we are going make damn sure to record it down!
                        self._stochasticParam = parameters
                    elif isinstance(value, tuple):
                        if callable(value[0]):
                            # using a temporary variable to shorten the line.
                            if isinstance(value[1], dict):
                                paramTemp = value[0](1, **value[1])
                            else:
                                paramTemp = value[0](1, *value[1])

                            paramOut[self._extractParamSymbol(inParam)] = paramTemp
                            self._stochasticParam = parameters
                        else:
                            raise InputError("First element should be a callable when using multi "
                                             +"argument distribution definition.  "
                                             +"Type of input was " +str(type(value)))
                    else:
                        raise InputError("Not supported input type for dict() input yet. "
                                         +str(type(value)))
            elif self._numParam == 1:
                # a single parameter ode and you are not evaluating it analytically!
                # fair enough! no further comment your honour.
                paramOut = list()
                if isinstance(parameters, tuple):
                    paramOut[self._extractParamSymbol(parameters[0])] = parameters[1]
                elif isinstance(parameters, (int, float)):
                    paramOut[self.getParamList()[0]] = parameters
                else:
                    raise InputError("Input type should either be a tuple of (str,numeric) "
                                     +"or a single numeric value")
            else:
                raise InputError("Expecting a dict, list or a tuple input because there are a "
                                 +"total of " + str(self._numParam)+ " parameters")
        else:
            if self._numParam != 0:
                raise Warning("Did not set the values of the parameters.  Input was None.")
            else:
                paramOut= dict()

        self._parameters = paramOut

        # unroll the parameter values into the appropriate list
        # if self._paramValue is None or isinstance(self._paramValue, list):
        #     self._paramValue = dict()
        self._paramValue = [0] * len(self._paramList)

        for k, v in self._parameters.iteritems():
            index = self.getParamIndex(k)
            self._paramValue[index] = v

        return self
示例#8
0
    def setParameters(self, parameters):
        '''
        Set the values for the parameters already defined.  Note that unless
        the parameters are entered via a dictionary or a two element list,tuple
        we assume that it is in the order of :meth:`.getParamList`

        Parameters
        ----------
        parameters: list or equivalent
            A list which contains two elements (string, numeric value) or
            just a single array like object

        '''

        # A stupid and complicated type checking procedure.  Someone please kill me
        # when you read this.
        if parameters is not None:
            # currently only accept 3 main types here, obviously apart from the
            # dict type below
            if isinstance(parameters, (list, tuple, numpy.ndarray)):
                # length checking, we are assuming here that we always set the full
                # set of parameters
                if len(parameters) == self._numParam:
                    if type(parameters) is numpy.ndarray:
                        if parameters.size == self._numParam:
                            parameters = parameters.ravel()
                        else:
                            raise InputError(
                                "The number of input parameters is " +
                                str(parameters.size) + " but " +
                                str(self._numParam) + " expected")

                    paramOut = dict()
                else:
                    raise InputError("The number of input parameters is " +
                                     str(len(parameters)) + " but " +
                                     str(self._numParam) + " expected")

                # type checking, making sure that all the different type are accepted
                if isinstance(parameters[0], tuple):
                    if len(parameters) == self._numParam:
                        for i in range(0, len(parameters)):
                            indexTemp = self._extractParamSymbol(
                                parameters[i][0])
                            valueTemp = parameters[i][1]
                            paramOut[indexTemp] = valueTemp
                # we are happy... I guess
                elif ode_utils.isNumeric(parameters[0]):
                    for i in range(0, len(parameters)):
                        paramOut[self._paramList[i]] = parameters[i]
                else:
                    raise InputError(
                        "Input type should either be a list of tuple with " +
                        "elements (str,numeric) or a list of numeric value")
            elif isinstance(parameters, dict):
                # we assume that the key of the dictionary is a string and
                # the value can be a single value or a distribution
                if len(parameters) > self._numParam:
                    raise Exception("Too many input parameters")

                # holder
                # TODO: change this properly so that there are two different types of parameter
                # input.  One is when we initialize and another when we set new ones
                if self._parameters is None:
                    paramOut = dict()
                else:
                    paramOut = self._parameters

                # extra the key from the parameters dictionary
                for inParam in parameters:
                    value = parameters[inParam]
                    if ode_utils.isNumeric(value):
                        # get index
                        if isinstance(inParam, sympy.Symbol):
                            paramOut[self._extractParamSymbol(
                                str(inParam))] = value
                        else:
                            paramOut[self._extractParamSymbol(inParam)] = value
                        # and replace only that specific one
                    elif isinstance(
                            value,
                            scipy.stats._distn_infrastructure.rv_frozen):
                        # we always assume that we have a frozen distribution
                        paramOut[self._extractParamSymbol(
                            inParam)] = value.rvs(1)[0]
                        # output of the rv from a frozen distribution is a numpy.ndarray even when
                        # the number of sample is one
                        ## Now we are going make damn sure to record it down!
                        self._stochasticParam = parameters
                    elif isinstance(value, tuple):
                        if callable(value[0]):
                            # using a temporary variable to shorten the line.
                            if isinstance(value[1], dict):
                                paramTemp = value[0](1, **value[1])
                            else:
                                paramTemp = value[0](1, *value[1])

                            paramOut[self._extractParamSymbol(
                                inParam)] = paramTemp
                            self._stochasticParam = parameters
                        else:
                            raise InputError(
                                "First element should be a callable when using multi "
                                + "argument distribution definition.  " +
                                "Type of input was " + str(type(value)))
                    else:
                        raise InputError(
                            "Not supported input type for dict() input yet. " +
                            str(type(value)))
            elif self._numParam == 1:
                # a single parameter ode and you are not evaluating it analytically!
                # fair enough! no further comment your honour.
                paramOut = list()
                if isinstance(parameters, tuple):
                    paramOut[self._extractParamSymbol(
                        parameters[0])] = parameters[1]
                elif isinstance(parameters, (int, float)):
                    paramOut[self.getParamList()[0]] = parameters
                else:
                    raise InputError(
                        "Input type should either be a tuple of (str,numeric) "
                        + "or a single numeric value")
            else:
                raise InputError(
                    "Expecting a dict, list or a tuple input because there are a "
                    + "total of " + str(self._numParam) + " parameters")
        else:
            if self._numParam != 0:
                raise Warning(
                    "Did not set the values of the parameters.  Input was None."
                )
            else:
                paramOut = dict()

        self._parameters = paramOut

        # unroll the parameter values into the appropriate list
        # if self._paramValue is None or isinstance(self._paramValue, list):
        #     self._paramValue = dict()
        self._paramValue = [0] * len(self._paramList)

        for k, v in self._parameters.iteritems():
            index = self.getParamIndex(k)
            self._paramValue[index] = v

        return self
示例#9
0
    def simulateJump(self, t, iteration, full_output=False):
        '''
        Simulate the ode using stochastic simulation.  It switches
        between a first reaction method and a :math:`\tau`-leap
        algorithm internally.

        Parameters
        ----------
        t: array like
            the range of time points which we want to see the result of
            or the final time point
        iteration: int
            number of iterations you wish to simulate
        full_output: bool,optional
            if we want additional information, simT

        Returns
        -------
        simX: list
            of length iteration each with (len(t),len(state)) if t is a vector,
            else it outputs unequal shape that was record of all the jumps
        simT: list or :class:`numpy.ndarray`
            if t is a single value, it outputs unequal shape that was
            record of all the jumps.  if t is a vector, it outputs t so that
            it is a :class:`numpy.ndarray` instead

        '''

        assert len(
            self._odeList
        ) == 0, "Currently only able to simulate when only transitions are present"
        assert numpy.all(
            numpy.mod(self._x0, 1) ==
            0), "Can only simulate a jump process with integer initial values"

        # this determines what type of output we want
        timePoint = False

        if ode_utils.isNumeric(
                t):  #, (int, float, numpy.int64, numpy.float64)):
            finalT = t
        elif isinstance(t, (list, tuple)):
            t = numpy.array(t)
            if len(t) == 1:
                finalT = t
            else:
                finalT = t[-1:]
                timePoint = True
        elif isinstance(t, numpy.ndarray):
            finalT = t[-1:]
            timePoint = True
        else:
            raise InputError("Unknown data type for time")

        if self._transitionVectorCompile is None:
            self._compileTransitionVector()

        # we are going to try the parallel option
        try:
            # check the type of parameter we have as input
            dview, canParallel = self._setupParallel(finalT, iteration,
                                                     self._paramValue)
            if canParallel:
                #print "Parallel"
                dview.execute(
                    'YList = [odeS._jump(t,full_output=True) for i in range(iteration)]'
                )
                # unroll information
                simXList = list()
                simTList = list()
                for Y in dview['YList']:
                    for simOut in Y:
                        simXList.append(simOut[0])
                        simTList.append(simOut[1])
                #print "Finished"
            else:
                raise SimulationError("Cannot run this in parallel")

        except Exception as e:
            #print "Serial"
            simXList = list()
            simTList = list()
            for i in range(iteration):
                # now we simulate the jumps
                simX, simT = self._jump(finalT, full_output=True)
                # add to list :)
                simXList.append(simX)
                simTList.append(simT)

        # now we want to fix our simulation, if they need fixing that is
        # print timePoint
        if timePoint:
            for i in range(len(simXList)):
                # unroll, always the first element
                # it is easy to remember that we are accessing the first
                # element because pop is spelt similar to poop and we
                # all know that your execute first in first out when you
                # poop!
                simX = simXList.pop(0)
                simT = simTList.pop(0)

                x = self._extractObservationAtTime(simX, simT, t)
                simTList.append(t)
                simXList.append(x)
        # note that we have to remain in list form because the number of
        # simulation will be different if we are not dealing with
        # a specific set of time points

        if full_output:
            if timePoint:
                return simXList, t
            else:
                return simXList, simTList
        else:
            return simXList