def test_extended_kalman_filter(self):
        for i, (is_f_linear, is_g_linear) in enumerate(
                zip([False, True, False], [True, False, False])):
            # tester différentes dimensions pour les espaces
            for j, (state_dim, output_dim, input_dim) in enumerate(
                    zip([1, 4, 3], [1, 3, 4], [0, 0, 0])):
                # tester différentes tailles
                for k, T in enumerate([1, 10]):
                    ssm = StateSpaceModel(is_f_linear=is_f_linear,
                                          is_g_linear=is_g_linear,
                                          state_dim=state_dim,
                                          output_dim=output_dim,
                                          input_dim=input_dim)
                    ssm.draw_sample(T=T)
                    ssm.kalman_filtering(is_extended=True)
                    self.assertEqual(len(getattr(ssm, 'filtered_state_means')),
                                     T)
                    self.assertEqual(
                        len(getattr(ssm, 'filtered_state_covariance')), T)

                    # verifier que les moyennes et covariances estimmées ont les bonnes dimensions
                    for i in range(0, T):
                        xFilter0 = ssm.filtered_state_means[i][0]
                        xFilter1 = ssm.filtered_state_means[i][1]
                        PFilter0 = ssm.filtered_state_covariance[i][0]
                        PFilter1 = ssm.filtered_state_covariance[i][1]

                        self.assertEqual(
                            xFilter0.size, ssm.state_dim,
                            'mean vector must have state_dim dimension')
                        self.assertEqual(
                            xFilter1.size, ssm.state_dim,
                            'mean vector must have state_dim dimension')
                        self.assertEqual(
                            PFilter0.shape, (ssm.state_dim, ssm.state_dim),
                            'cov matrix must have state_dim dimension')
                        self.assertEqual(
                            PFilter1.shape, (ssm.state_dim, ssm.state_dim),
                            'cov matrix must have state_dim dimension')
                        # check that matrices are definite positive
                        self.assertTrue(
                            utils.is_pos_def(PFilter0),
                            'filtered covariance matrix must be positive definite'
                        )
                        self.assertTrue(
                            utils.is_pos_def(PFilter1),
                            'filtered covariance matrix must be positive definite'
                        )
def two_subspace_min(X, func, gfunc, hess_func, delta, hyper_parameters=None, epsilon=1e-10, max_epoch=10000):
    """ 二维子空间极小化方法 求解TR子问题,注意此方法不是迭代方法

    Args:
        X ([np.array]): [Input X]
        func ([回调函数]): [目标函数]
        gfunc ([回调函数]): [目标函数的一阶导函数]
        hess_func ([回调函数]): [目标函数的Hessian矩阵]
        delta ([float]): [TR子问题约束中的delta]
        hyper_parameters: (Dic): 超参数,超参数中包括:
            epsilon ([float], optional): [解决浮点数相减不精确的问题,用于判等]. Defaults to 1e-10.
            max_epoch (int, optional): [description]. Defaults to 1000.

    Returns:
        [type]: [description]
    """
    k = 0

    I = np.identity(len(X))
    G = hess_func(X)
    
    # 先判断G是否正定
    if not is_pos_def(G): # G非正定的情况,通过取 v \in {-lambda_n , -2 * lambda_n},使得G正定
        values, _vector = np.linalg.eig(G)
        values = sorted(values)
        lambda_n = values[0]
        # v = random.uniform(-lambda_n, -2 * lambda_n)
        v = - 3 / 2 * lambda_n
        G = G + v * I
    
    inv_G = np.linalg.inv(G) 
    g = gfunc(X)
    abs_g = np.linalg.norm(g)
    inv_G_g = inv_G @ g

    g_tilde = np.array([abs_g**2, g @ inv_G @ g], dtype=float)
    G_tilde = np.array(
        [[g @ G @ g, abs_g**2     ],
            [abs_g**2,  g @ inv_G @ g]],
            dtype=float)
    G_overline = 2 * np.array(
        [[abs_g**2, g @ inv_G @ g],
            [g @ inv_G @ g, np.linalg.norm(inv_G_g) ** 2]],
            dtype=float)
    inv_G_tilde = np.linalg.inv(G_tilde) 
    u_star = - inv_G_tilde @ g_tilde
    if 1/2 * (u_star @ G_overline @ u_star) <= delta ** 2:
        u = u_star

    else:
        def fun(x):
            input = - np.linalg.inv(G_tilde + x * G_overline) @ g_tilde
            return [1/2 * (input @ G_overline @ input) - delta ** 2]
        lambda_sol = optimize.root(fun, [0])
        lambda_ = float(lambda_sol.x)
        u = - np.linalg.inv(G_tilde + lambda_ * G_overline) @ g_tilde
    alpha = u[0]
    beta = u[1]
    d = alpha * g + beta * inv_G_g
    return d, k
