コード例 #1
0
    def test_sum_of_squares_error_multi(self):
        """ Tests :class:`pints.MeanSquaredError` with multiple outputs. """

        # Set up problem
        model = pints.toy.ConstantModel(2)
        times = [1, 2, 3]
        values = [[1, 4], [1, 4], [1, 4]]
        p = pints.MultiOutputProblem(model, times, values)

        # Test
        e = pints.SumOfSquaresError(p)
        self.assertEqual(e.n_parameters(), 2)
        float(e([1, 2]))
        self.assertEqual(e([1, 2]), 0)  # 0
        self.assertEqual(e([2, 2]), 3)  # 3*(1^2+0^2) = 3
        self.assertEqual(e([2, 3]), 15)  # 3*(1^2+2^2) = 15
        self.assertEqual(e([3, 4]), 60)  # 3*(2^2+4^2) = 60

        # Derivatives
        values = np.array([[1, 4], [2, 7], [3, 10]])
        p = pints.MultiOutputProblem(model, times, values)
        e = pints.SumOfSquaresError(p)
        x = [1, 2]

        # Model outputs are 3 times [1,4]
        # Model derivatives are 3 times [[1, 0], [0, 1]]
        y, dy = p.evaluateS1(x)
        self.assertTrue(np.all(y == p.evaluate(x)))
        self.assertTrue(np.all(y[0, :] == [1, 4]))
        self.assertTrue(np.all(y[1, :] == [1, 4]))
        self.assertTrue(np.all(y[2, :] == [1, 4]))
        self.assertTrue(np.all(dy[0, :] == [[1, 0], [0, 1]]))
        self.assertTrue(np.all(dy[1, :] == [[1, 0], [0, 1]]))
        self.assertTrue(np.all(dy[2, :] == [[1, 0], [0, 1]]))

        # Check residuals
        rx = y - np.array(values)
        self.assertTrue(np.all(rx == np.array([[-0, -0], [-1, -3], [-2, -6]])))
        self.assertAlmostEqual(e(x), np.sum(rx**2))

        # Now with derivatives
        ex, dex = e.evaluateS1(x)

        # Check error
        self.assertTrue(np.all(ex == e(x)))

        # Check derivatives. Shape is (parameters, )
        self.assertEqual(dex.shape, (2, ))

        # Residuals are: [[0, 0], [-1, -3], [-2, -6]]
        # Derivatives are: [[1, 0], [0, 1]]
        # dex1 is: 2 * (0 - 1 - 2) * 1 = 2 * -3 * 1 = -6
        # dex2 is: 2 * (0 - 3 - 6) * 2 = 2 * -9 * 1 = -18
        self.assertEqual(dex[0], -6)
        self.assertEqual(dex[1], -18)
コード例 #2
0
    def optimise(self, data, sigma_fac=0.001, method="minimisation"):
        cmaes_problem = pints.MultiOutputProblem(self, self.frequency_range,
                                                 data)
        if method == "likelihood":
            score = pints.GaussianLogLikelihood(cmaes_problem)
            sigma = sigma_fac * np.sum(data) / 2 * len(data)
            lower_bound = [self.param_bounds[x][0]
                           for x in self.params] + [0.1 * sigma] * 2
            upper_bound = [self.param_bounds[x][1]
                           for x in self.params] + [10 * sigma] * 2
            CMAES_boundaries = pints.RectangularBoundaries(
                lower_bound, upper_bound)
            random_init = abs(np.random.rand(self.n_parameters()))
            x0 = self.change_norm_group(random_init, "un_norm",
                                        "list") + [sigma] * 2
            cmaes_fitting = pints.OptimisationController(
                score,
                x0,
                sigma0=None,
                boundaries=CMAES_boundaries,
                method=pints.CMAES)
        elif method == "minimisation":
            score = pints.SumOfSquaresError(cmaes_problem)
            lower_bound = [self.param_bounds[x][0] for x in self.params]
            upper_bound = [self.param_bounds[x][1] for x in self.params]
            CMAES_boundaries = pints.RectangularBoundaries(
                lower_bound, upper_bound)
            random_init = abs(np.random.rand(self.n_parameters()))
            x0 = self.change_norm_group(random_init, "un_norm", "list")
            cmaes_fitting = pints.OptimisationController(
                score,
                x0,
                sigma0=None,
                boundaries=CMAES_boundaries,
                method=pints.CMAES)
        cmaes_fitting.set_max_unchanged_iterations(iterations=200,
                                                   threshold=1e-7)
        #cmaes_fitting.set_log_to_screen(False)
        cmaes_fitting.set_parallel(True)

        found_parameters, found_value = cmaes_fitting.run()

        if method == "likelihood":
            sim_params = found_parameters[:-2]
            sim_data = self.simulate(sim_params, self.frequency_range)
        else:
            found_value = -found_value
            sim_params = found_parameters
            sim_data = self.simulate(sim_params, self.frequency_range)
            """

            log_score = pints.GaussianLogLikelihood(cmaes_problem)
            stds=self.get_std(data, sim_data)
            sigma=sigma_fac*np.sum(data)/2*len(data)
            score_params=list(found_parameters)+[sigma]*2
            found_value=log_score(score_params)
            print(stds, found_value, "stds")"""

        #DOITDIMENSIONALLY#NORMALISE DEFAULT TO BOUND
        return found_parameters, found_value, cmaes_fitting._optimiser._es.sm.C, sim_data
