Esempio n. 1
0
def score_function_ellipsoid_maker(param = 0.05, sigma=1.5):
    """
    param: decay rate of the exponentials
    """
    eta = np.linalg.norm(target_state-saddle_state)/np.linalg.norm(target_state-initial_state)
    
    covariance_matrix_start, quad_form_initial, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(force_matrix, initial_state, sigma, noise_matrix=noise_matrix)
    covariance_matrix_target, quad_form_target, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(force_matrix, target_state, sigma, noise_matrix=noise_matrix)
    
    def score_function(v):
        return eta - eta*np.exp(-param*quad_form_initial(v))+(1-eta)*np.exp(-param*quad_form_target(v))
    
    return score_function
Esempio n. 2
0
def remap_score_function_ell(score_function, force_matrix, equilibrium_point,
                             noise):
    """
    This function warps the score function so that the target set is the 0.95-confidence ellipsoid.
    return the score function and the associated threshold
    """
    C, quad_form, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
        force_matrix,
        equilibrium_point,
        noise,
        confidence=0.95,
        warning_threshold=1e-3)

    ellipsoid_array = ellipsoid_fun.get_ellipsoid_array(
        equilibrium_point, quad_form, level, bound)

    score_level = np.min(
        np.apply_along_axis(score_function, 1, ellipsoid_array))

    def remapped_score_function(v):
        score = score_function(v)
        if score >= score_level:
            if ellipsoid_fun.ellipsoid_test(v, quad_form, level):
                return 1
            else:
                return score_level
        else:
            return score

    return remapped_score_function, (1 - score_level) / 2
Esempio n. 3
0
def score_function_composite_maker(filename='trajectory.hdf5',
                                   decay=4,
                                   param=0.01,
                                   sigma=1.5):
    custom_score_function = score_function_custom_maker(filename, decay)

    eta = np.linalg.norm(target_state -
                         saddle_state) / np.linalg.norm(target_state -
                                                        initial_state)

    covariance_matrix_start, quad_form_initial, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
        force_matrix, initial_state, sigma, noise_matrix=noise_matrix)
    covariance_matrix_target, quad_form_target, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
        force_matrix, target_state, sigma, noise_matrix=noise_matrix)

    def score_function(v):
        return (custom_score_function(v) + eta -
                eta * np.exp(-param * quad_form_initial(v))) / 1.5

    return score_function
Esempio n. 4
0
def score_function_fred_ell_maker(sigma=1.5):
    covariance_matrix_target, quad_form_target, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
        force_matrix, target_state, sigma, noise_matrix=noise_matrix)

    def score_function(v):
        da = np.linalg.norm(v - initial_state)
        db = np.sqrt(quad_form_target(v))
        if da <= db:
            return da / 2 / db
        else:
            return 1 - db / 2 / da

    return score_function
Esempio n. 5
0
def score_function_ellipsoid_maker(param=0.01,
                                   sigma=1.5,
                                   direction=None,
                                   forward=0.3,
                                   backward=0.1):
    """
    param: decay rate of the exponentials
    """
    eta = np.linalg.norm(target_state -
                         saddle_state) / np.linalg.norm(target_state -
                                                        initial_state)

    covariance_matrix_start, quad_form_initial, spectral_radius, level_initial, bound_initial = ellipsoid_fun.ingredients_score_function(
        force_matrix, initial_state, sigma, noise_matrix=noise_matrix)
    covariance_matrix_target, quad_form_target, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
        force_matrix, target_state, sigma, noise_matrix=noise_matrix)

    if direction is None:

        def score_function(v):
            return eta - eta * np.exp(-param * quad_form_initial(v)) + (
                1 - eta) * np.exp(-param * quad_form_target(v))

        return score_function
    else:
        direction = direction / np.linalg.norm(direction)
        s = np.linspace(-3 * bound, 3 * bound, 1000)

        s = np.linspace(0, 3 * bound_initial, 1000)

        s = np.expand_dims(s, 1)
        line = s * direction + initial_state

        direction_on_border = line[np.argmin(
            np.apply_along_axis(quad_form_initial, 1, line) < level_initial
        )] - initial_state
        print(direction_on_border)

        def score_function(v):
            return eta - eta * np.exp(
                -param * forward * (backward + 1 + np.tanh(
                    0.2 * np.dot(v - initial_state, direction_on_border.T))) *
                quad_form_initial(v)) + (1 - eta) * np.exp(
                    -param * quad_form_target(v))

        return score_function
Esempio n. 6
0
def plot_trajectory(time_array,
                    force,
                    initial_state,
                    target_state,
                    sigma1,
                    noise_matrix,
                    force_matrix,
                    xmin=-15,
                    xmax=15,
                    ymin=-15,
                    ymax=15,
                    zmin=0,
                    zmax=15,
                    save_path=None,
                    vs=None):
    """
    plots the trajectories of two particles starting in the initial states, for two values of noise strength sigma
    """

    fig = plt.figure(1)
    ax = fig.add_subplot(111, projection='3d')
    ax.patch.set_facecolor('white')
    ax.tick_params(axis='both', which='major', pad=-2)

    if vs is None:
        solver_scheme = functools.partial(schemes.Euler_Maruyama_no_stop,
                                          force=force,
                                          time_array_length=len(time_array),
                                          dt=0.01,
                                          dims=3,
                                          noise_matrix=noise_matrix)
        vs = solver_scheme(0, initial_state, sigma1)

    ax.plot(vs[:, 1],
            vs[:, 0],
            zs=vs[:, 2],
            zdir='z',
            linewidth=0.2,
            color='C1')

    #plt.title(r'$\sigma$'+' = {}'.format(sigma1))
    ax.set_ylabel('x', labelpad=-7)
    ax.set_xlabel('y', labelpad=-7)
    ax.set_zlabel('z', labelpad=-7)

    ax.set_xlim(xmin, xmax)
    ax.set_zlim(zmin, zmax)
    ax.set_ylim(ymin, ymax)

    plt.scatter(initial_state[1],
                initial_state[0],
                zs=initial_state[2],
                marker='o',
                label='$X_A$',
                s=40,
                color='black',
                zorder=1000)
    plt.scatter(target_state[1],
                target_state[0],
                zs=target_state[2],
                marker='x',
                label='$X_B$',
                s=40,
                color='black',
                zorder=1000)

    if force_matrix is not None:
        covariance_matrix_target, quad_form_target, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
            force_matrix, target_state, sigma1, noise_matrix)
        plot_ellipsoid(np.linalg.inv(covariance_matrix_target),
                       level,
                       target_state,
                       ax,
                       color='C0',
                       label=None)

        covariance_matrix_initial, quad_form_target, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
            force_matrix, initial_state, sigma1, noise_matrix)
        plot_ellipsoid(np.linalg.inv(covariance_matrix_initial),
                       level,
                       initial_state,
                       ax,
                       label=None,
                       color='C0')

    plt.scatter(initial_state[1],
                initial_state[0],
                zs=initial_state[2],
                marker='o',
                label='$X_A$',
                s=40,
                color='black',
                zorder=1000)
    plt.scatter(target_state[1],
                target_state[0],
                zs=target_state[2],
                marker='x',
                label='$X_B$',
                s=40,
                color='black',
                zorder=1000)
    #plt.legend()

    plt.xticks([-5, 0, 5])
    plt.yticks([-5, 0, 5])
    ax.set_zticks([0, 5, 10, 15])

    ax.text2D(0.1,
              0.9,
              '(a)',
              horizontalalignment='center',
              verticalalignment='center',
              transform=plt.gca().transAxes,
              fontsize=9)
    if save_path is not None:
        plt.savefig(save_path)

    plt.show()
