1+ compound = 1
2+ nz = 10 * compound
3+ options = ROSolverOptions (ν = 1.0 , β = 1e16 , ϵa = 1e-6 , ϵr = 1e-6 , verbose = 10 )
4+ bpdn, bpdn_nls, sol = bpdn_model (compound)
5+ bpdn2, bpdn_nls2, sol2 = bpdn_model (compound, bounds = true )
6+ λ = norm (grad (bpdn, zeros (bpdn. meta. nvar)), Inf ) / 10
7+
8+ for (mod, mod_name) ∈ ((x -> x, " exact" ), (LSR1Model, " lsr1" ), (LBFGSModel, " lbfgs" ))
9+ for (h, h_name) ∈ ((NormL0 (λ), " l0" ), (NormL1 (λ), " l1" ), (IndBallL0 (10 * compound), " B0" ))
10+ for solver_sym ∈ (:R2 , :TR )
11+ solver_sym == :TR && mod_name == " exact" && continue
12+ solver_sym == :TR && h_name == " B0" && continue # FIXME
13+ solver_name = string (solver_sym)
14+ solver = eval (solver_sym)
15+ @testset " bpdn-$(mod_name) -$(solver_name) -$(h_name) " begin
16+ x0 = zeros (bpdn. meta. nvar)
17+ p = randperm (bpdn. meta. nvar)[1 : nz]
18+ x0[p[1 : nz]] = sign .(randn (nz)) # initial guess with nz nonzeros (necessary for h = B0)
19+ args = solver_sym == :R2 ? () : (NormLinf (1.0 ),)
20+ out = solver (mod (bpdn), h, args... , options, x0 = x0)
21+ @test typeof (out. solution) == typeof (bpdn. meta. x0)
22+ @test length (out. solution) == bpdn. meta. nvar
23+ @test typeof (out. dual_feas) == eltype (out. solution)
24+ @test out. status == :first_order
25+ end
26+ end
27+ end
28+ end
29+
30+ for (mod, mod_name) ∈ ((SpectralGradientModel, " spg" ),)
31+ # ((DiagonalPSBModel, "psb"),(DiagonalAndreiModel, "andrei")) work but do not always terminate
32+ for (h, h_name) ∈ ((NormL0 (λ), " l0" ), (NormL1 (λ), " l1" )) # , (IndBallL0(10 * compound), "B0"))
33+ @testset " bpdn-$(mod_name) -TRDH-$(h_name) " begin
34+ x0 = zeros (bpdn. meta. nvar)
35+ p = randperm (bpdn. meta. nvar)[1 : nz]
36+ # x0[p[1:nz]] = sign.(randn(nz)) # initial guess with nz nonzeros (necessary for h = B0)
37+ χ = NormLinf (1.0 )
38+ out = TRDH (mod (bpdn), h, χ, options, x0 = x0)
39+ @test typeof (out. solution) == typeof (bpdn. meta. x0)
40+ @test length (out. solution) == bpdn. meta. nvar
41+ @test typeof (out. dual_feas) == eltype (out. solution)
42+ @test out. status == :first_order
43+ end
44+ end
45+ end
46+
47+ # TR with h = L1 and χ = L2 is a special case
48+ for (mod, mod_name) ∈ ((LSR1Model, " lsr1" ), (LBFGSModel, " lbfgs" ))
49+ for (h, h_name) ∈ ((NormL1 (λ), " l1" ),)
50+ @testset " bpdn-$(mod_name) -TR-$(h_name) " begin
51+ x0 = zeros (bpdn. meta. nvar)
52+ p = randperm (bpdn. meta. nvar)[1 : nz]
53+ x0[p[1 : nz]] = sign .(randn (nz)) # initial guess with nz nonzeros (necessary for h = B0)
54+ TR_out = TR (mod (bpdn), h, NormL2 (1.0 ), options, x0 = x0)
55+ @test typeof (TR_out. solution) == typeof (bpdn. meta. x0)
56+ @test length (TR_out. solution) == bpdn. meta. nvar
57+ @test typeof (TR_out. dual_feas) == eltype (TR_out. solution)
58+ @test TR_out. status == :first_order
59+ end
60+ end
61+ end
62+
63+ for (h, h_name) ∈ ((NormL0 (λ), " l0" ), (NormL1 (λ), " l1" ), (IndBallL0 (10 * compound), " B0" ))
64+ for solver_sym ∈ (:LM , :LMTR )
65+ solver_name = string (solver_sym)
66+ solver = eval (solver_sym)
67+ solver_sym == :LMTR && h_name == " B0" && continue # FIXME
68+ @testset " bpdn-ls-$(solver_name) -$(h_name) " begin
69+ x0 = zeros (bpdn_nls. meta. nvar)
70+ p = randperm (bpdn_nls. meta. nvar)[1 : nz]
71+ x0[p[1 : nz]] = sign .(randn (nz)) # initial guess with nz nonzeros (necessary for h = B0)
72+ args = solver_sym == :LM ? () : (NormLinf (1.0 ),)
73+ out = solver (bpdn_nls, h, args... , options, x0 = x0)
74+ @test typeof (out. solution) == typeof (bpdn. meta. x0)
75+ @test length (out. solution) == bpdn. meta. nvar
76+ @test typeof (out. dual_feas) == eltype (out. solution)
77+ @test out. status == :first_order
78+ end
79+ end
80+ end
81+
82+ # LMTR with h = L1 and χ = L2 is a special case
83+ for (h, h_name) ∈ ((NormL1 (λ), " l1" ),)
84+ @testset " bpdn-ls-LMTR-$(h_name) " begin
85+ x0 = zeros (bpdn_nls. meta. nvar)
86+ p = randperm (bpdn_nls. meta. nvar)[1 : nz]
87+ x0[p[1 : nz]] = sign .(randn (nz)) # initial guess with nz nonzeros (necessary for h = B0)
88+ LMTR_out = LMTR (bpdn_nls, h, NormL2 (1.0 ), options, x0 = x0)
89+ @test typeof (LMTR_out. solution) == typeof (bpdn_nls. meta. x0)
90+ @test length (LMTR_out. solution) == bpdn_nls. meta. nvar
91+ @test typeof (LMTR_out. solver_specific[:Fhist ]) == typeof (LMTR_out. solution)
92+ @test typeof (LMTR_out. solver_specific[:Hhist ]) == typeof (LMTR_out. solution)
93+ @test typeof (LMTR_out. solver_specific[:SubsolverCounter ]) == Array{Int, 1 }
94+ @test typeof (LMTR_out. dual_feas) == eltype (LMTR_out. solution)
95+ @test length (LMTR_out. solver_specific[:Fhist ]) == length (LMTR_out. solver_specific[:Hhist ])
96+ @test length (LMTR_out. solver_specific[:Fhist ]) ==
97+ length (LMTR_out. solver_specific[:SubsolverCounter ])
98+ @test length (LMTR_out. solver_specific[:Fhist ]) == length (LMTR_out. solver_specific[:NLSGradHist ])
99+ @test LMTR_out. solver_specific[:NLSGradHist ][end ] ==
100+ bpdn_nls. counters. neval_jprod_residual + bpdn_nls. counters. neval_jtprod_residual - 1
101+ @test obj (bpdn_nls, LMTR_out. solution) == LMTR_out. solver_specific[:Fhist ][end ]
102+ @test h (LMTR_out. solution) == LMTR_out. solver_specific[:Hhist ][end ]
103+ @test LMTR_out. status == :first_order
104+ end
105+ end
106+
107+ R2N_R2DH (args... ; kwargs... ) = R2N (args... ; subsolver = R2DHSolver, kwargs... )
108+ for (mod, mod_name) ∈ (
109+ (SpectralGradientModel, " spg" ),
110+ (DiagonalPSBModel, " psb" ),
111+ (LSR1Model, " lsr1" ),
112+ (LBFGSModel, " lbfgs" ),
113+ )
114+ for (h, h_name) ∈ ((NormL0 (λ), " l0" ), (NormL1 (λ), " l1" ))
115+ for solver_sym ∈ (:R2DH , :R2N , :R2N_R2DH )
116+ solver_sym ∈ (:R2N , :R2N_R2DH ) && mod_name ∈ (" spg" , " psb" ) && continue
117+ solver_sym == :R2DH && mod_name != " spg" && continue
118+ solver_sym == :R2N_R2DH && h_name == " l1" && continue # this test seems to fail because s seems to be equal to zeros within the subsolver
119+ solver_name = string (solver_sym)
120+ solver = eval (solver_sym)
121+ @testset " bpdn-$(mod_name) -$(solver_name) -$(h_name) " begin
122+ x0 = zeros (bpdn. meta. nvar)
123+ out = solver (mod (bpdn), h, options, x0 = x0)
124+ @test typeof (out. solution) == typeof (bpdn. meta. x0)
125+ @test length (out. solution) == bpdn. meta. nvar
126+ @test typeof (out. dual_feas) == eltype (out. solution)
127+ @test out. status == :first_order
128+ end
129+ end
130+ end
131+ end
0 commit comments