コード例 #3
0
    def test_stopping_on_ill_conditioned_covariance_matrix(self):
        # Tests that ill conditioned covariance matrices are detected.
        from scipy.integrate import odeint
        #TODO: A quicker test-case for this would be great!

        def OnePopControlODE(y, t, p):
            a, b, c = p
            dydt = np.zeros(y.shape)
            k = (a - b) / c * (y[0] + y[1])
            dydt[0] = a * y[0] - b * y[0] - k * y[0]
            dydt[1] = k * y[0] - b * y[1]
            return dydt

        class Model(pints.ForwardModel):

            def simulate(self, parameters, times):
                y0 = [2000000, 0]
                solution = odeint(
                    OnePopControlODE, y0, times, args=(parameters,))
                return np.sum(np.array(solution), axis=1)

            def n_parameters(self):
                return 3

        model = Model()
        times = [0, 0.5, 2, 4, 8, 24]
        values = [2e6, 3.9e6, 3.1e7, 3.7e8, 1.6e9, 1.6e9]
        problem = pints.SingleOutputProblem(model, times, values)
        score = pints.SumOfSquaresError(problem)
        x = [3.42, -0.21, 5e6]
        opt = pints.OptimisationController(score, x, method=method)
        with StreamCapture() as c:
            opt.run()
        self.assertTrue('Ill-conditioned covariance matrix' in c.text())
コード例 #4
0
ファイル: test_error_measures.py プロジェクト: xl0418/pints
    def test_evaluateS1_two_dim_array_multi_weighted(self):
        # Create an object with links to the model and time series
        problem = pints.MultiOutputProblem(self.model_multi, self.times,
                                           self.data_multi)

        # Create error measure with weighted inputs
        weights = [1, 2]
        error = pints.SumOfSquaresError(problem, weights=weights)

        # Evaluate likelihood for test parameters
        test_parameters = [3, 4]
        score, deriv = error.evaluateS1(test_parameters)

        # Check that returned error is correct
        self.assertEqual(score, error(test_parameters))

        # Check that partial derivatives are returned for each parameter
        self.assertEqual(deriv.shape, (2, ))

        # Check that partials are correct
        # Expectation = [weight [0] * 2 * sum(input[0] - 1),
        # weight[1] * 4 * sum(2 * input[1] - 4)]
        self.assertEqual(deriv[0],
                         weights[0] * 2 * 3 * (test_parameters[0] - 1))
        self.assertEqual(deriv[1],
                         weights[1] * 4 * 3 * (2 * test_parameters[1] - 4))
コード例 #5
0
    def _problem(self):
        import numpy as np
        import pints
        import pints.toy

        # Load a forward model
        model = pints.toy.LogisticModel()

        # Create some toy data
        xtrue = [0.015, 500]
        times = np.linspace(0, 1000, 1000)
        values = model.simulate(xtrue, times)

        # Add noise
        values += np.random.normal(0, 10, values.shape)

        # Create problem
        problem = pints.SingleOutputProblem(model, times, values)
        score = pints.SumOfSquaresError(problem)

        # Select some boundaries
        boundaries = pints.RectangularBoundaries([0, 400], [0.03, 600])

        # Select a random starting point
        x0 = boundaries.sample(1)[0]

        # Select an initial sigma
        sigma0 = (1 / 6) * boundaries.range()

        return score, xtrue, x0, sigma0, boundaries
コード例 #6
0
    def test_sum_of_squares_error_single(self):
        """ Tests :class:`pints.MeanSquaredError` with a single output. """

        # Set up problem
        model = pints.toy.ConstantModel(1)
        times = [1, 2, 3]
        values = [1, 1, 1]
        p = pints.SingleOutputProblem(model, times, values)

        # Test
        e = pints.SumOfSquaresError(p)
        self.assertEqual(e.n_parameters(), 1)
        float(e([1]))
        self.assertEqual(e([1]), 0)
        self.assertEqual(e([2]), 3)
        self.assertEqual(e([0]), 3)
        self.assertEqual(e([3]), 12)

        # Derivatives
        for x in [1, 2, 3, 4]:
            ex, dex = e.evaluateS1([x])
            r = x - 1
            self.assertEqual(ex, e([x]))
            self.assertEqual(dex.shape, (1, ))
            self.assertEqual(dex[0], 2 * 3 * r)
コード例 #7
0
    def setUpClass(cls):
        """ Prepare problem for tests. """
        # Load a forward model
        model = pints.toy.LogisticModel()

        # Create some toy data
        real_parameters = [0.015, 500]
        times = np.linspace(0, 1000, 1000)
        org_values = model.simulate(real_parameters, times)

        # Add noise
        noise = 10
        values = org_values + np.random.normal(0, noise, org_values.shape)
        real_parameters = np.array(real_parameters + [noise])

        # Create an object with links to the model and time series
        problem = pints.SingleOutputProblem(model, times, values)

        # Create an error measure
        cls.score = pints.SumOfSquaresError(problem)
        cls.boundaries = pints.RectangularBoundaries([0, 400], [0.05, 600])

        # Create a log-likelihood function (adds an extra parameter!)
        log_likelihood = pints.GaussianLogLikelihood(problem)

        # Create a uniform prior over both the parameters and the new noise
        cls.log_prior = pints.UniformLogPrior([0.01, 400, noise * 0.1],
                                              [0.02, 600, noise * 100])

        # Create a posterior log-likelihood (log(likelihood * prior))
        cls.log_posterior = pints.LogPosterior(log_likelihood, cls.log_prior)
コード例 #8
0
    def _problem(self):
        import numpy as np
        import pints
        import pints.toy

        # Load a forward model
        model = pints.toy.ActionPotentialModel()

        # Create some toy data
        xtrue = model.suggested_parameters()
        times = model.suggested_times()
        values = model.simulate(xtrue, times)

        # Add noise
        values[:, 0] += np.random.normal(0, 1, values[:, 0].shape)
        values[:, 1] += np.random.normal(0, 5e-7, values[:, 1].shape)

        # Create problem and a weighted score function
        problem = pints.MultiOutputProblem(model, times, values)
        weights = [1 / 70, 1 / 0.000006]
        score = pints.SumOfSquaresError(problem, weights=weights)

        # Select some boundaries
        lower = xtrue - 2
        upper = xtrue + 2
        boundaries = pints.RectangularBoundaries(lower, upper)

        # Select a random starting point
        x0 = boundaries.sample(1)[0]

        # Select an initial sigma
        sigma0 = (1 / 6) * boundaries.range()

        return score, xtrue, x0, sigma0, boundaries
