//  [python]
def test_relative_weights(visualize=False):
    n_gmms = 2
    dimension = 2

    gmm_ellipse = GmmObstacle(n_gmms=n_gmms)
    gmm_ellipse._gmm = mixture.GaussianMixture(n_components=n_gmms)
    gmm_ellipse._gmm.means_ = np.zeros((n_gmms, dimension))
    gmm_ellipse._gmm.means_[0, :] = [3.0, 0]
    gmm_ellipse._gmm.means_[1, :] = [0, 3.0]

    gmm_ellipse._gmm.covariances_ = np.zeros((n_gmms, dimension, dimension))
    gmm_ellipse._gmm.covariances_[0, :, :] = [[1.0, 0], [0, 3.5]]
    gmm_ellipse._gmm.covariances_[1, :, :] = [[3.5, 0], [0, 1.0]]

    gmm_ellipse._gmm.precisions_cholesky_ = np.zeros((n_gmms, dimension, dimension))
    for ii in range(n_gmms):
        gmm_ellipse._gmm.precisions_cholesky_[ii, :, :] = LA.pinv(
            gmm_ellipse._gmm.covariances_[ii, :, :]
        )
    gmm_ellipse._gmm.weights_ = 0.5 * np.ones(n_gmms)
    gmm_ellipse.evaluate_hirarchy_and_reference_points()

    position = np.array([4, -4])
    gmm_ellipse.evaluate_axes_length_and_direction()
    gmm_ellipse.evaluate_gamma_weights(position=position)

    position = np.array([0, 0])
    gmm_ellipse.evaluate_gamma_weights(position=position)
    assert np.isclose(
        np.sum(gmm_ellipse.relative_weights), 1
    ), "Weights not summing up to one"
    assert (
        gmm_ellipse.relative_weights[0] == gmm_ellipse.relative_weights[1]
    ), "Weights not equal inbetween."

    position = np.array([2, -6])
    gmm_ellipse.evaluate_gamma_weights(position=position)
    assert np.isclose(
        np.sum(gmm_ellipse.relative_weights), 1
    ), "Weights not summing up to one"
    assert (
        gmm_ellipse.relative_weights[0] > gmm_ellipse.relative_weights[1]
    ), "Weights of closer ellipse should be higher."

    # Check which one is root => adapt test slightly
    ind_roots = gmm_ellipse.gmm_index_graph.get_root_indices()
    if ind_roots[0] == 0:
        ind_child = 1
        position = np.array([6, -6])
    else:
        ind_child = 0
        position = np.array([-6, 6])

    gmm_ellipse.evaluate_gamma_weights(position=position)
    assert np.isclose(
        np.sum(gmm_ellipse.relative_weights), 1
    ), "Weights not summing up to one"
    assert np.isclose(
        gmm_ellipse.relative_weights[ind_child], 0
    ), "Weight in parent shadow is not 0."

    if visualize:
        n_resolution = 50
        x_lim = [-8, 8]
        y_lim = [-8, 8]

        nx = ny = n_resolution
        x_vals, y_vals = np.meshgrid(
            np.linspace(x_lim[0], x_lim[1], nx),
            np.linspace(y_lim[0], y_lim[1], ny),
        )

        fig, axs = plt.subplots(1, 2, figsize=(15, 6))
        # levels = np.linspace(0.01, 1., 20 + 1)
        levels = np.linspace(1e-5, 1.0 + 1e-5, 40 + 1)
        cmap = "YlGn"

        positions = np.vstack((x_vals.reshape(1, -1), y_vals.reshape(1, -1)))
        weights = np.zeros((positions.shape[1], gmm_ellipse.n_gmms))

        print("Start loop")
        for it_gmm in range(gmm_ellipse.n_gmms):
            for ii in range(positions.shape[1]):
                gmm_ellipse.evaluate_gamma_weights(position=positions[:, ii])
                weights[ii, :] = gmm_ellipse.relative_weights

            cs0 = axs[it_gmm].contourf(
                x_vals,
                y_vals,
                weights[:, it_gmm].reshape(x_vals.shape),
                levels=levels,
                cmap=cmap,
            )
            axs[it_gmm].set_title(f"Gamma Obstacle {it_gmm}")

            gmm_ellipse.plot_obstacle(ax=axs[it_gmm], alpha_obstacle=0.0)
            delta_pos = [0.1, 0.1]
            axs[it_gmm].text(
                gmm_ellipse.get_center_position(it_gmm)[0] + delta_pos[0],
                gmm_ellipse.get_center_position(it_gmm)[1] + delta_pos[1],
                s=(f"{it_gmm}"),
                fontsize="large",
                fontweight="bold",
            )

        print(f"roots = {gmm_ellipse.gmm_index_graph.get_root_indices()}")

        for ax in axs:
            ax.set_aspect("equal", adjustable="box")
            ax.set_xlim(x_lim)
            ax.set_ylim(x_lim)
            ax.grid()

        plt.colorbar(cs0, ax=axs)