Esempio n. 7
0
def trajectory(time_array,
               force,
               initial_state,
               target_state,
               sigma1,
               noise_matrix,
               force_matrix,
               index_time=[0, 1],
               index_traj=[0, 1],
               label_time=['x', 'y'],
               label_traj=['x', 'y'],
               score_function=None,
               xmin=None,
               xmax=None,
               ymin=None,
               ymax=None,
               save_path=None):
    """
    plots the trajectories of two particles starting in the initial states, for two values of noise strength sigma
    """

    plt.figure()

    solver_scheme = functools.partial(schemes.Euler_Maruyama_no_stop,
                                      force=force,
                                      time_array_length=len(time_array),
                                      dt=0.01,
                                      dims=4,
                                      noise_matrix=noise_matrix)

    #solve first trajectory
    vs = solver_scheme(0, initial_state, sigma1)

    plt.plot(vs[:, index_traj[0]],
             vs[:, index_traj[1]],
             linewidth=0.1,
             color='C1')
    plt.title(r'$\sigma$' + ' = {}'.format(sigma1))
    plt.ylabel(label_traj[1])
    plt.ylim((ymin, ymax))
    plt.xlim(xmin, xmax)

    plt.scatter(initial_state[index_traj[0]],
                initial_state[index_traj[1]],
                marker='o',
                label='initial',
                s=40,
                color='black')
    plt.scatter(target_state[index_traj[0]],
                target_state[index_traj[1]],
                marker='x',
                label='target',
                s=40)

    if force_matrix is not None:
        dim = len(initial_state)
        indices = [0, 2]
        index1, index2 = indices
        rest1, rest2 = [idx for idx in range(dim) if idx not in indices]

        covariance_matrix_target, quad_form_target, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
            force_matrix, target_state, sigma1, noise_matrix)
        proj = target_state
        lims = bound
        binslist = [None] * dim

        binslist[rest1] = np.array([proj[rest1]])
        binslist[rest2] = np.array([proj[rest2]])

        binslist[index1] = np.linspace(proj[index1] - lims,
                                       proj[index1] + lims, 300)
        binslist[index2] = np.linspace(proj[index2] - lims,
                                       proj[index2] + lims, 300)

        a0, a1, a2, a3 = binslist

        grids = list(np.meshgrid(a0, a1, a2, a3))

        ell = np.apply_along_axis(quad_form_target, 0, np.array(grids))
        ell = np.squeeze(ell)
        plt.contour(np.squeeze(grids[index1]),
                    np.squeeze(grids[index2]),
                    ell,
                    levels=[level],
                    colors=['black'],
                    label='confidence ellipsoid')

        covariance_matrix_initial, quad_form_initial, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
            force_matrix, initial_state, sigma1, noise_matrix)
        proj = initial_state
        lims = bound
        binslist = [None] * dim

        binslist[rest1] = np.array([proj[rest1]])
        binslist[rest2] = np.array([proj[rest2]])

        binslist[index1] = np.linspace(proj[index1] - lims,
                                       proj[index1] + lims, 300)
        binslist[index2] = np.linspace(proj[index2] - lims,
                                       proj[index2] + lims, 300)

        a0, a1, a2, a3 = binslist

        grids = list(np.meshgrid(a0, a1, a2, a3))

        ell = np.apply_along_axis(quad_form_initial, 0, np.array(grids))
        ell = np.squeeze(ell)
        plt.contour(np.squeeze(grids[index1]),
                    np.squeeze(grids[index2]),
                    ell,
                    levels=[level],
                    colors=['black'],
                    label='confidence ellipsoid')

    plt.legend()

    if save_path is not None:

        plt.savefig(save_path)
    plt.show()

    plt.figure()

    #solve trajectory

    ax = plt.subplot(222)
    ax.plot(time_array,
            initial_state[2] + np.zeros((len(time_array))),
            linestyle='--')
    ax.plot(time_array,
            target_state[2] + np.zeros((len(time_array))),
            linestyle='--')
    ax.plot(time_array, vs[:, 2], linewidth=0.3)
    ax.set_ylabel('$A_3$')
    plt.setp(ax.get_xticklabels(), visible=False)

    ax = plt.subplot(221, sharex=ax)
    ax.plot(time_array,
            initial_state[0] + np.zeros((len(time_array))),
            linestyle='--',
            label='initial state')
    ax.plot(time_array,
            target_state[0] + np.zeros((len(time_array))),
            linestyle='--',
            label='target state')
    ax.plot(time_array, vs[:, 0], linewidth=0.3)
    ax.set_ylabel('$A_1$')
    ax.legend(fontsize='xx-small')
    plt.setp(ax.get_xticklabels(), visible=False)

    ax = plt.subplot(224)
    ax.plot(time_array,
            initial_state[3] + np.zeros((len(time_array))),
            linestyle='-')
    ax.plot(time_array,
            target_state[3] + np.zeros((len(time_array))),
            linestyle='--',
            dashes=(3.5, 3.5))
    ax.plot(time_array, vs[:, 3], linewidth=0.3)
    ax.set_ylabel('$A_4$')
    ax.set_xlabel('time')

    ax = plt.subplot(223, sharex=ax)
    ax.plot(time_array,
            initial_state[1] + np.zeros((len(time_array))),
            linestyle='-')
    ax.plot(time_array,
            target_state[1] + np.zeros((len(time_array))),
            linestyle='--',
            dashes=(3.5, 3.5))
    ax.plot(time_array, vs[:, 1], linewidth=0.3)
    ax.set_ylabel('$A_2$')
    ax.set_xlabel('time')

    if save_path is not None:
        plt.savefig(save_path)
    plt.show()

    print([f'{elem:.15e}' for elem in vs[-1]])