コード例 #9
0
    def __init__(self, name):
        super(TestCMAES, self).__init__(name)

        # Create toy model
        self.model = toy.LogisticModel()
        self.real_parameters = [0.015, 500]
        self.times = np.linspace(0, 1000, 1000)
        self.values = self.model.simulate(self.real_parameters, self.times)

        # Create an object with links to the model and time series
        self.problem = pints.SingleSeriesProblem(self.model, self.times,
                                                 self.values)

        # Select a score function
        self.score = pints.SumOfSquaresError(self.problem)

        # Select some boundaries
        self.boundaries = pints.Boundaries([0, 400], [0.03, 600])

        # Set an initial position
        self.x0 = 0.014, 499

        # Set a guess for the standard deviation around the initial position
        # (in both directions)
        self.sigma0 = 0.01

        # Minimum score function value to obtain
        self.cutoff = 1e-9

        # Maximum tries before it counts as failed
        self.max_tries = 3
コード例 #10
0
    def _problem(self):
        import numpy as np
        import pints
        import pints.toy

        # Create a model
        model = pints.toy.FitzhughNagumoModel()

        # Run a simulation
        xtrue = [0.1, 0.5, 3]
        times = np.linspace(0, 20, 200)
        values = model.simulate(xtrue, times)

        # Add some noise
        sigma = 0.5
        noisy = values + np.random.normal(0, sigma, values.shape)

        # Create problem
        problem = pints.MultiOutputProblem(model, times, noisy)
        score = pints.SumOfSquaresError(problem)

        # Select boundaries
        boundaries = pints.RectangularBoundaries([0, 0, 0], [10, 10, 10])

        # Select a random starting point
        x0 = boundaries.sample(1)[0]

        # Select an initial sigma
        sigma0 = (1 / 6) * boundaries.range()

        return score, xtrue, x0, sigma0, boundaries
コード例 #11
0
def main():
    #constants
    timeRangesToUse = [[1, 2499], [2549, 2999], [3049, 4999], [5049, 14999],
                       [15049, 19999], [20049, 29999], [30049, 64999],
                       [65049, 69999], [70049, -1]]
    true_parameters = [
        2.26E-04, 0.0699, 3.45E-05, 0.05462, 0.0873, 8.92E-03, 5.150E-3,
        0.03158, 0.1524
    ]

    model = ChannelModelPintsWrapper()
    data = pd.read_csv("data/averaged-data.txt", delim_whitespace=True)
    dat = extract_time_ranges(data.values, timeRangesToUse)
    times = dat[:, 0]
    values = dat[:, 1]

    current = model.simulate(true_parameters, times)
    plt.plot(times, values)
    plt.plot(times, current)
    plt.show()
    problem = pints.SingleOutputProblem(model, times, values)
    error = pints.SumOfSquaresError(problem)
    boundaries = MarkovModelBoundaries()
    x0 = np.array([0.1] * 9)
    found_parameters, found_value = pints.optimise(error,
                                                   true_parameters,
                                                   boundaries=boundaries)
    print(found_parameters, found_value)
コード例 #12
0
ファイル: inference.py プロジェクト: SABS-R3-projects/PKPD
    def __init__(self, models: List[m.MultiOutputModel], times: List[np.ndarray], values: List[np.ndarray]):
        """Initialises a multi-output inference problem with default objective function pints.SumOfSquaresError and
        default optimiser pints.CMAES. Standard deviation in initial starting point of optimisation as well as
        restricted domain of support for inferred parameters is disabled by default.

        Arguments:
            models {List[m.MultiOutputModel]} -- Models, which parameters are to be inferred.
            times {List[np.ndarray]} -- Times of data points for the different models.
            values {List[np.ndarray]} -- State values of data points for the different models.

        Return:
            None
        """
        # initialise problem container
        self.problem_container = []
        for model_id, model in enumerate(models):
            self.problem_container.append(pints.MultiOutputProblem(model, times[model_id], values[model_id]))

        # initialise error function container
        self.error_function_container = []
        for problem in self.problem_container:
            self.error_function_container.append(pints.SumOfSquaresError(problem))

        # initialise optimiser
        self.optimiser = pints.CMAES

        # initialise fluctuations around starting point of optimisation
        self.initial_parameter_uncertainty = None

        # initialise parameter constraints
        self.parameter_boundaries = None

        # initialise outputs
        self.estimated_parameters = None
        self.objective_score = None
