@@ -109,6 +109,20 @@ cdef inline floating Nh(floating x) nogil:
109109 return INFINITY # not - INFINITY
110110
111111
112+ @ cython.boundscheck (False )
113+ @ cython.wraparound (False )
114+ cdef floating fweighted_norm_w2(floating[:] w, floating[:] weights) nogil:
115+ cdef floating weighted_norm = 0.
116+ cdef int n_features = w.shape[0 ]
117+ cdef int j
118+
119+ for j in range (n_features):
120+ if weights[j] == INFINITY:
121+ continue
122+ weighted_norm += weights[j] * w[j] ** 2
123+ return weighted_norm
124+
125+
112126@ cython.boundscheck (False )
113127@ cython.wraparound (False )
114128@ cython.cdivision (True )
@@ -141,7 +155,7 @@ cdef floating primal_logreg(
141155@ cython.wraparound (False )
142156@ cython.cdivision (True )
143157cdef floating primal_lasso(
144- floating alpha, floating[:] R, floating[:] w,
158+ floating alpha, floating l1_ratio, floating [:] R, floating[:] w,
145159 floating[:] weights) nogil:
146160 cdef int n_samples = R.shape[0 ]
147161 cdef int n_features = w.shape[0 ]
@@ -152,24 +166,27 @@ cdef floating primal_lasso(
152166 for j in range (n_features):
153167 # avoid nan when weights[j] is INFINITY
154168 if w[j]:
155- p_obj += alpha * weights[j] * fabs(w[j])
169+ p_obj += alpha * weights[j] * (
170+ l1_ratio * fabs(w[j]) +
171+ 0.5 * (1. - l1_ratio) * w[j] ** 2 )
156172 return p_obj
157173
158174
159175cdef floating primal(
160- int pb, floating alpha, floating[:] R, floating[:] y,
176+ int pb, floating alpha, floating l1_ratio, floating [:] R, floating[:] y,
161177 floating[:] w, floating[:] weights) nogil:
162178 if pb == LASSO:
163- return primal_lasso(alpha, R, w, weights)
179+ return primal_lasso(alpha, l1_ratio, R, w, weights)
164180 else :
165181 return primal_logreg(alpha, R, y, w, weights)
166182
167183
168184@ cython.boundscheck (False )
169185@ cython.wraparound (False )
170186@ cython.cdivision (True )
171- cdef floating dual_lasso(int n_samples, floating norm_y2,
172- floating * theta, floating * y) nogil:
187+ cdef floating dual_enet(int n_samples, floating alpha, floating l1_ratio,
188+ floating norm_y2, floating norm_w2, floating * theta,
189+ floating * y) nogil:
173190 """ Theta must be feasible"""
174191 cdef int i
175192 cdef floating d_obj = 0.
@@ -178,6 +195,8 @@ cdef floating dual_lasso(int n_samples, floating norm_y2,
178195 d_obj -= (y[i] - n_samples * theta[i]) ** 2
179196 d_obj *= 0.5 / n_samples
180197 d_obj += norm_y2 / (2. * n_samples)
198+ if l1_ratio != 1.0 :
199+ d_obj -= 0.5 * alpha * (1 - l1_ratio) * norm_w2
181200 return d_obj
182201
183202
@@ -195,11 +214,10 @@ cdef floating dual_logreg(int n_samples, floating * theta,
195214 return d_obj
196215
197216
198- cdef floating dual(int pb, int n_samples, floating norm_y2,
199- floating * theta, floating * y) nogil:
200-
217+ cdef floating dual(int pb, int n_samples, floating alpha, floating l1_ratio,
218+ floating norm_y2, floating norm_w2, floating * theta, floating * y) nogil:
201219 if pb == LASSO:
202- return dual_lasso (n_samples, norm_y2, & theta[0 ], & y[0 ])
220+ return dual_enet (n_samples, alpha, l1_ratio, norm_y2, norm_w2 , & theta[0 ], & y[0 ])
203221 else :
204222 return dual_logreg(n_samples, & theta[0 ], & y[0 ])
205223
@@ -226,7 +244,6 @@ cdef void create_dual_pt(
226244@ cython.cdivision (True )
227245cdef int create_accel_pt(
228246 int pb, int n_samples, int epoch, int gap_freq,
229- floating alpha,
230247 floating * R, floating * out, floating * last_K_R, floating[:, :] U,
231248 floating[:, :] UtU, floating[:] onesK, floating[:] y):
232249
@@ -365,11 +382,11 @@ cpdef void compute_Xw(
365382@ cython.boundscheck (False )
366383@ cython.wraparound (False )
367384@ cython.cdivision (True )
368- cpdef floating dnorm_l1 (
369- bint is_sparse, floating[:] theta, floating[::1 , :] X,
385+ cpdef floating dnorm_enet (
386+ bint is_sparse, floating[:] theta, floating[:] w, floating[: :1 , :] X,
370387 floating[:] X_data, int [:] X_indices, int [:] X_indptr, int [:] skip,
371388 floating[:] X_mean, floating[:] weights, bint center,
372- bint positive) nogil:
389+ bint positive, floating alpha, floating l1_ratio ) nogil:
373390 """ compute norm(X[:, ~skip].T.dot(theta), ord=inf)"""
374391 cdef int n_samples = theta.shape[0 ]
375392 cdef int n_features = skip.shape[0 ]
@@ -399,6 +416,10 @@ cpdef floating dnorm_l1(
399416 else :
400417 Xj_theta = fdot(& n_samples, & theta[0 ], & inc, & X[0 , j], & inc)
401418
419+ # minus sign to consider the choice theta = y - Xw and not theta = Xw -y
420+ if l1_ratio != 1 :
421+ Xj_theta -= alpha * (1 - l1_ratio) * weights[j] * w[j]
422+
402423 if not positive:
403424 Xj_theta = fabs(Xj_theta)
404425 scal = max (scal, Xj_theta / weights[j])
@@ -409,14 +430,15 @@ cpdef floating dnorm_l1(
409430@ cython.wraparound (False )
410431@ cython.cdivision (True )
411432cdef void set_prios(
412- bint is_sparse, floating[:] theta, floating alpha,
433+ bint is_sparse, floating[:] theta, floating[:] w, floating alpha, floating l1_ratio ,
413434 floating[::1 , :] X, floating[:] X_data, int [:] X_indices, int [:] X_indptr,
414435 floating[:] norms_X_col, floating[:] weights, floating[:] prios,
415436 int [:] screened, floating radius, int * n_screened, bint positive) nogil:
416437 cdef int i, j, startptr, endptr
417438 cdef floating Xj_theta
418439 cdef int n_samples = theta.shape[0 ]
419440 cdef int n_features = prios.shape[0 ]
441+ cdef floating norms_X_col_j = 0.
420442
421443 # TODO we do not substract theta_sum, which seems to indicate that theta
422444 # is always centered...
@@ -433,11 +455,17 @@ cdef void set_prios(
433455 else :
434456 Xj_theta = fdot(& n_samples, & theta[0 ], & inc, & X[0 , j], & inc)
435457
458+ norms_X_col_j = norms_X_col[j]
459+ if l1_ratio != 1 :
460+ Xj_theta -= alpha * (1 - l1_ratio) * weights[j] * w[j]
461+
462+ norms_X_col_j = norms_X_col_j ** 2
463+ norms_X_col_j += sqrt(norms_X_col_j + alpha * (1 - l1_ratio) * weights[j])
436464
437465 if positive:
438- prios[j] = fabs(Xj_theta - alpha * weights[j]) / norms_X_col[j]
466+ prios[j] = fabs(Xj_theta - alpha * l1_ratio * weights[j]) / norms_X_col_j
439467 else :
440- prios[j] = (alpha * weights[j] - fabs(Xj_theta)) / norms_X_col[j]
468+ prios[j] = (alpha * l1_ratio * weights[j] - fabs(Xj_theta)) / norms_X_col_j
441469
442470 if prios[j] > radius:
443471 screened[j] = True
0 commit comments