Esempio n. 8
0
def draw_projection(
    initial_state,
    target_state,
    indices,
    proj,
    noise_matrix,
    lims=[2, 2],
    function=None,
    sigma=None,
    force_matrix=None,
):

    dim = len(initial_state)

    plt.figure()
    index1, index2 = indices
    [rest1] = [idx for idx in range(dim) if idx not in indices]

    binslist = [None] * dim

    binslist[rest1] = np.array([proj[rest1]])

    binslist[index1] = np.linspace(proj[index1] - lims[0],
                                   proj[index1] + lims[0], 300)
    binslist[index2] = np.linspace(proj[index2] - lims[1],
                                   proj[index2] + lims[1], 300)

    a0, a1, a2 = binslist

    grids = list(np.meshgrid(a0, a1, a2))

    if function is not None:
        values = np.apply_along_axis(function, 0, np.array(grids))

        values = np.squeeze(values)
        im = plt.contourf(np.squeeze(grids[index1]), np.squeeze(grids[index2]),
                          values, 50)
        plt.colorbar(im)

    if initial_state is not None:
        plt.scatter(initial_state[index1],
                    initial_state[index2],
                    marker='o',
                    label='initial',
                    s=40,
                    color='black')
    if target_state is not None:
        plt.scatter(target_state[index1],
                    target_state[index2],
                    marker='x',
                    label='target',
                    s=40)

    if sigma is not None and force_matrix is not None:
        covariance_matrix_target, quad_form_target, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
            force_matrix, target_state, sigma, noise_matrix)
        ell = np.apply_along_axis(quad_form_target, 0, np.array(grids))
        ell = np.squeeze(ell)
        plt.contour(np.squeeze(grids[index1]),
                    np.squeeze(grids[index2]),
                    ell,
                    levels=[level],
                    colors=['black'],
                    label='confidence ellipsoid')
    plt.legend()
    plt.show()
Esempio n. 9
0
def check(time_array,
          force,
          initial_state,
          target_state,
          sigma1,
          noise_matrix,
          force_matrix,
          xmin=-15,
          xmax=15,
          ymin=-15,
          ymax=15,
          zmin=0,
          zmax=15,
          save_path=None):

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    solver_scheme = functools.partial(schemes.Euler_Maruyama_no_stop,
                                      force=force,
                                      time_array_length=len(time_array),
                                      dt=0.01,
                                      dims=3,
                                      noise_matrix=noise_matrix)

    plt.title(r'$\sigma$' + ' = {}'.format(sigma1))
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_zlabel('z')

    plt.scatter(initial_state[0],
                initial_state[1],
                zs=initial_state[2],
                marker='o',
                label='initial',
                s=40,
                color='black')
    plt.scatter(target_state[0],
                target_state[1],
                zs=target_state[2],
                marker='x',
                label='target',
                s=40)

    if force_matrix is not None:
        covariance_matrix_target, quad_form_target, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
            force_matrix, target_state, sigma1, noise_matrix, confidence=0.99)
        plot_ellipsoid(np.linalg.inv(covariance_matrix_target),
                       level,
                       target_state,
                       ax,
                       color='C0')

        covariance_matrix_initial, quad_form_initial, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
            force_matrix, initial_state, sigma1, noise_matrix, confidence=0.99)
        plot_ellipsoid(np.linalg.inv(covariance_matrix_initial),
                       level,
                       initial_state,
                       ax,
                       label=None)

        print(level)

        ell = ellipsoid_fun.get_ellipsoid_interior(target_state,
                                                   quad_form_target,
                                                   level,
                                                   bound,
                                                   nb_points=1e6,
                                                   sample=100)
        for elem in ell:
            vs = solver_scheme(0, elem, 0)
            plt.plot(vs[:, 0], vs[:, 1], vs[:, 2], linewidth=0.1, color='C1')
            plt.scatter(vs[-1, 0], vs[-1, 1], zs=vs[-1:2], s=10, color='red')
            plt.scatter(vs[0, 0], vs[0, 1], zs=vs[0, 2], s=10, color='green')
            print(quad_form_target(elem), level)

    plt.legend()

    if save_path is not None:
        plt.savefig(save_path)
    ax.set_xlim(xmin, xmax)
    ax.set_zlim(zmin, zmax)
    ax.set_ylim(ymin, ymax)
    plt.show()