コード例 #13
0
    def optimise(self, x, parallel=False):
        """
        Runs the optimisation, this method:
            (1) generates simulated data and adds noise
            (2) sets up the optimiser with the method given, trying to
                optimise the function f(x) = sum of squared error
            (3) runs the optimisation
            (4) returns:
                - the found parameters x,
                - the ratio of f(x) / f(x_0), where x_0 are the real parameters
                - time total time taken divided by the time taken to evaluate a
                  single evaluation of f(x)
        """
        the_model = self.model()
        print('model = ', the_model)
        values = the_model.simulate(self.real_parameters, self.times)
        value_range = np.max(values) - np.min(values)
        values += np.random.normal(0, self.noise * value_range, values.shape)
        problem = pints.MultiOutputProblem(the_model, self.times, values)
        score = pints.SumOfSquaresError(problem)
        middle = [0.5 * (u + l) for l, u in zip(self.lower, self.upper)]
        sigma = [(1.0/6.0)*(u - l) for l, u in zip(self.lower, self.upper)]
        print('sigma = ', sigma)
        boundaries = pints.RectangularBoundaries(self.lower, self.upper)

        optimisation = pints.Optimisation(
            score,
            middle,
            sigma0=sigma,
            boundaries=boundaries,
            method=self.method
        )
        optimisation.optimiser().set_hyper_parameters(x)
        if parallel:
            optimisation.set_parallel(int(os.environ['OMP_NUM_THREADS']))
        else:
            optimisation.set_parallel(False)


        start = timer()
        found_parameters, found_value = optimisation.run()
        end = timer()
        N = 10
        start_score = timer()
        for i in range(N):
            minimum_value = score(self.real_parameters)
        end_score = timer()
        score_duration = (end_score - start_score) / N

        return found_parameters,  \
            found_value / minimum_value, \
            (end - start) / score_duration
コード例 #14
0
    def setUpClass(cls):
        # Define objective function
        model = pints.toy.ConstantModel(1)
        times = np.linspace(1, 10)
        cls.true_params = [2.5]
        values = model.simulate(cls.true_params, times)
        problem = pints.SingleOutputProblem(model, times, values)
        cls.error = pints.SumOfSquaresError(problem)

        # Define initial parameters
        cls.params = [[3]]

        # Define boundaries
        cls.boundaries = pints.RectangularBoundaries(1, 5)
コード例 #15
0
ファイル: test_error_measures.py プロジェクト: xl0418/pints
    def test_call_two_dim_array_multi(self):
        # Create an object with links to the model and time series
        problem = pints.MultiOutputProblem(self.model_multi, self.times,
                                           self.data_multi)

        # Create error measure
        error = pints.SumOfSquaresError(problem)

        # Evaluate likelihood for test parameters
        test_parameters = [3, 4]
        score = error(test_parameters)

        # Check that error returns expected value
        # Exp = sum((input[0] - 1) ** 2) + sum((2 * input[1] - 4) ** 2)
        self.assertEqual(score, 60)
コード例 #16
0
def main():
    #constants
    timeRangesToUse = [[1,2499], [2549,2999], [3049,4999], [5049,14999], [15049,19999], [20049,29999], [30049,64999], [65049,69999], [70049,-1]]
    starting_parameters = [3.87068845e-04, 5.88028759e-02, 6.46971727e-05, 4.87408447e-02, 8.03073893e-02, 7.36295506e-03, 5.32908518e-03, 3.32254316e-02, 6.56614672e-02]

    model = ChannelModelPintsWrapper()
    data  = pd.read_csv("data/averaged-data.txt", delim_whitespace=True)
    dat = extract_time_ranges(data.values, timeRangesToUse)
    times=dat[:,0]
    values=dat[:,1]
    current = model.simulate(starting_parameters, times)
    problem = pints.SingleOutputProblem(model, times, values)
    error = pints.SumOfSquaresError(problem)
    boundaries  = MarkovModelBoundaries()
    x0 = np.array([0.1]*9)
    found_parameters, found_value = pints.optimise(error, starting_parameters, boundaries=boundaries)
    print(found_parameters, found_value)
コード例 #17
0
ファイル: test_error_measures.py プロジェクト: xl0418/pints
    def test_call_two_dim_array_single(self):
        # Convert data to array of shape (n_times, 1)
        values = np.reshape(self.data_single, (self.n_times, 1))

        # Create an object with links to the model and time series
        problem = pints.SingleOutputProblem(self.model_single, self.times,
                                            values)

        # Create error measure
        error = pints.SumOfSquaresError(problem)

        # Evaluate likelihood for test parameters
        test_parameters = [3]
        score = error(test_parameters)

        # Check that error returns expected value
        # Expected = sum((input - 1) ** 2)
        self.assertEqual(score, 12)
コード例 #18
0
    def optimise(self):
        """
        Parameter inference using SNES (Seperable Natural Evolution Strategy).

        Returns:
        ---------------
            found_parameters:
                - found optimal parameters
        """
        #Define a score function, i.e the sum of squares error
        score = pints.SumOfSquaresError(self.problem)

        #Define the boundaries for F and k according to literature
        boundaries = pints.RectangularBoundaries([0.01, 0.01], [1.0, 1.0])

        #Starting point within the boundaries
        x0 = [0.05, 0.05]

        #Run SNES
        found_parameters, found_value = pints.optimise(score, x0, boundaries=boundaries, method=pints.SNES)
        return found_parameters
コード例 #19
0
ファイル: test_error_measures.py プロジェクト: xl0418/pints
    def test_evaluateS1_two_dim_array_single(self):
        # Convert data to array of shape (n_times, 1)
        values = np.reshape(self.data_single, (self.n_times, 1))

        # Create an object with links to the model and time series
        problem = pints.SingleOutputProblem(self.model_single, self.times,
                                            values)

        # Create error measure
        error = pints.SumOfSquaresError(problem)

        # Evaluate likelihood for test parameters
        test_parameters = [3]
        score, deriv = error.evaluateS1(test_parameters)

        # Check that returned error is correct
        self.assertEqual(score, error(test_parameters))

        # Check that partial derivatives are returned for each parameter
        self.assertEqual(deriv.shape, (1, ))

        # Check that partials are correct
        # Expected = 2 * sum(input - 1)
        self.assertEqual(deriv, 2 * 3 * (test_parameters[0] - 1))
コード例 #20
0
plt.ylabel('Vm (mV)')
plt.plot(times, noisy_values[:, 0])
plt.plot(times, values[:, 0])
plt.subplot(2, 1, 2)
plt.xlabel('Time (ms)')
plt.ylabel('[Ca]i (mol/L)')
plt.plot(times, noisy_values[:, 1])
plt.plot(times, values[:, 1])
#plt.show()

