Skip to main content

BallP

Struct BallP 

Source
pub struct BallP<'a, T = f64> { /* private fields */ }
Expand description

An $\ell_p$ ball, that is, $$B_p^r = \{ x \in R^n : \Vert x \Vert_p \leq r \}$$ or a translated ball $$B_p^{x_c, r} = \{ x \in \mathbb{R}^n : \Vert x - x_c \Vert_p \leq r \},$$ with $1 < p < \infty$.

§Projection problem

Given a vector $x$, projection onto the ball means solving

$$\Pi_{B_p^r}(x) = \mathrm{argmin}_{z \in B_p^r} \frac{1}{2}\Vert z - x \Vert_2^2.$$

If $x$ already belongs to the ball, the projection is $x$ itself. Otherwise, the projection lies on the boundary of the ball.

§Numerical method

For general $1 < p < \infty$, the projection does not admit a simple closed-form expression. This implementation computes it numerically using the optimality conditions of the constrained problem.

For a ball centered at the origin, the projection is characterized by

$$z_i = \operatorname{sign}(x_i),u_i(\lambda),$$

where each scalar $u_i(\lambda) \geq 0$ solves

$$u_i + \lambda p,u_i^{p-1} = |x_i|,$$

and the Lagrange multiplier $\lambda \geq 0$ is chosen so that the projected vector satisfies the feasibility condition $|z|_p = r.$

The implementation uses:

  • an outer bisection loop to determine the multiplier $\lambda$,
  • an inner safeguarded Newton method to solve the scalar nonlinear equation for each coordinate.

The Newton iteration is combined with bracketing and a bisection fallback, which improves robustness.

§Translated balls

If the ball has a center $x_c$, projection is performed by translating the input vector to the origin, projecting onto the origin-centered ball, and translating the result back:

$$\Pi_{B_p^{x_c, r}}(x) = x_c + \Pi_{B_p^r}(x - x_c).$$

§Convexity

Since this module assumes p > 1.0, every BallP is convex, and therefore Constraint::project computes a unique Euclidean projection.

§Examples

Project onto the unit (\ell_p)-ball centered at the origin:

use optimization_engine::constraints::{BallP, Constraint};

let ball = BallP::new(None, 1.0, 1.5, 1e-10, 100);
let mut x = vec![3.0, -1.0, 2.0];
ball.project(&mut x).unwrap();

Project onto a translated (\ell_p)-ball:

use optimization_engine::constraints::{BallP, Constraint};

let center = vec![1.0, 1.0, 1.0];
let ball = BallP::new(Some(&center), 2.0, 3.0, 1e-10, 100);
let mut x = vec![4.0, -1.0, 2.0];
ball.project(&mut x).unwrap();

§Notes

  • The projection is with respect to the Euclidean norm
  • The implementation is intended for general finite $p > 1.0$. If you need to project on a $\Vert{}\cdot{}\Vert_1$-ball or an $\Vert{}\cdot{}\Vert_\infty$-ball, use the implementations in Ball1 and BallInf.
  • Do not use this struct to project on a Euclidean ball; the implementation in Ball2 is more efficient
  • The quality and speed of the computation depend on the chosen numerical tolerance and iteration limit.

Implementations§

Source§

impl<'a, T: Float> BallP<'a, T>

Source

pub fn new( center: Option<&'a [T]>, radius: T, p: T, tolerance: T, max_iter: usize, ) -> Self

Construct a new l_p ball with given center, radius, and exponent.

  • center: if None, the ball is centered at the origin
  • radius: radius of the ball
  • p: norm exponent, must satisfy p > 1.0 and be finite
  • tolerance: tolerance for the numerical solvers
  • max_iter: maximum number of iterations for the numerical solvers

Trait Implementations§

Source§

impl<'a, T: Clone> Clone for BallP<'a, T>

Source§

fn clone(&self) -> BallP<'a, T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a, T: Float> Constraint<T> for BallP<'a, T>

Source§

fn project(&self, x: &mut [T]) -> FunctionCallResult

Projection onto the set, that is, Read more
Source§

fn is_convex(&self) -> bool

Returns true if and only if the set is convex
Source§

impl<'a, T: Copy> Copy for BallP<'a, T>

Auto Trait Implementations§

§

impl<'a, T> Freeze for BallP<'a, T>
where T: Freeze,

§

impl<'a, T> RefUnwindSafe for BallP<'a, T>
where T: RefUnwindSafe,

§

impl<'a, T> Send for BallP<'a, T>
where T: Send + Sync,

§

impl<'a, T> Sync for BallP<'a, T>
where T: Sync,

§

impl<'a, T> Unpin for BallP<'a, T>
where T: Unpin,

§

impl<'a, T> UnsafeUnpin for BallP<'a, T>
where T: UnsafeUnpin,

§

impl<'a, T> UnwindSafe for BallP<'a, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.