Esempio n. 10
0
    def monte_carlo_run(self,
                        sigma_grid,
                        N_particles,
                        freq=1000,
                        output_path=None):

        #transition_probability matrix
        transition_probability_grid_MC = np.zeros((len(sigma_grid)))

        #hitting time matrix, computing time matrix
        computing_time = np.zeros((len(sigma_grid)))
        number_timesteps = np.zeros((len(sigma_grid)))

        job_start_time = tm.time()
        print("############################")
        print("Starting Monte Carlo job ...")
        print("############################\n\n")

        for s, sigma in enumerate(sigma_grid):
            print(
                'Parameters: \n noise strength sigma: {:.2f}. \n particles number: {:.1e} \n trajectory length: {} seconds. \n dt = {} seconds'
                .format(sigma, N_particles, self.t_trajectory, self.dt))

            sigma_start_time = tm.time()
            #covariance matrix and associated quadratic form
            covariance_matrix, quad_form, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
                self.force_matrix,
                equilibrium_point=self.target_state,
                noise=sigma)

            for n in range(N_particles):
                ndt, vs, count = schemes.Euler_Maruyama_ellipsoid_stop(
                    0,
                    self.initial_state,
                    sigma=sigma,
                    ellipsoid_test=functools.partial(
                        ellipsoid_fun.ellipsoid_test,
                        quad_form=quad_form,
                        level=level),
                    dims=self.dims,
                    force=self.force,
                    time_array_length=self.time_array_length,
                    dt=self.dt)
                transition_probability_grid_MC[s] += count
                number_timesteps[s] += ndt

                if n % freq == 0:
                    print(
                        f'Estimated probability: {transition_probability_grid_MC[s]}/{n+1} = {transition_probability_grid_MC[s]/(n+1):.2e}'
                    )
            transition_probability_grid_MC[
                s] = transition_probability_grid_MC[s] / N_particles
            sigma_end_time = tm.time()
            computing_time[s] += sigma_end_time - sigma_start_time
            print(
                f"Computed transition probability: {transition_probability_grid_MC[s]:.3e}"
            )

        job_end_time = tm.time()
        job_elapsed_time = job_end_time - job_start_time
        print('Total computing time: ' + self.display_time(job_elapsed_time))

        if output_path != None:
            #write data to hdf5 file
            with h5py.File(output_path, 'a') as file:
                transition_proability_dataset_MC = file.create_dataset(
                    f'transition_probability_grid_MC',
                    data=transition_probability_grid_MC)

                transition_proability_dataset_MC.attrs[
                    'sigma_grid'] = sigma_grid

                transition_proability_dataset_MC.attrs[
                    'trajectory_length'] = self.t_trajectory
                transition_proability_dataset_MC.attrs['dt'] = self.dt

                transition_proability_dataset_MC.attrs[
                    'N_particles'] = N_particles

                transition_proability_dataset_MC.attrs[
                    'number_timesteps'] = number_timesteps
                transition_proability_dataset_MC.attrs[
                    'computing_time'] = computing_time

                file.close()
                print(f'Wrote data to file {output_path}.')

        return transition_probability_grid_MC, computing_time, number_timesteps
    initial guess
    force matrix
    noise
    """

    #arguments
    score_function_maker = tw.score_function_ellipsoid_maker
    force_matrix = tw.force_matrix
    noise = noise
    initial_guess = 3
    initial_state = tw.initial_state
    target_state = tw.target_state
    threshold_param = tw.threshold_simexp_param

    #result
    covariance_matrix_start, quad_form_initial, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
        force_matrix, initial_state, noise)
    covariance_matrix_target, quad_form_target, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
        force_matrix, target_state, noise)

    ell = ellipsoid_fun.get_ellipsoid_array(target_state, quad_form_target,
                                            level, bound)
    score_function, score_threshold = ellipsoid_fun.optimize_param(
        score_function_maker, initial_guess, ell, noise,
        functools.partial(threshold_param, level=level))
#%%
if test_histogram_to_trajectory:
    """
    input:
    histogram
    start and end states
    binslist