# Create an object with links to the model and time series
problem = pints.MultiOutputProblem(model, times, noisy_values)

# Create a score function
weights = [1 / 70, 1 / 0.000006]
score = pints.SumOfSquaresError(problem, weights=weights)

# Select some boundaries
lower = x_true / 2
upper = x_true * 2
boundaries = pints.RectangularBoundaries(lower, upper)

# Perform an optimization
x0 = x_true * 1.2
optimiser = pints.OptimisationController(score,
                                         x0,
                                         boundaries=boundaries,
                                         method=pints.CMAES)

print('Running...')
x_found, score_found = optimiser.run()
コード例 #21
0
    def test_best_vs_guessed(self):
        # Tests tracking and logging of best and guessed values

        # Set up a problem
        model = pints.toy.LogisticModel()
        real = model.suggested_parameters()
        times = model.suggested_times()
        values = model.simulate(real, times)
        values += np.random.normal(0, 10, values.shape)
        problem = pints.SingleOutputProblem(model, times, values)
        f = pints.SumOfSquaresError(problem)
        b = pints.RectangularBoundaries([0, 200], [1, 1000])
        x = [0, 700]

        # Check getting and setting tracking method
        np.random.seed(123)
        opt = pints.OptimisationController(
            f, x, boundaries=b, method=pints.SNES)
        self.assertFalse(opt.f_guessed_tracking())
        opt.set_f_guessed_tracking(True)
        self.assertTrue(opt.f_guessed_tracking())
        opt.set_f_guessed_tracking(False)
        self.assertFalse(opt.f_guessed_tracking())

        # Check f_best and f_guessed with callback
        fb, fg = [], []

        def cb(i, opt):
            fb.append(opt.f_best())
            fg.append(opt.f_guessed())

        # Run and check the logged values
        opt.set_callback(cb)
        opt.set_log_to_screen(False)
        opt.set_log_interval(1)
        with TemporaryDirectory() as d:
            p = d.path('out.csv')
            opt.set_log_to_file(p, csv=True)
            x1, f1 = opt.run()
            csv = np.genfromtxt(p, delimiter=',', skip_header=1)[:-1]
            lb = csv[:, 2]
            lg = csv[:, 3]
            del(csv)

        fb, fg = np.array(fb), np.array(fg)

        if debug:
            import matplotlib.pyplot as plt
            plt.figure()
            plt.semilogy()
            plt.plot(fb, label='best, callback')
            plt.plot(fg, label='guessed, callback')
            plt.plot(lb, '--', label='best, logged')
            plt.plot(lg, '--', label='guessed, logged')
            plt.legend()
            plt.show()

        self.assertTrue(np.all(fb == lb))
        self.assertTrue(np.all(fg == lg))
        self.assertFalse(np.all(lb == lg))

        # Run again, but checking on f_guessed
        np.random.seed(123)
        opt2 = pints.OptimisationController(
            f, x, boundaries=b, method=pints.SNES)
        opt2.set_log_to_screen(False)
        opt2.set_f_guessed_tracking(True)
        x2, f2 = opt2.run()
        self.assertNotEqual(opt.iterations(), opt2.iterations())
        self.assertAlmostEqual(f1, f2)
コード例 #22
0
ファイル: init_sv.py プロジェクト: HOLL95/LPMO
        abs_vals=[0.12267918433476588, 0.10000001217777187, 110.7217695311136, 6.436119838423983e-09, 9.015056846897231, 2.300030530938936, 5.0949078241522905, 0.599999988589617]
        abs_vals=[0.1942552896092487, 1.6396496330592818, 53.46929098380687, 2.745723906710015e-09, 9.015061323815008, 4.022601263585928, 3.2663583722003433, 0.4804444355077191]

        cmaes_abs=LPMO.test_vals(abs_vals, "timeseries")
        plot_harmonics(LPMO.t_nondim(time_results), h_class, abs_time_series=LPMO.i_nondim(cmaes_abs), data_time_series=LPMO.i_nondim(current_results), xaxis=LPMO.e_nondim(voltage_results))
        LPMO.def_optim_list(["E_0","k0_shape", "k0_scale","Ru","gamma","omega","cap_phase","phase", "alpha"])
        true_data=current_results#LPMO.add_noise(cmaes_time, 0.0*max(cmaes_time))
        exp_harms=h_class.generate_harmonics(LPMO.t_nondim(time_results), LPMO.i_nondim(true_data))
        fourier_arg=LPMO.top_hat_filter(true_data)
        plot_harmonics(LPMO.t_nondim(time_results), h_class, noisy_time_series=true_data, base_time_series=cmaes_time, xaxis=voltage_results)
        if LPMO.simulation_options["likelihood"]=="timeseries":
            cmaes_problem=pints.SingleOutputProblem(LPMO, time_results, true_data)
        elif LPMO.simulation_options["likelihood"]=="fourier":
            dummy_times=np.linspace(0, 1, len(fourier_arg))
            cmaes_problem=pints.SingleOutputProblem(LPMO, dummy_times, fourier_arg)
        score = pints.SumOfSquaresError(cmaes_problem)
        CMAES_boundaries=pints.RectangularBoundaries(list(np.zeros(len(LPMO.optim_list))), list(np.ones(len(LPMO.optim_list))))
        num_runs=5
        for i in range(0, num_runs):
            x0=abs(np.random.rand(LPMO.n_parameters()))
            starting_point=[orig_cmaes_results[ts_results_optim_list.index((param))] if param in ts_results_optim_list else LPMO.dim_dict[param] for param in LPMO.optim_list]
            print(starting_point)
            #x0=LPMO.change_norm_group(starting_point, "norm")
            print(len(x0), cmaes_problem.n_parameters(), CMAES_boundaries.n_parameters(), score.n_parameters())
            cmaes_fitting=pints.OptimisationController(score, x0, sigma0=None, boundaries=CMAES_boundaries, method=pints.CMAES)
            cmaes_fitting.set_max_unchanged_iterations(iterations=200, threshold=1e-7)
            cmaes_fitting.set_parallel(not LPMO.simulation_options["test"])#
            found_parameters, found_value=cmaes_fitting.run()
            print(found_parameters)
            cmaes_results=LPMO.change_norm_group(found_parameters[:], "un_norm")
            print(list(cmaes_results))
