def pga_oracle(D, DtY, xOracle, xhat, alphathat=None): # todo cur_diver = DBL_MAX cur_patch_error = DBL_MAX Dr, Dc = D.shape DtYr, DtYc = DtY.shape T = np.zeros((1, Dc)) for i in range(Dc): T[i] = i k = min(max(math.sqrt(Dc) + 1, Dr / 10 + 1), Dc) D_T = np.zeros((Dr, k)) alpha = np.zeros((k, DtYc)) D_TtY = np.zeros((k, DtYc)) # cur_xhat = np.zeros_like(xhat) actual_alpha = np.zeros((k, DtYc)) cur_spar = 0 for cur_spar in range(k): atom_index = 0 tmp_D_T = D_T[:Dr, :cur_spar + 1] init_alpha = alpha[:cur_spar + 1, :np.size(alpha, 1)] cur_D_TtY = D_TtY[:cur_spar + 1, :DtYc] # tmp_alpha = np.zeros_like(init_alpha) for cur_atom in range(Dc - cur_spar): tmp_D_T[:Dr, cur_spar] = D[:Dr, cur_atom] tmp_alpha = init_alpha D_TtY[cur_spar, :DtYc] = DtY[T[cur_atom], :DtYc] diver_error = newton(cur_D_TtY, tmp_D_T, tmp_alpha, NB_ITERATIONS_ITER) if diver_error < cur_diver: cur_diver = diver_error alpha[:cur_spar + 1, :np.size(alpha, 1)] = tmp_alpha atom_index = T[cur_atom] D_T[:Dr, cur_spar] = D[:Dr, atom_index] D_TtY[cur_spar, :DtYc] = DtY[atom_index, :DtYc] T[atom_index], T[Dc - 1 - cur_spar] = D[Dc - 1 - cur_spar], T[atom_index] cur_xhat = D_T[:Dr, :cur_spar + 1] * alpha[:cur_spar + 1, :np.size(alpha, 1)] cur_xhat = np.exp(cur_xhat) patch_error = np.linalg.norm((cur_xhat - xOracle), 'fro') if patch_error >= cur_patch_error: break cur_patch_error = patch_error actual_alpha[:cur_spar + 1, :np.size(actual_alpha, 1)] = alpha[:cur_spar + 1, :np.size(alpha, 1)] xhat = cur_xhat tmp_D_T = D_T[:Dr, :cur_spar] final_alpha = actual_alpha[:cur_spar, :np.size(actual_alpha, 1)] cur_D_TtY = D_TtY[:cur_spar, :DtYc] newton(cur_D_TtY, tmp_D_T, final_alpha, NB_ITERATIONS_FINAL) xhat = tmp_D_T * final_alpha xhat = np.exp(xhat) alphahat = np.zeros((Dc, DtYc)) for i in range(cur_spar): alphahat[T[Dc - i - 1], :DtYc] = final_alpha[i, :DtYc] return cur_diver
def pga(D, DTY, k, xhat, alphahat=None): # todo cur_diver = DBL_MAX Dr, Dc = D.shape DtYr, DtYc = DTY.shape T = np.zeros((1, Dc)) for i in range(Dc): T[i] = i D_T = np.zeros((Dr, k)) alpha = np.zeros((k, DtYc)) D_TtY = np.zeros((k, DtYc)) for cur_spar in range(k): atom_index = 0 tmp_D_T = D[:Dr, :cur_spar + 1] init_alpha = alpha[:cur_spar + 1, :DtYc] cur_D_TtY = D_TtY[:cur_spar + 1, :DtYc] # tmp_alpha = np.zeros_like(init_alpha) for cur_atom in range(Dc - cur_spar): tmp_D_T[:Dr, cur_spar] = D[:Dr, T[cur_atom]] tmp_alpha = init_alpha cur_D_TtY[cur_spar, :DtYc] = DTY[T[cur_atom], :DtYc] diver_error = newton(cur_D_TtY, tmp_D_T, tmp_alpha, NB_ITERATIONS_ITER) if diver_error < cur_diver: cur_diver = diver_error alpha[:cur_spar + 1, :DtYc] = tmp_alpha atom_index = T[cur_atom] D_T[:Dr, cur_spar] = D[:Dr, atom_index] D_TtY[cur_spar, :DtYc] = DTY[atom_index, :DtYc] T[atom_index], T[Dc - 1 - cur_spar] = T[Dc - 1 - cur_spar], T[atom_index] alpha = newton(D_TtY, D_T, alpha, NB_ITERATIONS_FINAL) xhat = D_T * alpha xhat = np.exp(xhat) alphahat = np.zeros((Dc, DtYc)) for i in range(k): alphahat[T[Dc - i - 1], :DtYc] = alpha[i, :DtYc] return cur_diver