Esempio n. 12
0
    def TAMS_run(self,
                 sigma_grid,
                 N_particles,
                 N_samples,
                 Nitermax,
                 listbins,
                 output_path,
                 histbis=False,
                 quadrant=False,
                 branching_points=False,
                 verbose=True,
                 quadrant_factor=1000,
                 geom_stopping=False,
                 score_stopping=False,
                 warp=False):

        #transition_probability matrix
        transition_probability_grid_TAMS = np.zeros(
            (len(sigma_grid), N_samples))

        #computing time matrix
        computing_time = np.zeros((len(sigma_grid), N_samples))
        number_timesteps = np.zeros((len(sigma_grid), N_samples))

        #same_score_error matrix (0 if no error, 1 if same score error is encountered)
        same_score_error = np.zeros((len(sigma_grid), N_samples))

        #density probability or histogram, mean trajectory
        probability_density = np.zeros([len(sigma_grid)] +
                                       [len(elem) - 1 for elem in listbins])
        mean_trajectory = np.zeros(
            (len(sigma_grid), len(self.time_array), self.dims))

        #samples for the preferred initial direction WARNING: this only works if running N_samples=1 sample
        quadrant_samples = None
        direction = None

        #branching points at each iteration WARNING: this only works if running N_samples=1 sample
        branching_points_list = []
        pre_branching_points_list = []
        branching_scores_list = []
        pre_branching_scores_list = []

        job_start_time = tm.time()
        print('\n######################')
        print("Starting TAMS job ...")
        print('###################### \n\n')

        for s, sigma in enumerate(sigma_grid):
            print(
                'Parameters: \n noise strength sigma: {:.2f}. \n particles number: {:.1e} \n trajectory length: {} seconds. \n dt = {} seconds \n'
                .format(sigma, N_particles, self.t_trajectory, self.dt))
            """
            if self.adapt_param:
                #covariance matrix and associated quadratic form
                covariance_matrix, quad_form_start, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(self.force_matrix, equilibrium_point=self.initial_state, noise = sigma)
                covariance_matrix, quad_form, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(self.force_matrix, equilibrium_point=self.target_state, noise = sigma)
                
                ell = ellipsoid_fun.get_ellipsoid_array(self.target_state, quad_form, level, bound)
                self.score_function, self.score_threshold = ellipsoid_fun.optimize_param_normal(self.score_function_param, initial_guess= 1/quad_form_start(self.saddle_state)*2,
                                                        ell=ell, threshold_param = functools.partial(self.threshold_param, level = level))
            """

            #adapt the score function
            run_score_function = self.score_function

            #warp the score function so that the target set is the confidence ellipsoid
            if warp:
                print('Warping the score function...')
                run_score_function, run_threshold = warp_score_function_ell.remap_score_function_ell(
                    run_score_function,
                    self.force_matrix,
                    self.target_state,
                    noise=sigma)
                print(
                    f'Used the ellipsoid to warp the score function threshold. Automatic threshold: {run_threshold:.2e} \n'
                )

            # if you want to sample the exit direction of the ellipsoid, calculate the ellipsoid and the function that tests if a point is in the ellipsoid
            if quadrant:
                covariance_matrix_initial, quad_form_initial, spectral_radius_initial, level_initial, bound_initial = ellipsoid_fun.ingredients_score_function(
                    self.force_matrix,
                    self.initial_state,
                    sigma,
                    self.noise_matrix,
                    confidence=0.99)
                initial_test = functools.partial(ellipsoid_fun.ellipsoid_test,
                                                 quad_form=quad_form_initial,
                                                 level=level_initial)

            # defines the criterion for knowing if a trajectory has converged or not: either score (automatic or manual) or geometric
            if score_stopping:
                if warp:
                    score_stopping_level = 1 - run_threshold
                else:
                    score_stopping_level = float(score_stopping)
                print(
                    f'Using score stopping with level : {score_stopping_level: .2e}'
                )
                target_test = lambda v: run_score_function(
                    v
                ) > score_stopping_level  #stopping if score > score_stopping_level
            else:
                if not geom_stopping:
                    covariance_matrix_target, quad_form_target, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
                        self.force_matrix, self.target_state, sigma,
                        self.noise_matrix)
                    target_test = functools.partial(
                        ellipsoid_fun.ellipsoid_test,
                        quad_form=quad_form_target,
                        level=level)
                else:
                    geom_stopping_threshold = float(geom_stopping)
                    print(
                        f'Using geometrical stopping with  threshold : {geom_stopping_threshold: .2e}'
                    )
                    target_test = lambda v: np.linalg.norm(
                        v - self.target_state
                    ) < geom_stopping_threshold  #stopping if the trajectory is close to the target state by geom_stopping_threshold

            #generate Euler-Maruyama solver
            solver_scheme = functools.partial(
                self.solver_scheme_no_stop,
                dims=self.dims,
                force=self.force,
                time_array_length=self.time_array_length,
                dt=self.dt,
                noise_matrix=self.noise_matrix)

            for n in range(N_samples):
                print('Computing sample number {} out of {} ... \n'.format(
                    n + 1, N_samples))

                #initialize variables

                k = 1  #iteration number
                weights = [1]  #initial weight
                number_discarded_trajectories = [
                ]  #number discarded trajectories at each iteration

                TAMS_start_time = tm.time()  #timer

                #1. generate N independent trajectories, starting in initial condition
                traj = np.empty(
                    (N_particles, self.time_array_length, self.dims))
                for i in range(N_particles):
                    xs = solver_scheme(0, self.initial_state, sigma)
                    traj[i, :, :] = xs

                local_number_timesteps = N_particles * self.time_array_length  #stores number of computed steps

                #2. calculate scores
                scores_array = np.apply_along_axis(run_score_function, 2, traj)
                scores = np.max(scores_array, axis=1)
                min_score = np.min(scores)

                #3. target reached based on defined criterion
                target_reached_array = np.any(np.apply_along_axis(
                    target_test, 2, traj),
                                              axis=1)

                while k < Nitermax and np.count_nonzero(
                        target_reached_array
                ) < N_particles and not same_score_error[s, n]:

                    #3.get  worst trajectories
                    indexes_to_discard = np.array(
                        scores == min_score).nonzero()[0]

                    if len(indexes_to_discard) == N_particles:
                        same_score_error[s, n] = 1
                        break

                    #4. update weights and number of discarded trajectories
                    if verbose:
                        print(f'\n Iteration # {k}')
                        print(
                            f'Number of branched trajectories: {len(indexes_to_discard)}. Minimum score: {min_score}'
                        )

                    number_discarded_trajectories.append(
                        len(indexes_to_discard))
                    weights.append(weights[-1] *
                                   (1 - len(indexes_to_discard) / N_particles))

                    indexes_choice_pool = [
                        elem for elem in range(N_particles)
                        if not elem in indexes_to_discard
                    ]

                    #5. branch the discarded trajectories
                    for discarded_index in indexes_to_discard:
                        #select random trajectory in the rest
                        branch_traj_index = np.random.choice(
                            indexes_choice_pool)

                        #get branching time and position
                        branch_time_index = np.argmax(
                            scores_array[branch_traj_index, :] >= min_score)
                        branch_x = traj[branch_traj_index, branch_time_index]

                        #store branching points if asked
                        if branching_points:
                            reached_max = np.argmax(
                                scores_array[discarded_index])
                            assert scores_array[discarded_index,
                                                reached_max] == min_score

                            pre_branch_x = traj[discarded_index][
                                reached_max, :]

                            pre_branching_points_list.append(pre_branch_x)
                            branching_points_list.append(branch_x)

                            pre_branching_scores_list.append(
                                run_score_function(pre_branch_x))
                            branching_scores_list.append(
                                run_score_function(branch_x))

                        #compute the branched trajectory and update total computed timesteps
                        x_new = solver_scheme(branch_time_index, branch_x,
                                              sigma)
                        scores_new = np.apply_along_axis(
                            run_score_function, 1, x_new)
                        local_number_timesteps += self.time_array_length - branch_time_index

                        #update the trajectory storage matrix
                        traj[discarded_index, :branch_time_index] = traj[
                            branch_traj_index, :
                            branch_time_index]  #necessary only for the histogram?
                        traj[discarded_index, branch_time_index:] = x_new

                        #update the scores list and target reached
                        scores_array[discarded_index, :
                                     branch_time_index] = scores_array[
                                         branch_traj_index, :
                                         branch_time_index]  #unnecessary?
                        scores_array[discarded_index,
                                     branch_time_index:] = scores_new

                        scores[discarded_index] = np.max(scores_new)

                        #update target reached
                        target_reached_array[discarded_index] = np.any(
                            np.apply_along_axis(target_test, 1, x_new))

                        #verbose
                        if verbose:
                            print(
                                f'Branching index {discarded_index} to {branch_traj_index}. New score: {scores[discarded_index]}'
                            )
                            if scores[discarded_index] == min_score:
                                print('No score improvement')
                            else:
                                print('Score improved')
                            print(
                                f'{np.count_nonzero(target_reached_array)}/{N_particles} reached the target.'
                            )

                    #update iteration number
                    k += 1
                    min_score = np.min(scores)

                if same_score_error[s, n]:
                    print('All trajectories have the same score! :(')
                else:
                    #convert lists to numpy arrays
                    weights = np.array(weights)
                    number_discarded_trajectories = np.array(
                        number_discarded_trajectories)

                    #calculate transition probability
                    target_reached_indexes = np.nonzero(
                        target_reached_array)[0]
                    target_reached_number = np.count_nonzero(
                        target_reached_array)

                    #print(target_reached,k)
                    weight_normalisation_constant = N_particles * weights[
                        -1] + np.sum(
                            number_discarded_trajectories * weights[:-1])
                    transition_probability = target_reached_number / weight_normalisation_constant * weights[
                        -1]
                    transition_probability_grid_TAMS[
                        s, n] = transition_probability

                    #update mean_trajectory
                    with warnings.catch_warnings():
                        warnings.simplefilter("ignore",
                                              category=RuntimeWarning)
                        mean_trajectory[s] += np.mean(
                            traj[target_reached_indexes], axis=0) / N_samples

                    #update histogram
                    if histbis:
                        traj = np.asarray(traj)
                        traj_reshaped = traj.reshape((-1, self.dims))
                        time_weights = np.broadcast_to(
                            np.exp(self.time_array**2),
                            (N_particles, self.time_array_length))
                        weights = time_weights.reshape((-1))
                        hist, bins = np.histogramdd(traj_reshaped,
                                                    bins=listbins,
                                                    weights=weights)
                        probability_density[s] += hist
                    else:
                        traj = np.asarray(
                            traj
                        )  #convert matrix to array otherwise dimensionnality error in histogram
                        traj_reshaped = traj.reshape((-1, self.dims))
                        hist, bins = np.histogramdd(traj_reshaped,
                                                    bins=listbins)
                        probability_density[s] += hist

                    #calculates the preferred directions
                    if quadrant:
                        traj = np.asarray(traj)  #matrix to arrat
                        tested = np.apply_along_axis(
                            initial_test, 2, traj
                        )  #tests if the positions are in the initial confidence ellipsoid
                        indices_start = self.time_array_length - np.apply_along_axis(
                            np.argmax, 1, tested[:, ::-1]
                        )  #gets the last position at which all the positions after are outside the ellipsoid
                        indices_end = indices_start + int(
                            self.time_array_length // quadrant_factor
                        )  #defines the sample window (int(self.time_array_length//quadrant_factor) )

                        r = np.arange(self.time_array_length)
                        mask = (indices_start[:, None] <=
                                r) & (r <= indices_end[:, None])
                        quadrant_samples = traj[
                            mask, :]  #get the defined samples

                        #get the first two eigenvectors of the covariance matrix (can be easily generalized to more)
                        spectrum, eigvec = np.linalg.eig(
                            np.linalg.inv(covariance_matrix_initial))
                        eigvec1 = eigvec[:, 0]
                        eigvec2 = eigvec[:, 1]

                        #define projections onto the eigenvectors
                        def proj_1(v):
                            return np.sum((eigvec1) * (v - self.initial_state))

                        def proj_2(v):
                            return np.sum((eigvec2) * (v - self.initial_state))

                        #compute the average projections
                        avg_1 = np.mean(
                            np.apply_along_axis(proj_1, 1, quadrant_samples))
                        avg_2 = np.mean(
                            np.apply_along_axis(proj_2, 1, quadrant_samples))

                        #compute the direction
                        direction = avg_1 * eigvec1 + avg_2 * eigvec2
                        vector_direction = avg_1 * eigvec1 + avg_2 * eigvec2 + self.initial_state

                    #computing time update
                    TAMS_end_time = tm.time()
                    computing_time[s, n] = TAMS_end_time - TAMS_start_time
                    number_timesteps[s, n] = local_number_timesteps

                    #verbose
                    print(
                        f'\nTAMS algorithm stopped after {k}/{Nitermax} iterations'
                    )
                    print(
                        f'Computed transition probability: {transition_probability:.2e}'
                    )
                    print(
                        f'Number of computed timesteps: {local_number_timesteps:.2e}\n'
                    )

                    print(
                        f'Average number of trajectories discarded/iteration : {np.mean(number_discarded_trajectories):.2f}'
                    )
                    print(
                        f'Computed a total of {np.sum(number_discarded_trajectories)} trajectories.'
                    )
                    print(
                        f'Computed {target_reached_number} reactive trajectories.'
                    )

                    if quadrant:
                        print(
                            f"Collected {quadrant_samples.shape[0]} points for direction calculation."
                        )
                        print(
                            f'Computed starting direction: {direction} and direction vector: {vector_direction}'
                        )

                    print(
                        f'TAMS computing time: {self.display_time(TAMS_end_time - TAMS_start_time)} \n'
                    )

        job_end_time = tm.time()
        job_elapsed_time = job_end_time - job_start_time
        print("\n" + "TAMS job finished. ")
        print(
            f'Total timesteps computed: {np.sum(number_timesteps, axis = (0,1)):.2e}'
        )
        print('Total computing time: ' + self.display_time(job_elapsed_time))

        if 1 in same_score_error:
            print('WARNING: Same score error occured at some point.')

        if output_path is not None:
            #write data to hdf5 file
            with h5py.File(output_path, 'a') as file:
                transition_proability_dataset_TAMS = file.create_dataset(
                    'transition_probability_grid_TAMS',
                    data=transition_probability_grid_TAMS)

                if quadrant:
                    file.create_dataset('quadrant_samples',
                                        data=quadrant_samples)
                    file.create_dataset('direction', data=direction)

                if branching_points:
                    file.create_dataset('branching_points',
                                        data=np.array(branching_points_list))
                    file.create_dataset(
                        'pre_branching_points',
                        data=np.array(pre_branching_points_list))

                    file.create_dataset('branching_scores',
                                        data=np.array(branching_scores_list))
                    file.create_dataset(
                        'pre_branching_scores',
                        data=np.array(pre_branching_scores_list))

                transition_proability_dataset_TAMS.attrs[
                    'sigma_grid'] = sigma_grid

                transition_proability_dataset_TAMS.attrs[
                    'trajectory_length'] = self.t_trajectory
                transition_proability_dataset_TAMS.attrs['dt'] = self.dt
                #transition_proability_dataset_TAMS.attrs['score_threshold'] = run_threshold

                transition_proability_dataset_TAMS.attrs[
                    'Initial state'] = self.initial_state

                transition_proability_dataset_TAMS.attrs[
                    'N_samples'] = N_samples
                transition_proability_dataset_TAMS.attrs[
                    'N_particles'] = N_particles
                transition_proability_dataset_TAMS.attrs[
                    'Maximum_number_iterations'] = Nitermax

                file.create_dataset('number_timesteps', data=number_timesteps)
                file.create_dataset('computing_time', data=computing_time)

                file.create_dataset('probability_density',
                                    data=probability_density)
                file.create_dataset('listbins', data=listbins)

                mean_trajectory = mean_trajectory / N_samples
                file.create_dataset('mean_trajectory', data=mean_trajectory)

                file.close()
                print(f'Wrote data to file {output_path}.')
        return transition_probability_grid_TAMS, probability_density, quadrant_samples