コード例 #23
0
ファイル: test_error_measures.py プロジェクト: xl0418/pints
    def test_sum_of_errors(self):
        # Tests :class:`pints.SumOfErrors`.

        e1 = pints.SumOfSquaresError(MiniProblem())
        e2 = pints.MeanSquaredError(MiniProblem())
        e3 = pints.RootMeanSquaredError(BigMiniProblem())
        e4 = pints.SumOfSquaresError(BadMiniProblem())

        # Basic use
        e = pints.SumOfErrors([e1, e2])
        x = [0, 0, 0]
        self.assertEqual(e.n_parameters(), 3)
        self.assertEqual(e(x), e1(x) + e2(x))
        e = pints.SumOfErrors([e1, e2], [3.1, 4.5])
        x = [0, 0, 0]
        self.assertEqual(e.n_parameters(), 3)
        self.assertEqual(e(x), 3.1 * e1(x) + 4.5 * e2(x))
        e = pints.SumOfErrors([e1, e1, e1, e1, e1, e1], [1, 2, 3, 4, 5, 6])
        self.assertEqual(e.n_parameters(), 3)
        self.assertEqual(e(x), e1(x) * 21)
        self.assertNotEqual(e(x), 0)

        with np.errstate(all='ignore'):
            e = pints.SumOfErrors([e4, e1, e1, e1, e1, e1],
                                  [10, 1, 1, 1, 1, 1])
            self.assertEqual(e.n_parameters(), 3)
            self.assertEqual(e(x), float('inf'))
            e = pints.SumOfErrors([e4, e1, e1, e1, e1, e1], [0, 2, 0, 2, 0, 2])
            self.assertEqual(e.n_parameters(), 3)
            self.assertTrue(e(x), 6 * e1(x))
            e5 = pints.SumOfSquaresError(BadMiniProblem(float('-inf')))
            e = pints.SumOfErrors([e1, e5, e1], [2.1, 3.4, 6.5])
            self.assertTrue(np.isinf(e(x)))
            e = pints.SumOfErrors([e4, e5, e1], [2.1, 3.4, 6.5])
            self.assertTrue(np.isinf(e(x)))
            e5 = pints.SumOfSquaresError(BadMiniProblem(float('nan')))
            e = pints.SumOfErrors(
                [BadErrorMeasure(float('inf')),
                 BadErrorMeasure(float('inf'))], [1, 1])
            self.assertEqual(e(x), float('inf'))
            e = pints.SumOfErrors([
                BadErrorMeasure(float('inf')),
                BadErrorMeasure(float('-inf'))
            ], [1, 1])
            self.assertTrue(np.isnan(e(x)))
            e = pints.SumOfErrors(
                [BadErrorMeasure(5),
                 BadErrorMeasure(float('nan'))], [1, 1])
            self.assertTrue(np.isnan(e(x)))
            e = pints.SumOfErrors([e1, e5, e1], [2.1, 3.4, 6.5])
            self.assertTrue(np.isnan(e(x)))
            e = pints.SumOfErrors([e4, e5, e1], [2.1, 3.4, 6.5])
            self.assertTrue(np.isnan(e(x)))

        # Wrong number of ErrorMeasures
        self.assertRaises(ValueError, pints.SumOfErrors, [], [])

        # Wrong argument types
        self.assertRaises(TypeError, pints.SumOfErrors, [e1, e1], [e1, 1])
        self.assertRaises(ValueError, pints.SumOfErrors, [e1, 3], [2, 1])

        # Mismatching sizes
        self.assertRaises(ValueError, pints.SumOfErrors, [e1, e1, e1], [1, 1])

        # Mismatching problem dimensions
        self.assertRaises(ValueError, pints.SumOfErrors, [e1, e1, e3],
                          [1, 2, 3])

        # Single-output derivatives
        model = pints.toy.ConstantModel(1)
        times = [1, 2, 3]
        p1 = pints.SingleOutputProblem(model, times, [1, 1, 1])
        p2 = pints.SingleOutputProblem(model, times, [2, 2, 2])
        e1 = pints.SumOfSquaresError(p1)
        e2 = pints.SumOfSquaresError(p2)
        e = pints.SumOfErrors([e1, e2], [1, 2])
        x = [4]
        y, dy = e.evaluateS1(x)
        self.assertEqual(y, e(x))
        self.assertEqual(dy.shape, (1, ))
        y1, dy1 = e1.evaluateS1(x)
        y2, dy2 = e2.evaluateS1(x)
        self.assertTrue(np.all(dy == dy1 + 2 * dy2))

        # Multi-output derivatives
        model = pints.toy.ConstantModel(2)
        times = [1, 2, 3]
        p1 = pints.MultiOutputProblem(model, times, [[3, 2], [1, 7], [3, 2]])
        p2 = pints.MultiOutputProblem(model, times, [[2, 3], [3, 4], [5, 6]])
        e1 = pints.SumOfSquaresError(p1)
        e2 = pints.SumOfSquaresError(p2)
        e = pints.SumOfErrors([e1, e2], [1, 2])
        x = [4, -2]
        y, dy = e.evaluateS1(x)
        self.assertEqual(y, e(x))
        self.assertEqual(dy.shape, (2, ))
        y1, dy1 = e1.evaluateS1(x)
        y2, dy2 = e2.evaluateS1(x)
        self.assertTrue(np.all(dy == dy1 + 2 * dy2))
