def _update_beta_jac_bcd(X, y, beta, dbeta, dual_var, ddual_var, alpha, L, compute_jac=True): n_samples, n_features = X.shape non_zeros = np.where(L != 0)[0] for j in non_zeros: beta_old = beta[j] if compute_jac: dbeta_old = dbeta[j, :].copy() # compute derivatives zj = beta[j] + dual_var @ X[:, j] / (L[j] * n_samples) beta[j] = prox_elasticnet(zj, alpha[0] / L[j], alpha[1] / L[j]) if compute_jac: dzj = dbeta[j, :] + X[:, j] @ ddual_var / (L[j] * n_samples) dbeta[j:j+1, :] = (1 / (1 + alpha[1] / L[j])) * \ np.abs(np.sign(beta[j])) * dzj dbeta[j:j + 1, 0] -= (alpha[0] * np.sign(beta[j])) / L[j] / (1 + alpha[1] / L[j]) dbeta[j:j + 1, 1] -= (alpha[1] / L[j] * beta[j]) / (1 + alpha[1] / L[j]) # update residuals ddual_var[:, 0] -= X[:, j] * (dbeta[j, 0] - dbeta_old[0]) ddual_var[:, 1] -= X[:, j] * (dbeta[j, 1] - dbeta_old[1]) dual_var -= X[:, j] * (beta[j] - beta_old)
def _update_beta_jac_bcd_sparse(data, indptr, indices, y, n_samples, n_features, beta, dbeta, dual_var, ddual_var, alphas, L, compute_jac=True): non_zeros = np.where(L != 0)[0] for j in non_zeros: # get the j-st column of X in sparse format Xjs = data[indptr[j]:indptr[j + 1]] # get the non zero indices idx_nz = indices[indptr[j]:indptr[j + 1]] beta_old = beta[j] if compute_jac: dbeta_old = dbeta[j, :].copy() zj = beta[j] + dual_var[idx_nz] @ Xjs / (L[j] * n_samples) beta[j:j + 1] = prox_elasticnet(zj, alphas[0] / L[j], alphas[1] / L[j]) if compute_jac: dzj = dbeta[j, :] + Xjs @ ddual_var[idx_nz, :] / \ (L[j] * n_samples) dbeta[j:j+1, :] = (1 / (1 + alphas[1] / L[j])) * \ np.abs(np.sign(beta[j])) * dzj dbeta[j:j+1, 0] -= alphas[0] * \ np.sign(beta[j]) / L[j] / (1 + (alphas[1] / L[j])) dbeta[j:j + 1, 1] -= (alphas[1] / L[j] * beta[j]) / (1 + (alphas[1] / L[j])) # update residuals ddual_var[idx_nz, 0] -= Xjs * (dbeta[j, 0] - dbeta_old[0]) ddual_var[idx_nz, 1] -= Xjs * (dbeta[j, 1] - dbeta_old[1]) dual_var[idx_nz] -= Xjs * (beta[j] - beta_old)