Esempio n. 13
0
    def monte_carlo_run(self,
                        sigma_grid,
                        N_particles,
                        freq=1000,
                        geom_stopping=False,
                        output_path=None,
                        listbins=None):

        #transition_probability matrix
        transition_probability_grid_MC = np.zeros((len(sigma_grid)))

        #hitting time matrix, computing time matrix
        computing_time = np.zeros((len(sigma_grid)))
        number_timesteps = np.zeros((len(sigma_grid)))

        if listbins is not None:
            probability_density = np.zeros(
                [len(sigma_grid)] + [len(elem) - 1 for elem in listbins])

        job_start_time = tm.time()
        print("############################")
        print("Starting Monte Carlo job ...")
        print("############################\n\n")

        for s, sigma in enumerate(sigma_grid):
            print(
                'Parameters: \n noise strength sigma: {:.2f}. \n particles number: {:.1e} \n trajectory length: {} seconds. \n dt = {} seconds'
                .format(sigma, N_particles, self.t_trajectory, self.dt))

            sigma_start_time = tm.time()
            #covariance matrix and associated quadratic form

            if not geom_stopping:
                covariance_matrix, quad_form_target, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
                    self.force_matrix,
                    equilibrium_point=self.target_state,
                    noise=sigma)
                target_test = functools.partial(ellipsoid_fun.ellipsoid_test,
                                                quad_form=quad_form_target,
                                                level=level)
            else:
                geom_stopping_threshold = float(geom_stopping)
                print(
                    f'Using geometrical stopping with  threhsold : {geom_stopping_threshold: .2e}'
                )
                target_test = lambda v: np.linalg.norm(
                    v - self.target_state) < geom_stopping_threshold

            solver_scheme = functools.partial(
                self.solver_scheme_no_stop,
                dims=self.dims,
                force=self.force,
                time_array_length=self.time_array_length,
                dt=self.dt,
                noise_matrix=self.noise_matrix)

            for n in range(N_particles):
                vs = solver_scheme(0, self.initial_state, sigma=sigma)
                reached = np.any(np.apply_along_axis(target_test, 1, vs))
                transition_probability_grid_MC[s] += reached

                if reached and listbins is not None:
                    hist, bins = np.histogramdd(vs, bins=listbins)
                    probability_density[s] += hist

                number_timesteps[s] += self.time_array_length

                if n % freq == 0 and n != 0:
                    print(
                        f'Estimated probability: {transition_probability_grid_MC[s]}/{n+1} = {transition_probability_grid_MC[s]/(n+1):.2e}'
                    )
            transition_probability_grid_MC[
                s] = transition_probability_grid_MC[s] / N_particles
            sigma_end_time = tm.time()
            computing_time[s] += sigma_end_time - sigma_start_time
            print("Computing time: " + self.display_time(computing_time[s]))
            print(
                f"Computed transition probability: {transition_probability_grid_MC[s]:.3e} \n"
            )
        job_end_time = tm.time()
        job_elapsed_time = job_end_time - job_start_time
        print('Total computing time: ' + self.display_time(job_elapsed_time))

        if output_path != None:
            #write data to hdf5 file
            with h5py.File(output_path, 'a') as file:
                transition_proability_dataset_MC = file.create_dataset(
                    f'transition_probability_grid_MC',
                    data=transition_probability_grid_MC)

                transition_proability_dataset_MC.attrs[
                    'sigma_grid'] = sigma_grid

                transition_proability_dataset_MC.attrs[
                    'trajectory_length'] = self.t_trajectory
                transition_proability_dataset_MC.attrs['dt'] = self.dt

                transition_proability_dataset_MC.attrs[
                    'N_particles'] = N_particles

                transition_proability_dataset_MC.attrs[
                    'number_timesteps'] = number_timesteps
                transition_proability_dataset_MC.attrs[
                    'computing_time'] = computing_time

                if listbins is not None:
                    file.create_dataset('probability_density',
                                        data=probability_density)

                file.close()
                print(f'Wrote data to file {output_path}.')

        return transition_probability_grid_MC, computing_time, number_timesteps