コード例 #24
0
    def test_sum_of_squares_error_weighted(self):
        """ Tests :class:`pints.MeanSquaredError` with weighted outputs. """

        # Set up problem
        model = pints.toy.ConstantModel(2)
        times = [1, 2, 3]
        values = [[1, 4], [1, 4], [1, 4]]
        p = pints.MultiOutputProblem(model, times, values)

        # Test
        e = pints.SumOfSquaresError(p, weights=[1, 2])
        self.assertRaisesRegex(ValueError,
                               'Number of weights',
                               pints.SumOfSquaresError,
                               p,
                               weights=[1, 2, 3])
        self.assertEqual(e.n_parameters(), 2)
        float(e([1, 2]))
        self.assertEqual(e([1, 2]), 0)  # 0
        self.assertEqual(e([2, 2]), 3)  # 3*(1^2*1+0^2*2) = 3
        self.assertEqual(e([2, 3]), 27)  # 3*(1^2*1+2^2*2) = 27
        self.assertEqual(e([3, 4]), 108)  # 3*(2^2*1+4^2*2) = 108

        # Derivatives
        values = np.array([[1, 4], [2, 7], [3, 10]])
        p = pints.MultiOutputProblem(model, times, values)
        w = np.array([1, 2])
        e = pints.SumOfSquaresError(p, weights=w)
        x = [1, 2]

        # Model outputs are 3 times [1, 4]
        # Model derivatives are 3 times [[1, 0], [0, 1]]
        y, dy = p.evaluateS1(x)
        self.assertTrue(np.all(y == p.evaluate(x)))
        self.assertTrue(np.all(y[0, :] == [1, 4]))
        self.assertTrue(np.all(y[1, :] == [1, 4]))
        self.assertTrue(np.all(y[2, :] == [1, 4]))
        self.assertTrue(np.all(dy[0, :] == [[1, 0], [0, 1]]))
        self.assertTrue(np.all(dy[1, :] == [[1, 0], [0, 1]]))
        self.assertTrue(np.all(dy[2, :] == [[1, 0], [0, 1]]))

        # Check residuals
        rx = y - np.array(values)
        self.assertTrue(np.all(rx == np.array([[-0, -0], [-1, -3], [-2, -6]])))
        self.assertAlmostEqual(e(x), np.sum(np.sum(rx**2, axis=0) * w))

        # Now with derivatives
        ex, dex = e.evaluateS1(x)

        # Check error
        self.assertAlmostEqual(ex, e(x))

        # Check derivatives. Shape is (parameters, )
        self.assertEqual(dex.shape, (2, ))

        # Residuals are: [[0, 0], [-1, -3], [-2, -6]]
        # Derivatives are: [[1, 0], [0, 1]]
        # dex1 is: 2 * (0 - 1 - 2) * 1 * 1
        #        = 2 * -3 * 1 * 1
        #        = -6
        # dex2 is: 2 * (0 - 3 - 6) * 2 * 1
        #        = 2 * -9 * 2 * 1
        #        = -36
        self.assertEqual(dex[0], -6)
        self.assertEqual(dex[1], -36)
コード例 #25
0
def main(args, output_dir="", ms_to_remove_after_spike=50):
    output_dir = os.path.join(args.output, output_dir)
    if not os.path.exists(output_dir):
        os.mkdir(output_dir)
    # Constants
    if ms_to_remove_after_spike == 0:
        indices_to_remove = None
    else:
        spikes = [2500, 3000, 5000, 15000, 20000, 30000, 65000, 70000]
        indices_to_remove = [[spike, spike + ms_to_remove_after_spike*10] for spike in spikes]

    indices_to_use = remove_indices(list(range(80000)), indices_to_remove)
    # indices_to_use = [[1,2499], [2549,2999], [3049,4999], [5049,14999], [15049,19999], [20049,29999], [30049,64999], [65049,69999], [70049,-1]]
    starting_parameters = [3.87068845e-04, 5.88028759e-02, 6.46971727e-05, 4.87408447e-02, 8.03073893e-02, 7.36295506e-03, 5.32908518e-03, 3.32254316e-02, 6.56614672e-02]

    plt.rcParams['axes.axisbelow'] = True

    data  = pd.read_csv(args.data_file_path, delim_whitespace=True)

    print("outputting to {}".format(args.output))

    if not os.path.exists(args.data_file_path):
        print("Input file not provided. Doing nothing.")
        return

    par = Params()

    skip = int(par.timestep/0.1)
    dat = data.values[indices_to_use]

    times=dat[:,0]
    values=dat[:,1]

    model = PintsWrapper(par, args, times)

    current = model.simulate(starting_parameters, times)

    if args.plot:
        plt.plot(times, values)
        plt.plot(model.times_to_use, current)
        plt.show()

    problem = pints.SingleOutputProblem(model, times, values)
    error = pints.SumOfSquaresError(problem)
    boundaries  = Boundaries()
    x0 = starting_parameters

    found_parameters, found_value = pints.optimise(error, starting_parameters, boundaries=boundaries)
    # found_parameters = np.array([2.26E-04, 0.0699, 3.45E-05, 0.05462, 0.0873, 8.92E-03, 5.150E-3, 0.03158, 0.1524])
    # found_value = 100

    print("finished! found parameters : {} ".format(found_parameters, found_value))

    # Find error sensitivities
    funcs = model.funcs
    current, sens = funcs.SimulateForwardModelSensitivities(found_parameters)
    sens = (sens * found_parameters[None,:]).T

    for i, vec in enumerate(sens):
        plt.plot(times, vec, label="state_variable".format(i))

    plt.title("Output sensitivities for four gate Markov Model")
    if args.plot:
        plt.show()
    else:
        plt.savefig(os.path.join(output_dir, "output_sensitivities"))
        plt.clf()

    # Estimate the various of the i.i.d Gaussian noise
    nobs = len(times)
    sigma2 = sum((current - values)**2)/(nobs-1)

    # Compute the Fischer information matrix
    FIM = sens @ sens.T/sigma2
    cov = FIM**-1
    eigvals = np.linalg.eigvals(FIM)
    for i in range(0, par.n_params):
        for j in range(i+1, par.n_params):
            parameters_to_view = np.array([i,j])
            sub_cov = cov[parameters_to_view[:,None], parameters_to_view]
            eigen_val, eigen_vec = np.linalg.eigh(sub_cov)
            eigen_val=eigen_val.real
            if eigen_val[0] > 0 and eigen_val[1] > 0:
                print("COV_{},{} : well defined".format(i, j))
                cov_ellipse(sub_cov, q=[0.75, 0.9, 0.99])
                plt.ylabel("parameter {}".format(i))
                plt.xlabel("parameter {}".format(j))
                if args.plot:
                    plt.show()
                else:
                    plt.savefig(os.path.join(output_dir, "covariance_for_parameters_{}_{}".format(i,j)))
                plt.clf()
            else:
                print("COV_{},{} : negative eigenvalue".format(i,j))


    print('Eigenvalues of FIM:\n{}'.format(eigvals))
    print("Covariance matrix is: \n{}".format(cov))

    plt.plot(data["time"], data["current"], label="averaged data")
    plt.plot(times, current, label="current")
    plt.legend()
    if args.plot:
        plt.show()
    else:
        plt.savefig(os.path.join(output_dir, "fit"))
        plt.clf()

    return times, found_parameters
