@@ -158,10 +158,8 @@ fixedLassoInf <- function(x, y, beta, lambda, family=c("gaussian","binomial","co
158
158
159
159
# Approximate inverse covariance matrix for when (n < p) from lasso_Inference.R
160
160
161
- htheta <- InverseLinfty (hsigma , n , length(S ), verbose = FALSE , max.try = linesearch.try )
161
+ htheta = debiasing_matrix (hsigma , n , 1 : length(S ), verbose = FALSE , max_try = linesearch.try , warn_kkt = TRUE )
162
162
163
- # htheta <- InverseLinfty(hsigma, n, verbose=FALSE)
164
-
165
163
FS = rbind(diag(length(S )),matrix (0 ,pp - length(S ),length(S )))
166
164
GS = cbind(diag(length(S )),matrix (0 ,length(S ),pp - length(S )))
167
165
ithetasigma = (GS - (htheta %*% hsigma ))
@@ -269,137 +267,162 @@ fixedLasso.poly=
269
267
# ## Functions borrowed and slightly modified from lasso_inference.R
270
268
271
269
# # Approximates inverse covariance matrix theta
272
- InverseLinfty <- function (sigma , n , e , resol = 1.2 , mu = NULL , maxiter = 50 , threshold = 1e-2 , verbose = TRUE , max.try = 10 ) {
273
270
274
- max_active = max(50 , 2 * sqrt(n ))
271
+ debiasing_matrix = function (Sigma ,
272
+ nsample ,
273
+ rows ,
274
+ verbose = FALSE ,
275
+ mu = NULL , # starting value of mu
276
+ linesearch = TRUE , # do a linesearch?
277
+ resol = 1.2 , # multiplicative factor for linesearch
278
+ max_active = NULL , # how big can active set get?
279
+ max_try = 10 , # how many steps in linesearch?
280
+ warn_kkt = FALSE , # warn if KKT does not seem to be satisfied?
281
+ max_iter = 100 , # how many iterations for each optimization problem
282
+ kkt_tol = 1.e-4 , # tolerance for the KKT conditions
283
+ objective_tol = 1.e-4 # tolerance for relative decrease in objective
284
+ ) {
285
+
286
+
287
+ if (is.null(max_active )) {
288
+ max_active = max(50 , 0.3 * nsample )
289
+ }
290
+
291
+ p = nrow(Sigma );
292
+ M = matrix (0 , length(rows ), p );
275
293
276
- isgiven <- 1 ;
277
- if (is.null(mu )){
278
- isgiven <- 0 ;
294
+ if (is.null(mu )) {
295
+ mu = (1 / sqrt(nsample )) * qnorm(1 - (0.1 / (p ^ 2 )))
279
296
}
280
-
281
- p <- nrow(sigma );
282
- M <- matrix (0 , e , p );
297
+
283
298
xperc = 0 ;
284
299
xp = round(p / 10 );
285
- for (i in 1 : e ) {
286
- if ((i %% xp )== 0 ){
300
+ idx = 1 ;
301
+ for (row in rows ) {
302
+
303
+ if ((idx %% xp )== 0 ){
287
304
xperc = xperc + 10 ;
288
305
if (verbose ) {
289
306
print(paste(xperc ," % done" ,sep = " " )); }
290
307
}
291
- if (isgiven == 0 ){
292
- mu <- (1 / sqrt(n )) * qnorm(1 - (0.1 / (p ^ 2 )));
293
- }
294
- mu.stop <- 0 ;
295
- try.no <- 1 ;
296
- incr <- 0 ;
297
308
298
- output = NULL
309
+ output = debiasing_row(Sigma ,
310
+ row ,
311
+ mu ,
312
+ linesearch = linesearch ,
313
+ resol = resol ,
314
+ max_active = max_active ,
315
+ max_try = max_try ,
316
+ warn_kkt = FALSE ,
317
+ max_iter = max_iter ,
318
+ kkt_tol = kkt_tol ,
319
+ objective_tol = objective_tol )
320
+
321
+ if (warn_kkt && (! output $ kkt_check )) {
322
+ warning(" Solution for row of M does not seem to be feasible" )
323
+ }
324
+
325
+ M [idx ,] = output $ soln ;
326
+ idx = idx + 1 ;
327
+ }
328
+ return (M )
329
+ }
299
330
300
- last.beta = NULL
331
+ debiasing_row = function (Sigma ,
332
+ row ,
333
+ mu ,
334
+ linesearch = TRUE , # do a linesearch?
335
+ resol = 1.2 , # multiplicative factor for linesearch
336
+ max_active = NULL , # how big can active set get?
337
+ max_try = 10 , # how many steps in linesearch?
338
+ warn_kkt = FALSE , # warn if KKT does not seem to be satisfied?
339
+ max_iter = 100 , # how many iterations for each optimization problem
340
+ kkt_tol = 1.e-4 , # tolerance for the KKT conditions
341
+ objective_tol = 1.e-4 # tolerance for relative decrease in objective
342
+ ) {
301
343
302
- while (( mu.stop != 1 ) && ( try.no < max.try ) ){
344
+ p = nrow( Sigma )
303
345
304
- output <- InverseLinftyOneRow(sigma , i , mu , maxiter = maxiter , soln_result = output , max_active = max_active ) # uses a warm start
305
- beta <- output $ soln
346
+ if (is.null(max_active )) {
347
+ max_active = nrow(Sigma )
348
+ }
306
349
307
- iter <- output $ iter
350
+ # Initialize variables
308
351
309
- if (isgiven == 1 ) {
310
- mu.stop <- 1
311
- }
312
- else {
313
- if (try.no == 1 ){
314
- if (iter == (maxiter + 1 )){
315
- incr <- 1 ;
316
- mu <- mu * resol ;
317
- } else {
318
- incr <- 0 ;
319
- mu <- mu / resol ;
320
- }
321
- }
322
- if (try.no > 1 ){
323
- if ((incr == 1 )&& (iter == (maxiter + 1 ))){
324
- mu <- mu * resol ;
325
- }
326
- if ((incr == 1 )&& (iter < (maxiter + 1 ))){
327
- mu.stop <- 1 ;
328
- }
329
- if ((incr == 0 )&& (iter < (maxiter + 1 ))){
330
- mu <- mu / resol ;
331
- }
332
- if ((incr == 0 ) && (iter == (maxiter + 1 ))){
333
- mu <- mu * resol ;
334
- beta <- last.beta ;
335
- mu.stop <- 1 ;
336
- }
337
- }
338
- if (output $ max_active_check ) {
339
- mu.stop <- 1 ;
340
- beta <- last.beta ;
341
- }
342
- }
343
- try.no <- try.no + 1
344
- last.beta <- beta
345
- }
346
- M [i ,] <- beta ;
347
- }
348
- return (M )
349
- }
352
+ soln = rep(0 , p )
350
353
354
+ ever_active = rep(0 , p )
355
+ ever_active [1 ] = row # 1-based
356
+ ever_active = as.integer(ever_active )
357
+ nactive = as.integer(1 )
351
358
352
- InverseLinftyOneRow <- function (Sigma , i , mu , maxiter = 50 , soln_result = NULL , kkt_tol = 1.e-6 , objective_tol = 1.e-6 ,
353
- use_QP = TRUE , max_active = NULL ) {
359
+ linear_func = rep(0 , p )
360
+ linear_func [row ] = - 1
361
+ linear_func = as.numeric(linear_func )
362
+ gradient = 1 . * linear_func
354
363
355
- # If soln_result is not Null, it is used as a warm start.
356
- # It should be a list
357
- # with entries "soln", "gradient", "ever_active", "nactive"
364
+ counter_idx = 1 ;
365
+ incr = 0 ;
358
366
359
- p = nrow( Sigma )
367
+ last_output = NULL
360
368
361
- if (is.null(max_active )) {
362
- max_active = 50 # arbitrary?
363
- }
369
+ while (counter_idx < max_try ) {
364
370
365
- if (is.null(soln_result )) {
366
- soln = rep(0 , p )
367
- ever_active = rep(0 , p )
368
- ever_active [1 ] = i # 1-based
369
- ever_active = as.integer(ever_active )
370
- nactive = as.integer(1 )
371
- if (use_QP ) {
372
- linear_func = rep(0 , p )
373
- linear_func [i ] = - 1
374
- linear_func = as.numeric(linear_func )
375
- gradient = 1 . * linear_func
376
- } else {
377
- gradient = rep(0 , p )
378
- }
379
- }
380
- else {
381
- soln = soln_result $ soln
382
- gradient = soln_result $ gradient
383
- ever_active = as.integer(soln_result $ ever_active )
384
- nactive = as.integer(soln_result $ nactive )
385
- if (use_QP ) {
386
- linear_func = soln_result $ linear_func
387
- }
388
- }
371
+ result = solve_QP(Sigma , mu , max_iter , soln , linear_func , gradient , ever_active , nactive , kkt_tol , objective_tol , max_active )
389
372
390
- if (use_QP ) {
391
- result = solve_QP(Sigma , mu , maxiter , soln , linear_func , gradient , ever_active , nactive , kkt_tol , objective_tol , max_active )
392
- } else {
393
- result = find_one_row_debiasingM(Sigma , i , mu , maxiter , soln , gradient , ever_active , nactive , kkt_tol , objective_tol , max_active ) # C function uses 1-based indexing for active set
394
- }
373
+ iter = result $ iter
374
+
375
+ # Logic for whether we should continue the line search
376
+
377
+ if (! linesearch ) {
378
+ break
379
+ }
380
+
381
+ if (counter_idx == 1 ){
382
+ if (iter == (max_iter + 1 )){
383
+ incr = 1 ; # was the original problem feasible? 1 if not
384
+ } else {
385
+ incr = 0 ; # original problem was feasible
386
+ }
387
+ }
388
+
389
+ if (incr == 1 ) { # trying to find a feasible point
390
+ if ((iter < (max_iter + 1 )) && (counter_idx > 1 )) {
391
+ break ; # we've found a feasible point and solved the problem
392
+ }
393
+ mu = mu * resol ;
394
+ } else { # trying to drop the bound parameter further
395
+ if ((iter == (max_iter + 1 )) && (counter_idx > 1 )) {
396
+ result = last_output ; # problem seems infeasible because we didn't solve it
397
+ break ; # so we revert to previously found solution
398
+ }
399
+ mu = mu / resol ;
400
+ }
401
+
402
+ # If the active set has grown to a certain size
403
+ # then we stop, presuming problem has become
404
+ # infeasible.
405
+
406
+ # We revert to the previous solution
407
+
408
+ if (result $ max_active_check ) {
409
+ result = last_output ;
410
+ break ;
411
+ }
412
+
413
+ counter_idx = counter_idx + 1
414
+ last_output = list (soln = result $ soln ,
415
+ kkt_check = result $ kkt_check )
416
+ }
395
417
396
418
# Check feasibility
397
419
398
- if (! result $ kkt_check ) {
420
+ if (warn_kkt && ( ! result $ kkt_check ) ) {
399
421
warning(" Solution for row of M does not seem to be feasible" )
400
422
}
401
423
402
- return (result )
424
+ return (list (soln = result $ soln ,
425
+ kkt_check = result $ kkt_check ))
403
426
404
427
}
405
428
0 commit comments