Esempio n. 14
0
import functools
import ellipsoid_fun
import numpy as np

sigma = 3
covariance_matrix_initial, quad_form_initial, spectral_radius_initial, level_initial, bound_initial = ellipsoid_fun.ingredients_score_function(
    run.force_matrix, run.initial_state, sigma, run.noise_matrix)
initial_test = functools.partial(ellipsoid_fun.ellipsoid_test,
                                 quad_form=quad_form_initial,
                                 level=level_initial)

tested = np.apply_along_axis(initial_test, 2, traj)

indices_start = run.time_array_length - np.apply_along_axis(
    np.argmax, 1, tested[:, ::-1])
indices_end = indices_start + 1  #TOOOO CHANGE §§§
r = np.arange(run.time_array_length)

mask = (indices_start[:, None] <= r) & (r <= indices_end[:, None])

print(mask.shape)
samples = traj[mask, :]
print(traj[mask, :].shape)

import matplotlib.pyplot as plt

plt.scatter(samples[:, 0], samples[:, 1], label='last exit points')
plt.scatter(run.initial_state[0], run.initial_state[1], marker='o', s=20)
CS = ellipsoid_fun.draw_ellipsoid_2D(run.force_matrix,
                                     run.initial_state,
                                     noise=sigma,
Esempio n. 15
0
def check(time_array,
          force,
          initial_state,
          target_state,
          sigma1,
          noise_matrix,
          force_matrix,
          index_time=[0, 2],
          index_traj=[0, 2],
          label_time=['x', 'y'],
          label_traj=['x', 'y'],
          score_function=None,
          xmin=None,
          xmax=None,
          ymin=None,
          ymax=None,
          save_path=None):
    plt.figure()
    dim = len(initial_state)
    indices = [0, 2]
    index1, index2 = indices
    rest1, rest2 = [idx for idx in range(dim) if idx not in indices]

    covariance_matrix_target, quad_form_target, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
        force_matrix, target_state, sigma1, noise_matrix)

    solver_scheme = functools.partial(schemes.Euler_Maruyama_no_stop,
                                      force=force,
                                      time_array_length=len(time_array),
                                      dt=0.01,
                                      dims=4,
                                      noise_matrix=noise_matrix)

    proj = target_state
    lims = bound
    binslist = [None] * dim

    binslist[rest1] = np.array([proj[rest1]])
    binslist[rest2] = np.array([proj[rest2]])

    binslist[index1] = np.linspace(proj[index1] - lims, proj[index1] + lims,
                                   300)
    binslist[index2] = np.linspace(proj[index2] - lims, proj[index2] + lims,
                                   300)

    a0, a1, a2, a3 = binslist

    grids = list(np.meshgrid(a0, a1, a2, a3))

    ell = np.apply_along_axis(quad_form_target, 0, np.array(grids))
    ell = np.squeeze(ell)
    #plt.contour(np.squeeze(grids[index1]), np.squeeze(grids[index2]), ell, levels = [level], colors = ['black'], label = 'confidence ellipsoid')

    ell = ellipsoid_fun.get_ellipsoid_interior(target_state,
                                               quad_form_target,
                                               level,
                                               bound,
                                               nb_points=1e6,
                                               sample=200)
    for elem in ell:

        vs = solver_scheme(0, elem, 0)
        plt.plot(vs[:, index_traj[0]],
                 vs[:, index_traj[1]],
                 linewidth=0.1,
                 color='C1')
        plt.scatter(vs[-1, index_traj[0]],
                    vs[-1, index_traj[1]],
                    linewidth=0.1,
                    s=30,
                    color='red',
                    zorder=10)
        plt.scatter(vs[0, index_traj[0]],
                    vs[0, index_traj[1]],
                    linewidth=0.1,
                    s=7,
                    color='green',
                    zorder=10)

    #plt.title(r'$\sigma$'+' = {}'.format(sigma1))
    plt.xlabel(label_traj[0])
    plt.ylabel(label_traj[1])
    plt.ylim((ymin, ymax))
    plt.xlim(xmin, xmax)

    plt.scatter(initial_state[index_traj[0]],
                initial_state[index_traj[1]],
                marker='o',
                label='$X_A$',
                s=20,
                color='black',
                zorder=50)
    plt.scatter(target_state[index_traj[0]],
                target_state[index_traj[1]],
                marker='x',
                label='$X_B$',
                color='black',
                s=20,
                zorder=50)

    plt.legend()
    if save_path is not None:

        plt.savefig(save_path)