コード例 #26
0
model, prot, script = myokit.load('./PKPD_linear.mmt')

s = myokit.Simulation(model, prot)

# Format the values list to use it in PINTS
fit_values = values[0] + values[1]

# Calling PINTS library
# Parameters : [CL, Vc, Qp1, Vp1, Qp2, Vp2]
initial_point = [5.4, 8.5, 18.6, 8.3, 1.7, 32.8]
problem = pints.SingleOutputProblem(model=MyModel(),
                                    times=np.linspace(0, 24, 10),
                                    values=fit_values)
boundaries = pints.RectangularBoundaries([3, 5, 7, 5, 0.5, 30],
                                         [15, 15, 30, 20, 5, 60])
error_measure = pints.SumOfSquaresError(problem)
found_parameters, found_value = pints.optimise(error_measure,
                                               initial_point,
                                               boundaries=boundaries,
                                               method=pints.XNES)

#%% Running the simulation with found parameters
# Reset the variables to initial state for the plot
s.reset()

# Use parameters returned from optimisation or user-defined parameters set
parameters = [6.7, 10.1, 17.8, 9.4, 1.4, 18.3]
plot_parameters = found_parameters
s.set_constant('constants.CL', plot_parameters[0])
s.set_constant('plasma.Vc', plot_parameters[1])
s.set_constant('constants.kp1', plot_parameters[2])
コード例 #27
0
def infer_params(initial_point,
                 data_exp,
                 boundaries_low,
                 boundaries_high,
                 pints_method=pints.XNES,
                 parallel=False):
    """
    Infers parameters using PINTS library pnits.optimise() function, using
    method pints.XNES, and rectangular boundaries.

    :param initial_point: list
        Starting point for optimisation. It has to match the length of fitting
        parameters annotations.
    :param data_exp: Data_exp
        Contains the data that the model is fitted too. See documentation for
        sabs_pkpd.load_data for further info
    :param boundaries_low: list
        List of lower boundaries for the fitted parameters. It has to match the
        length of fitting parameters annotations
    :param boundaries_high: list
        List of lower boundaries for the fitted parameters. It has to match the
        length of fitting parameters annotations
    :return: found_parameters : numpy.array
        List of parameters values after optimisation routine.
    """

    if len(initial_point) != \
            len(data_exp.fitting_instructions.fitted_params_annot):
        raise ValueError('The initial point should have the same length as '
                         'the fitted parameters annotations '
                         '(defined in data_exp.fitting_instructions')

    if len(boundaries_low) != \
            len(data_exp.fitting_instructions.fitted_params_annot):
        raise ValueError('The lower boundaries should have the same length as '
                         'the fitted parameters annotations '
                         '(defined in data_exp.fitting_instructions')

    if len(boundaries_high) != \
            len(data_exp.fitting_instructions.fitted_params_annot):
        raise ValueError('The higher boundaries should have the same length '
                         'as the fitted parameters annotations '
                         '(defined in data_exp.fitting_instructions')

    fit_values = np.concatenate(data_exp.values)

    sabs_pkpd.constants.n = len(
        sabs_pkpd.constants.data_exp.fitting_instructions.fitted_params_annot)

    problem = pints.SingleOutputProblem(
        model=MyModel(),
        times=np.linspace(0, 1, len(fit_values)),
        values=fit_values)
    boundaries = pints.RectangularBoundaries(boundaries_low, boundaries_high)
    error_measure = pints.SumOfSquaresError(problem)
    optimiser = pints.OptimisationController(error_measure,
                                             initial_point,
                                             boundaries=boundaries,
                                             method=pints_method)
    optimiser.set_parallel(parallel=parallel)
    found_parameters, found_value = optimiser.run()
    print(data_exp.fitting_instructions.fitted_params_annot)
    print(found_parameters)
    return found_parameters, found_value