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
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 _