Esempio n. 16
0
def trajectory_plot_report1(time_array,
                            dt,
                            force,
                            initial_state,
                            target_state,
                            sigma1,
                            save_path,
                            force_matrix=None,
                            score_threshold=None,
                            score_function=None,
                            xmin=-10,
                            xmax=10,
                            ymin=-10,
                            ymax=15):
    """
    plots the trajectories of two particles starting in the initial states, for two values of noise strength sigma
    """

    fig, ax = plt.subplots(1, 1)
    x, y = np.linspace(xmin, xmax, 100), np.linspace(ymin, ymax, 100)
    xx, yy = np.meshgrid(x, y)

    #solve first trajectory
    vs = schemes.Euler_Maruyama_no_stop(0,
                                        initial_state,
                                        sigma1,
                                        dt=dt,
                                        dims=2,
                                        force=force,
                                        time_array_length=len(time_array))

    ax.plot(vs[:, 0], vs[:, 1], linewidth=0.03, color='C0')

    print(
        np.sum(vs[:, 0] * vs[:, 1]) /
        np.sqrt(np.sum(vs[:, 0] * vs[:, 0]) * np.sum(vs[:, 1] * vs[:, 1])))

    vs2 = schemes.Euler_Maruyama_no_stop(0,
                                         target_state,
                                         sigma1,
                                         dt=dt,
                                         dims=2,
                                         force=force,
                                         time_array_length=len(time_array))
    ax.plot(vs2[:, 0], vs2[:, 1], linewidth=0.03, color='C1')
    #ax.set_title(r'$\sigma$'+' = {}'.format(sigma1))
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_ylim((ymin, ymax))
    ax.set_xlim((xmin, xmax))

    plt.scatter(initial_state[0],
                initial_state[1],
                marker='o',
                color='black',
                s=40,
                zorder=10)
    plt.scatter(target_state[0],
                target_state[1],
                marker='x',
                color='black',
                s=40,
                zorder=10)

    #threshold and stopping criterion
    if score_function is not None:
        #score function threshold for the TAMS algorithm stopping criterion
        score_levels = np.apply_along_axis(score_function, 0,
                                           np.array([xx, yy]))
        ax.contour(xx,
                   yy,
                   score_levels,
                   levels=[1 - score_threshold],
                   zorder=10)

    if force_matrix is not None:
        ellipsoid_fun.draw_ellipsoid_2D(force_matrix,
                                        target_state,
                                        noise=sigma1,
                                        zorder=20)
        CS = ellipsoid_fun.draw_ellipsoid_2D(force_matrix,
                                             initial_state,
                                             noise=sigma1,
                                             zorder=20)
        CS.collections[0].set_label('confidence ellipsoid')

        covariance_matrix_target, quad_form_target, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
            force_matrix, initial_state, sigma1)
        target_test = functools.partial(ellipsoid_fun.ellipsoid_test,
                                        quad_form=quad_form_target,
                                        level=level)

        a = np.apply_along_axis(target_test, 1, vs)
        print(len(a[a == True]) / len(a))

        covariance_matrix_target, quad_form_target, spectral_radius, level, bound = ellipsoid_fun.ingredients_score_function(
            force_matrix, target_state, sigma1)
        target_test = functools.partial(ellipsoid_fun.ellipsoid_test,
                                        quad_form=quad_form_target,
                                        level=level)

        b = np.apply_along_axis(target_test, 1, vs2)
        print(len(b[b == True]) / len(b))

    plt.legend()
    plt.text(-0.2,
             1,
             '(a)',
             horizontalalignment='center',
             verticalalignment='center',
             transform=plt.gca().transAxes,
             fontsize=9)
    if save_path is not None:
        plt.savefig(save_path, bbox_inches='tight')
    plt.show()