def sorensen(X, func, gfunc, hess_func, delta, hyper_parameters=None,  v_0=1e-2, epsilon=1e-10, max_epoch=10000):
    """ sorensen求解TR子问题

    Args:
        X ([np.array]): [Input X]
        func ([回调函数]): [目标函数]
        gfunc ([回调函数]): [目标函数的一阶导函数]
        hess_func ([回调函数]): [目标函数的Hessian矩阵]
        delta ([float]): [TR子问题约束中的delta]
        hyper_parameters: (Dic): 超参数,超参数中包括:
            v_0 ([float]], optional): [v的初值]. Defaults to 1e-2.
            epsilon ([float], optional): [解决浮点数相减不精确的问题,用于判等]. Defaults to 1e-10.
            max_epoch (int, optional): [description]. Defaults to 1000.

    Returns:
        [type]: [description]
    """
    # 初始化
    k = 1
    v_k = v_0

    I = np.identity(len(X))
    G_org = hess_func(X)
    G = copy.deepcopy(G_org)
    # 先判断G是否正定

    if not is_pos_def(G): # G非正定的情况,通过取 v \in {-lambda_n , -2 * lambda_n},使得G正定
        values, _vector = np.linalg.eig(G)
        values = sorted(values)
        lambda_n = values[0]
        # v = random.uniform(-lambda_n, -2 * lambda_n)
        v_k = - 3 / 2 * lambda_n
        G = G + v_k * I
    
    # 和Hebden最大的区别就是在这cholesky分解,用cholesky分解,一是不用次次都求逆,节约了计算量;二是可以用分解出来的结果进行近似迭代
    L = np.linalg.cholesky(G)
    inv_L = np.linalg.inv(L) 
    inv_G = inv_L.T @ inv_L
    g = gfunc(X)
    
    d_v = - inv_G @ g
    if np.linalg.norm(d_v) < delta:
        return d_v, k

    label.step4
    
    # d_v = - inv_G @ g
    q_l = inv_L @ d_v
    abs_d_v = np.linalg.norm(d_v)
    phi_v = abs_d_v - delta 

    # 判断终止准则是否成立
    if abs(phi_v) <= epsilon:
        return d_v, k
    if k > max_epoch:
        raise Exception("使用sorensen方法求解TR子问题时,超过最大迭代次数:%d", max_epoch)

    # 更新v_k
    abs_d_v = np.linalg.norm(d_v)
    abs_q_l = np.linalg.norm(q_l)
    v_k = v_k + ((abs_d_v/abs_q_l) ** 2) * (abs_d_v - delta) / delta

    # 重新计算(G+vI)
    G = G_org + v_k * I
    L = np.linalg.cholesky(G)
    inv_L = np.linalg.inv(L) 

    inv_G = inv_L.T @ inv_L
    d_v = - inv_G @ g
    k = k + 1
    goto.step4
    def test_linear_kalman_methods(self):
        for i, (state_dim, output_dim,
                input_dim) in enumerate(zip([1, 4, 3], [1, 3, 4], [0, 0, 0])):
            # tester différentes tailles
            for j, T in enumerate([1, 10]):
                default_message = 'Parameters : T = ' + str(
                    T) + '. state_dim = ' + str(
                        state_dim) + '.  output_dim = ' + str(
                            output_dim) + '. input_dim = ' + str(input_dim)
                ssm = StateSpaceModel(is_f_linear=True,
                                      is_g_linear=True,
                                      state_dim=state_dim,
                                      output_dim=output_dim,
                                      input_dim=input_dim)
                ssm.draw_sample(T=T)
                ssm.kalman_smoothing(is_extended=False)
                self.assertEqual(len(getattr(ssm, 'filtered_state_means')), T)
                self.assertEqual(
                    len(getattr(ssm, 'filtered_state_covariance')), T)
                self.assertEqual(len(getattr(ssm, 'smoothed_state_means')), T)
                self.assertEqual(
                    len(getattr(ssm, 'smoothed_state_covariance')), T)

                # verifier que les moyennes et covariances estimmées ont les bonnes dimensions
                for i in range(0, T):
                    xFilter0 = ssm.filtered_state_means[i][0]
                    xFilter1 = ssm.filtered_state_means[i][1]
                    PFilter0 = ssm.filtered_state_covariance[i][0]
                    PFilter1 = ssm.filtered_state_covariance[i][1]

                    xSmooth = ssm.smoothed_state_means[i]
                    PSmooth = ssm.smoothed_state_covariance[T - 1 - i]

                    self.assertEqual(
                        xFilter0.size, ssm.state_dim,
                        'mean vector must have state_dim dimension')
                    self.assertEqual(
                        xFilter1.size, ssm.state_dim,
                        'mean vector must have state_dim dimension')
                    self.assertEqual(
                        PFilter0.shape, (ssm.state_dim, ssm.state_dim),
                        'cov matrix must have state_dim dimension')
                    self.assertEqual(
                        PFilter1.shape, (ssm.state_dim, ssm.state_dim),
                        'cov matrix must have state_dim dimension')
                    # check that matrices are definite positive
                    self.assertTrue(
                        utils.is_pos_def(PFilter0),
                        'filtered covariance matrix must be positive definite')
                    self.assertTrue(
                        utils.is_pos_def(PFilter1),
                        'filtered covariance matrix must be positive definite')

                    self.assertEqual(
                        xSmooth.size, ssm.state_dim,
                        'mean vector must have state_dim dimension')
                    self.assertEqual(
                        PSmooth.shape, (ssm.state_dim, ssm.state_dim),
                        'cov matrix must have state_dim dimension')
                    self.assertTrue(
                        utils.is_pos_def(PSmooth),
                        default_message + '. Smoothed covariance P_{T-' +
                        str(i) + '} matrix must be positive definite')
