def projection_cone_nosign(p, max_idx): """ Does not condition on sign! Create a callable that projects onto one of two cones, determined by which coordinate achieves the max in one step of forward stepwise. Parameters ---------- p : int Dimension. max_idx : int Index achieving the max. max_sign : [-1,1] Sign of achieved max. Returns ------- projection : callable A function to compute projection onto appropriate cone. Takes one argument of shape (p,). """ P_plus = rr.linf_epigraph(p-1) P_minus = rr.l1_epigraph_polar(p-1) def _projection(state): permuted_state = np.zeros_like(state) permuted_state[-1] = state[max_idx] permuted_state[:max_idx] = state[:max_idx] permuted_state[max_idx:-1] = state[(max_idx+1):] projected_state_plus = P_plus.cone_prox(permuted_state) projected_state_minus = P_minus.cone_prox(permuted_state) D_plus = np.linalg.norm(permuted_state - projected_state_plus) D_minus = np.linalg.norm(permuted_state - projected_state_minus) if D_plus < D_minus: projected_state = projected_state_plus else: projected_state = projected_state_minus new_state = np.zeros_like(state) new_state[max_idx] = projected_state[-1] new_state[:max_idx] = projected_state[:max_idx] new_state[(max_idx+1):] = projected_state[max_idx:-1] return new_state return _projection
def projection_cone(p, max_idx, max_sign): """ Create a callable that projects onto one of two cones, determined by which coordinate achieves the max in one step of forward stepwise. Parameters ---------- p : int Dimension. max_idx : int Index achieving the max. max_sign : [-1,1] Sign of achieved max. Returns ------- projection : callable A function to compute projection onto appropriate cone. Takes one argument of shape (p,). """ if max_sign > 0: P = rr.linf_epigraph(p-1) else: P = rr.l1_epigraph_polar(p-1) def _projection(state): permuted_state = np.zeros_like(state) permuted_state[-1] = state[max_idx] permuted_state[:max_idx] = state[:max_idx] permuted_state[max_idx:-1] = state[(max_idx+1):] projected_state = P.cone_prox(permuted_state) new_state = np.zeros_like(state) new_state[max_idx] = projected_state[-1] new_state[:max_idx] = projected_state[:max_idx] new_state[(max_idx+1):] = projected_state[max_idx:-1] return new_state return _projection