예제 #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
    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
    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
    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)
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
    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
    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
    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