def hebden(X,
           func,
           gfunc,
           hess_func,
           delta,
           hyper_parameters=None,
           v_0=1e-2,
           epsilon=1e-10,
           max_epoch=1000):
    """ Hebden方法求解TR子问题

    Args:
        X ([np.array]): [Input X]
        func ([回调函数]): [目标函数]
        gfunc ([回调函数]): [目标函数的一阶导函数]
        hess_func ([回调函数]): [目标函数的Hessian矩阵]
        delta ([float]): [TR子问题约束中的delta]
        hyper_parameters: (Dic): 超参数,超参数中包括:
            v_0 ([float]], optional): [v的初值]. Defaults to 1e-2.
            epsilon ([float], optional): [解决浮点数相减不精确的问题,用于判等]. Defaults to 1e-10.
            max_epoch (int, optional): [description]. Defaults to 1000.

    Returns:
        [type]: [description]
    """
    # 初始化
    k = 1
    v_k = v_0

    I = np.identity(len(X))
    G_org = hess_func(X)
    G = copy.deepcopy(G_org)
    # 先判断G是否正定

    if not is_pos_def(
            G):  # G非正定的情况,通过取 v \in {-lambda_n , -2 * lambda_n},使得G正定
        values, _vector = np.linalg.eig(G)
        values = sorted(values)
        lambda_n = values[0]
        # v = random.uniform(-lambda_n, -2 * lambda_n)
        v_k = -3 / 2 * lambda_n
        G = G + v_k * I

    inv_G = np.linalg.inv(G)
    g = gfunc(X)
    d_v = -inv_G @ g

    if np.linalg.norm(d_v) < delta:
        return d_v, k

    label.step4
    abs_d_v = np.linalg.norm(d_v)
    d_v_prime = -inv_G @ d_v  # d_v的导数
    phi_v = abs_d_v - delta
    phi_v_prime = d_v @ d_v_prime / abs_d_v  # phi_v的导数
    # 判断终止准则是否成立
    if abs(phi_v) <= epsilon:
        return d_v, k
    if k > max_epoch:
        raise Exception("使用Hebden方法求解TR子问题时,超过最大迭代次数:%d", max_epoch)
    # return d_v, k

    # 更新v_k
    v_k = v_k - (phi_v + delta) * phi_v / (delta * phi_v_prime)
    # 重新计算(G+vI)
    G = G_org + v_k * I
    inv_G = np.linalg.inv(G)  # 求Hesse矩阵的逆
    d_v = -inv_G @ g
    k = k + 1
    goto.step4
Ejemplo n.º 6
0
uni_norm_error_list = []
uni_eig_error_list = []
lev_error_list = []
uni_CUR_error_list = []

# check for similar rows or columns
unique_rows, indices = np.unique(similarity_matrix, axis=0, return_index=True)
similarity_matrix_O = similarity_matrix[indices][:, indices]
# symmetrization
similarity_matrix = (similarity_matrix_O + similarity_matrix_O.T) / 2.0
id_count = len(similarity_matrix)
# eigenshift
# min_eig = np.min(np.linalg.eigvals(similarity_matrix))
# similarity_matrix = similarity_matrix - min_eig*np.eye(len(similarity_matrix))
# check if current matrix is PSD
print("is the current matrix PSD? ", is_pos_def(similarity_matrix))


# if filename == "rte":
# 	similarity_matrix = 1-similarity_matrix
# 	similarity_matrix_O = 1-similarity_matrix_O

################# uniform sampling #####################################
from Nystrom import simple_nystrom

for k in tqdm(range(10, id_count, 10)):
    error, _, _, _ = simple_nystrom(similarity_matrix, similarity_matrix_O, \
        k, runs=runs_, mode='eigI', normalize=norm_type, expand=expand_eigs,
        correction_mode=True)
    uni_eig_error_list.append(error)
    del _