From b79d003d20d2d8e5bf375bbd0ecdabe95e1c395d Mon Sep 17 00:00:00 2001 From: Alessandro Daducci Date: Fri, 1 Jun 2018 11:57:48 +0200 Subject: [PATCH 1/5] If a lambda=0, do not compute corresponding prox --- commit/solvers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/commit/solvers.py b/commit/solvers.py index 54869300..28bcf149 100755 --- a/commit/solvers.py +++ b/commit/solvers.py @@ -168,7 +168,7 @@ def regularisation2omegaprox(regularisation): sizeIC = regularisation.get('sizeIC') if lambdaIC == 0.0: omegaIC = lambda x: 0.0 - proxIC = lambda x: non_negativity(x, startIC, sizeIC) + proxIC = lambda x: x elif normIC == norm2: omegaIC = lambda x: lambdaIC * np.linalg.norm(x[startIC:sizeIC]) proxIC = lambda x: projection_onto_l2_ball(x, lambdaIC, startIC, sizeIC) @@ -205,7 +205,7 @@ def regularisation2omegaprox(regularisation): sizeEC = regularisation.get('sizeEC') if lambdaEC == 0.0: omegaEC = lambda x: 0.0 - proxEC = lambda x: non_negativity(x, startEC, sizeEC) + proxEC = lambda x: x elif normEC == norm2: omegaEC = lambda x: lambdaEC * np.linalg.norm(x[startEC:sizeEC]) proxEC = lambda x: projection_onto_l2_ball(x, lambdaEC, startEC, sizeEC) @@ -223,7 +223,7 @@ def regularisation2omegaprox(regularisation): sizeISO = regularisation.get('sizeISO') if lambdaISO == 0.0: omegaISO = lambda x: 0.0 - proxISO = lambda x: non_negativity(x, startISO, sizeISO) + proxISO = lambda x: x elif normISO == norm2: omegaISO = lambda x: lambdaISO * np.linalg.norm(x[startISO:sizeISO]) proxISO = lambda x: projection_onto_l2_ball(x, lambdaISO, startISO, sizeISO) From ebff2b6b4f8cb1635c57cef26bff42605272834c Mon Sep 17 00:00:00 2001 From: Alessandro Daducci Date: Fri, 1 Jun 2018 11:59:17 +0200 Subject: [PATCH 2/5] Fix indices of ranges --- commit/proximals.pyx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/commit/proximals.pyx b/commit/proximals.pyx index f2554b21..58bc6784 100644 --- a/commit/proximals.pyx +++ b/commit/proximals.pyx @@ -22,7 +22,7 @@ cpdef non_negativity(np.ndarray[np.float64_t] x, int compartment_start, int comp np.ndarray[np.float64_t] v size_t i v = x.copy() - for i in range(compartment_start, compartment_size): + for i in range(compartment_start, compartment_start+compartment_size): if v[i] < 0.0: v[i] = 0.0 return v @@ -36,7 +36,7 @@ cpdef soft_thresholding(np.ndarray[np.float64_t] x, double lam, int compartment_ np.ndarray[np.float64_t] v size_t i v = x.copy() - for i in range(compartment_start, compartment_size): + for i in range(compartment_start, compartment_start+compartment_size): if v[i] <= lam: v[i] = 0.0 else: @@ -53,9 +53,9 @@ cpdef projection_onto_l2_ball(np.ndarray[np.float64_t] x, double lam, int compar np.ndarray[np.float64_t] v size_t i v = x.copy() - xn = sqrt(sum(v[compartment_start:compartment_size]**2)) + xn = sqrt(sum(v[compartment_start:(compartment_start+compartment_size)]**2)) if xn > lam: - for i in range(compartment_start, compartment_size): + for i in range(compartment_start, compartment_start+compartment_size): v[i] = v[i]/xn*lam return v From e162f9e3ce76a8a94ae54fad77dc653fb3a1ac9e Mon Sep 17 00:00:00 2001 From: Alessandro Daducci Date: Fri, 1 Jun 2018 12:07:28 +0200 Subject: [PATCH 3/5] Fix l2-norm bug --- commit/proximals.pyx | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/commit/proximals.pyx b/commit/proximals.pyx index 58bc6784..a4f50c71 100644 --- a/commit/proximals.pyx +++ b/commit/proximals.pyx @@ -66,17 +66,14 @@ cpdef omega_group_sparsity(np.ndarray[np.float64_t] v, np.ndarray[object] subtre """ cdef: int nG = weight.size - size_t k, i - double xn, tmp = 0.0 + size_t k + double tmp = 0.0 if lam != 0: if n == 2: for k in range(nG): idx = subtree[k] - xn = 0.0 - for i in idx: - xn += v[i]*v[i] - tmp += weight[k] * sqrt( xn ) + tmp += weight[k] * sqrt( sum(v[idx]**2) ) elif n == np.Inf: for k in range(nG): idx = subtree[k] @@ -92,7 +89,7 @@ cpdef prox_group_sparsity( np.ndarray[np.float64_t] x, np.ndarray[object] subtre np.ndarray[np.float64_t] v int nG = weight.size, N, rho size_t k, i - double r, xn, theta + double r, xn v = x.copy() v[v<0] = 0.0 @@ -111,10 +108,7 @@ cpdef prox_group_sparsity( np.ndarray[np.float64_t] x, np.ndarray[object] subtre if n == 2: for k in range(nG): idx = subtree[k] - xn = 0.0 - for i in idx: - xn += v[i]*v[i] - xn = sqrt(xn) + xn = sqrt( sum(v[idx]**2) ) r = weight[k] * lam if xn > r: r = (xn-r)/xn From 7070cff7332b1a17536a990fd39b025506707102 Mon Sep 17 00:00:00 2001 From: Alessandro Daducci Date: Fri, 1 Jun 2018 13:34:59 +0200 Subject: [PATCH 4/5] Removed brackets as suggested by @matteofrigo --- commit/proximals.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commit/proximals.pyx b/commit/proximals.pyx index a4f50c71..46760470 100644 --- a/commit/proximals.pyx +++ b/commit/proximals.pyx @@ -53,7 +53,7 @@ cpdef projection_onto_l2_ball(np.ndarray[np.float64_t] x, double lam, int compar np.ndarray[np.float64_t] v size_t i v = x.copy() - xn = sqrt(sum(v[compartment_start:(compartment_start+compartment_size)]**2)) + xn = sqrt(sum(v[compartment_start:compartment_start+compartment_size]**2)) if xn > lam: for i in range(compartment_start, compartment_start+compartment_size): v[i] = v[i]/xn*lam From 1b69c3f6c0026e981a284cc324f3a5fd246f7fb5 Mon Sep 17 00:00:00 2001 From: Alessandro Daducci Date: Fri, 1 Jun 2018 13:46:38 +0200 Subject: [PATCH 5/5] Added decorators suggested by @matteofrigo --- commit/proximals.pyx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/commit/proximals.pyx b/commit/proximals.pyx index 46760470..bfa148e0 100644 --- a/commit/proximals.pyx +++ b/commit/proximals.pyx @@ -1,3 +1,5 @@ +#!python +#cython: boundscheck=False, wraparound=False """ Author: Matteo Frigo - lts5 @ EPFL and Dep. of CS @ Univ. of Verona @@ -10,9 +12,6 @@ cimport numpy as np from math import sqrt import sys -@cython.boundscheck(False) -@cython.wraparound(False) -@cython.profile(False) cpdef non_negativity(np.ndarray[np.float64_t] x, int compartment_start, int compartment_size): """ @@ -27,6 +26,7 @@ cpdef non_negativity(np.ndarray[np.float64_t] x, int compartment_start, int comp v[i] = 0.0 return v + cpdef soft_thresholding(np.ndarray[np.float64_t] x, double lam, int compartment_start, int compartment_size) : """ Proximal of L1 norm @@ -43,6 +43,7 @@ cpdef soft_thresholding(np.ndarray[np.float64_t] x, double lam, int compartment_ v[i] -= lam return v + cpdef projection_onto_l2_ball(np.ndarray[np.float64_t] x, double lam, int compartment_start, int compartment_size) : """ Proximal of L2 norm @@ -59,6 +60,7 @@ cpdef projection_onto_l2_ball(np.ndarray[np.float64_t] x, double lam, int compar v[i] = v[i]/xn*lam return v + cpdef omega_group_sparsity(np.ndarray[np.float64_t] v, np.ndarray[object] subtree, np.ndarray[np.float64_t] weight, double lam, double n) : """ References: @@ -80,6 +82,7 @@ cpdef omega_group_sparsity(np.ndarray[np.float64_t] v, np.ndarray[object] subtre tmp += weight[k] * max( v[idx] ) return lam*tmp + cpdef prox_group_sparsity( np.ndarray[np.float64_t] x, np.ndarray[object] subtree, np.ndarray[np.float64_t] weight, double lam, double n ) : """ References: @@ -87,7 +90,7 @@ cpdef prox_group_sparsity( np.ndarray[np.float64_t] x, np.ndarray[object] subtre """ cdef: np.ndarray[np.float64_t] v - int nG = weight.size, N, rho + int nG = weight.size size_t k, i double r, xn