5.4.8. L2-ball#

For a given scalar \(\xi \ge 0\), the L2-ball is a convex constraint defined as

\[ \mathcal{C}_{L_2} = \big\{ {\bf w} \in \mathbb{R}^{N} \;|\; \|{\bf w}\|_2 \le \xi \big\}, \]

where \(\|{\bf w}\|_2 = \sqrt{w_1^2+\dots+w_N^2}\) is the L2-norm. The condition \(\xi \ge 0\) is required for this subset to be nonempty. The figure below shows how this constraint looks like in \(\mathbb{R}^{2}\) or in \(\mathbb{R}^{3}\).

L2-ball in 2D

L2-ball in 3D

5.4.8.1. Constrained optimization#

Optimizing a function \(J({\bf w})\) subject to the L2-ball constraint can be expressed as

\[ \operatorname*{minimize}_{\textbf{w}\in\mathbb{R}^N}\; J({\bf w}) \quad{\rm s.t.}\quad \|{\bf w}\|_2 \le \xi. \]

The figure below visualizes such an optimization problem in \(\mathbb{R}^{2}\).

../../_images/7517717c231d29adb8172c1f410c51c77bbe7d1e5d6c436aaa2c885e2ce6b00f.png

5.4.8.2. Orthogonal projection#

The projection of a point \({\bf u}\in\mathbb{R}^{N}\) onto the L2-ball is the (unique) solution to the following problem

\[ \operatorname*{minimize}_{{\bf w}\in\mathbb{R}^N}\;\; \|{\bf w}-{\bf u}\|^2 \quad{\rm s.t.}\quad \|{\bf w}\|_2 \le \xi. \]

The solution can be analytically computed as follows.

Projection onto the L2-ball

\[\begin{split} \mathcal{P}_{\mathcal{C}_{L_2}}({\bf u}) = \begin{cases} {\bf u} &\textrm{if $\|{\bf u}\|_2 \le \xi$}\\ {\bf u} \, \dfrac{\xi}{\|{\bf u}\|_2} &\textrm{otherwise} \end{cases} \end{split}\]

The next figure visualizes a point \({\bf u}\in \mathbb{R}^{2}\) (blue dot) along with its projection (red dot) onto this set.

../../_images/63bf0d3503b913e8d212f298dd3dbabc496e04909d70ec608c19071176f27ff4.png

5.4.8.3. Implementation#

The python implementation is given below.

def project_l2ball(u, bound):
    
    assert bound >= 0, "The bound must be non-negative"
    
    if np.linalg.norm(u) < 1e-16:
        p = np.zeros(u.shape)
    else:
        p = u * np.minimum(1, bound / np.linalg.norm(u))
        
    return p

Here is an example of use.

u = np.array([-1.2, 1.2])

p = project_l2ball(u, bound=1)