QPALM main
Proximal Augmented Lagrangian method for Quadratic Programs
Loading...
Searching...
No Matches
qpalm_fiface.F90
Go to the documentation of this file.
1! THIS VERSION: 25/04/2022 AT 13:45 GMT
2! Nick Gould (nick.gould@stfc.ac.uk)
3
4!> @defgroup qpalm-fortran-grp Fortran Interface
5!! This is the Fortran interface of the QPALM solver.
6
7!> Fortran interface to the C package QPALM, with the aim to
8!> minimize the objective function
9!>
10!> 1/2 x' H x + g' x + f
11!>
12!> subject to the constraints
13!>
14!> cl <= A x <= cu,
15!>
16!> where any of the bounds cl, cu may be infinite, See the comments to
17!> the interface block, qpalm_fortran, below for details on how to call the
18!> subroutine, and check qpalm_fortran_example.f90 for an example of use
19!>
20!> @ingroup qpalm-fortran-grp
21
23
24 USE iso_c_binding, ONLY : c_float, c_double, c_int, c_long, c_char, &
25 c_int32_t, c_int64_t
26
27 IMPLICIT NONE
28
29 PUBLIC
30
31 !-------------------------------------------
32 ! I n r e g e r a n d r e a l k i n d s
33 !-------------------------------------------
34
35 ! integer and real kinds for problem data
36
37#ifdef QPALM_FORTRAN_64BIT_INDICES
38 INTEGER, PARAMETER :: integer_kind = c_long
39#else
40 INTEGER, PARAMETER :: integer_kind = c_int
41#endif
42
43#ifdef QPALM_FORTRAN_SINGLE_PRECISION
44 INTEGER, PARAMETER :: real_kind = c_float
45#else
46 INTEGER, PARAMETER :: real_kind = c_double
47#endif
48
49 ! integer and real kinds for qpalm-related data
50
51#ifdef LADEL_64BIT_INDICES
52 INTEGER, PARAMETER :: integer_kind_qpalm = c_int64_t
53#else
54 INTEGER, PARAMETER :: integer_kind_qpalm = c_int32_t
55#endif
56
57#ifdef LADEL_SINGLE_PRECISION
58 INTEGER, PARAMETER :: real_kind_qpalm = c_float
59#else
60 INTEGER, PARAMETER :: real_kind_qpalm = c_double
61#endif
62
63 !----------------------
64 ! P a r a m e t e r s
65 !----------------------
66
67 REAL ( kind = real_kind_qpalm ), PARAMETER :: ten = 10.0_real_kind_qpalm
68
69 !-------------------------------------------------
70 ! D e r i v e d t y p e d e f i n i t i o n s
71 !-------------------------------------------------
72
73 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
74 !> settings derived type with component defaults bound to C’s QPALMSettings
75 !> @see @ref QPALMSettings
76 !> @ingroup qpalm-fortran-grp
77 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
78
79 TYPE, BIND( C ), PUBLIC :: QPALM_settings
80
81 !> maximum number of iterations: > 0
82
83 INTEGER ( KIND = integer_kind_qpalm ) :: max_iter = 10000
84
85 !> maximum number of iterations per subproblem: > 0
86
87 INTEGER ( KIND = integer_kind_qpalm ) :: inner_max_iter = 100
88
89 !> absolute convergence tolerance: >= 0,
90 !> either eps_abs or eps_rel must be > 0
91
92 REAL ( kind = real_kind_qpalm ) :: eps_abs = ten ** ( - 4 )
93
94 !> relative convergence tolerance: >= 0,
95 !> either eps_abs or eps_rel must be > 0
96
97 REAL ( kind = real_kind_qpalm ) :: eps_rel = ten ** ( - 4 )
98
99 !> intermediate absolute convergence tolerance: >= 0,
100 !> either eps_abs_in or eps_rel_in must be > 0
101
102 REAL ( kind = real_kind_qpalm ) :: eps_abs_in = 1.0_real_kind_qpalm
103
104 !> intermediate relative convergence tolerance: >= 0,
105 !> either eps_abs_in or eps_rel_in must be > 0
106
107 REAL ( kind = real_kind_qpalm ) :: eps_rel_in = 1.0_real_kind_qpalm
108
109 !> tolerance scaling factor: 0 < rho < 1
110
111 REAL ( kind = real_kind_qpalm ) :: rho = 0.1_real_kind_qpalm
112
113 !> primal infeasibility tolerance: >= 0
114
115 REAL ( kind = real_kind_qpalm ) :: eps_prim_inf = ten ** ( - 5 )
116
117 !> dual infeasibility tolerance: >= 0
118
119 REAL ( kind = real_kind_qpalm ) :: eps_dual_inf = ten ** ( - 5 )
120
121 !> penalty update criterion parameter: <= 1
122
123 REAL ( kind = real_kind_qpalm ) :: theta = 0.25_real_kind_qpalm
124
125 !> penalty update factor: > 1
126
127 REAL ( kind = real_kind_qpalm ) :: delta = 100.0_real_kind_qpalm
128
129 !> penalty factor cap: > 0
130
131 REAL ( kind = real_kind_qpalm ) :: sigma_max = ten ** 9
132
133 !> initial penalty parameter (guideline): > 0
134
135 REAL ( kind = real_kind_qpalm ) :: sigma_init = 20.0_real_kind_qpalm
136
137 !> boolean, use proximal method of multipliers or not: in {0,1}
138
139 INTEGER ( KIND = integer_kind_qpalm ) :: proximal = 1
140
141 !> initial proximal penalty parameter: > 0
142
143 REAL ( kind = real_kind_qpalm ) :: gamma_init = ten ** 7
144
145 !> proximal penalty update factor: >= 1
146
147 REAL ( kind = real_kind_qpalm ) :: gamma_upd = 10.0_real_kind_qpalm
148
149 !> proximal penalty parameter cap: >= gamma_init
150
151 REAL ( kind = real_kind_qpalm ) :: gamma_max = ten ** 7
152
153 !> scaling iterations, if 0 then scaling is disabled: >= 0
154
155 INTEGER ( KIND = integer_kind_qpalm ) :: scaling = 10
156
157 !> boolean, indicates whether the QP is nonconvex: in {0,1}
158
159 INTEGER ( KIND = integer_kind_qpalm ) :: nonconvex = 0
160
161 !> boolean, write out progress: in {0,1}
162
163 INTEGER ( KIND = integer_kind_qpalm ) :: verbose = 1
164
165 !> frequency of printing: > 0
166
167 INTEGER ( KIND = integer_kind_qpalm ) :: print_iter = 1
168
169 !> boolean, warm start: in {0,1}
170
171 INTEGER ( KIND = integer_kind_qpalm ) :: warm_start = 0
172
173 !> frequency of performing a complete Cholesky factorization: > 0
174
175 INTEGER ( KIND = integer_kind_qpalm ) :: reset_newton_iter = 10000
176
177 !> boolean, enable termination based on dual objective (useful
178 !> in branch and bound): in {0,1}
179
180 INTEGER ( KIND = integer_kind_qpalm ) :: enable_dual_termination = 0
181
182 !> termination value for the dual objective (useful in branch and bound)
183
184 REAL ( kind = real_kind_qpalm ) :: dual_objective_limit = ten ** 20
185
186 !> time limit: > 0
187
188 REAL ( kind = real_kind_qpalm ) :: time_limit = ten ** 20
189
190 !> ordering method for factorization:
191 !> 0 No ordering is performed during the symbolic part of the factorization
192 !> 1 Ordering method during the symbolic part of the factorization
193 !> 2 The ordering was computed previously and is already stored
194
195 INTEGER ( KIND = integer_kind_qpalm ) :: ordering = 1
196
197 !> factorize KKT or Schur complement:
198 !> 0 factorize the kkt system
199 !> 1 factorize the Schur complement
200 !> 2 select automatically between kkt system and schur complemen
201
202 INTEGER ( KIND = integer_kind_qpalm ) :: factorization_method = 2
203
204 !> maximum rank for the sparse factorization update
205
206 INTEGER ( KIND = integer_kind_qpalm ) :: max_rank_update = 160
207
208 !> maximum rank (relative to n+m) for the factorization update
209
210 REAL ( kind = real_kind_qpalm ) :: &
211 max_rank_update_fraction = 0.1_real_kind_qpalm
212
213 END TYPE qpalm_settings
214
215 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
216 !> info derived type with component defaults bound to C’s QPALMInfo
217 !> @see @ref QPALMInfo
218 !> @ingroup qpalm-fortran-grp
219 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
220
221 TYPE, BIND( C ), PUBLIC :: QPALM_info
222
223 !> number of iterations taken
224
225 INTEGER ( KIND = integer_kind_qpalm ) :: iter
226
227 !> number of outer iterations (i.e. dual updates)
228
229 INTEGER ( KIND = integer_kind_qpalm ) :: iter_out
230
231 !> status string, e.g. 'solved'
232
233 CHARACTER ( KIND = C_CHAR ), DIMENSION( 31 ) :: status
234
235 !> status as integer:
236 !> * 1 the problem is solved to optimality given the specified tolerances
237 !> * 2 the problem has a dual objective that is higher than the specified bound
238 !> * 0 an error has occured (this error should automatically be printed)
239 !> * -2 termination due to reaching the maximum number of iterations
240 !> * -3 the problem is primal infeasible
241 !> * -4 the problem is dual infeasible
242 !> * -5 the problem’s runtime has exceeded the specified time limit
243 !> * -10 the problem is unsolved. Only setup function has been called
244
245 INTEGER ( KIND = integer_kind_qpalm ) :: status_val
246
247 !> norm of primal residual
248
249 REAL ( kind = real_kind_qpalm ) :: pri_res_norm
250
251 !> norm of dual residual
252
253 REAL ( kind = real_kind_qpalm ) :: dua_res_norm
254
255 !> norm of intermediate dual residual (minus proximal term)
256
257 REAL ( kind = real_kind_qpalm ) :: dua2_res_norm
258
259 !> objective function value
260
261 REAL ( kind = real_kind_qpalm ) :: objective
262
263 !> dual objective function value (= NaN if enable_dual_termination is false)
264
265 REAL ( kind = real_kind_qpalm ) :: dual_objective
266
267 !> time taken for setup phase (seconds)
268
269 REAL ( kind = real_kind_qpalm ) :: setup_time
270
271 !> time taken for solve phase (seconds)
272
273 REAL ( kind = real_kind_qpalm ) :: solve_time
274
275 !> total time (seconds)
276
277 REAL ( kind = real_kind_qpalm ) :: run_time
278
279 END TYPE qpalm_info
280
281 !---------------------------------
282 ! I n t e r f a c e B l o c k s
283 !---------------------------------
284
285 INTERFACE
286 !> Invoke the QPALM solver.
287 !> @see @ref qpalm_solve
288 !> @ingroup qpalm-fortran-grp
289 SUBROUTINE qpalm_fortran( n, m, hne, hrow, hptr, hval, g, f, &
290 ane, arow, aptr, aval, cl, cu, settings, &
291 x, y, info ) bind( C, NAME = 'qpalm_fortran_c' )
292
293 ! dummy arguments
294
296
297 !> the number of variables
298
299 INTEGER ( KIND = integer_kind ), INTENT( IN ), VALUE :: n
300
301 !> the number of constraints
302
303 INTEGER ( KIND = integer_kind ), INTENT( IN ), VALUE :: m
304
305 !> the number of nonzeros in the upper triangular part of the objective
306 !> Hessian, H
307
308 INTEGER ( KIND = integer_kind ), INTENT( IN ), VALUE :: hne
309
310 !> the (1-based) row indices of the upper triangular part of H when H is
311 !> stored by columns. Columns are stored consecutively, with column i directly
312 !> before column i+1, for i = 1,...,n-1
313
314 INTEGER ( KIND = integer_kind ), INTENT( IN ), DIMENSION( hne ) :: hrow
315
316 !> the (1-based) pointers to the first entry in each column of the upper
317 !> triangular part of H, i = 1,...,n, as well as the pointer to one position
318 !> beyond the last entry, stored in hptr(n+1)
319
320 INTEGER ( KIND = integer_kind ), INTENT( IN ), DIMENSION( n + 1 ) :: hptr
321
322 !> the values of the nonzeros in the upper triangular part of H, in the same
323 !> order as the row indices stored in hrow
324
325 REAL ( kind = real_kind ), INTENT( IN ), DIMENSION( hne ) :: hval
326
327 !> the vector of values of the linear term, g, in the objective
328
329 REAL ( kind = real_kind ), INTENT( IN ), DIMENSION( n ) :: g
330
331 !> the value of the constant term, f, in the objective
332
333 REAL ( kind = real_kind ), INTENT( IN ), VALUE :: f
334
335 !> the number of nonzeros in the constraint Jacobian, A
336
337 INTEGER ( KIND = integer_kind ), INTENT( IN ), VALUE :: ane
338
339 !> the (1-based) row indices of the A when A is stored by columns. Columns
340 !> are stored consecutively, with column i directly before column i+1, for
341 !> i = 1,...,n-1
342
343 INTEGER ( KIND = integer_kind ), INTENT( IN ), DIMENSION( ane ) :: arow
344
345 !> the (1-based) pointers to the first entry in each column of A, i = 1,...,n,
346 !> as well as the pointer to one position beyond the last entry, stored in
347 !> aptr(n+1)
348
349 INTEGER ( KIND = integer_kind ), INTENT( IN ), DIMENSION( n + 1 ) :: aptr
350
351 !> the values of the nonzeros in A, in the same order as the row indices
352 !> stored in arow
353
354 REAL ( kind = real_kind ), INTENT( IN ), DIMENSION( ane ) :: aval
355
356 !> the vector of lower constraint bounds, cl. An infinite bound should
357 !> be given a value no larger than - QPALM_INFTY = -10^20
358
359 REAL ( kind = real_kind ), INTENT( IN ), DIMENSION( m ) :: cl
360
361 !> the vector of upper constraint bounds, cu. An infinite bound should
362 !> be given a value no smaller than QPALM_INFTY = 10^20
363
364 REAL ( kind = real_kind ), INTENT( IN ), DIMENSION( m ) :: cu
365
366 !> parameters that are used to control the optimization. See QPALM_settings
367 !> above for details
368
369 TYPE ( qpalm_settings ), INTENT( IN ), VALUE :: settings
370
371 !> the values of the best primal variables, x, on successful termination
372
373 REAL ( kind = real_kind ), INTENT( OUT ), DIMENSION( n ) :: x
374
375 !> the values of the best dual variables, y, on successful termination
376
377 REAL ( kind = real_kind ), INTENT( OUT ), DIMENSION( m ) :: y
378
379 !> output information after the optimization. See QPALM_info above for details
380
381 TYPE ( qpalm_info ), INTENT( OUT ) :: info
382
383 END SUBROUTINE qpalm_fortran
384 END INTERFACE
385
386END MODULE qpalm_fiface
ladel_int c_int
type for integer numbers
Definition global_opts.h:42
ladel_double c_float
type for floating point numbers
Definition global_opts.h:41
Invoke the QPALM solver.
Fortran interface to the C package QPALM, with the aim to minimize the objective function.
real(kind=real_kind_qpalm), parameter ten
integer, parameter integer_kind_qpalm
integer, parameter real_kind
integer, parameter real_kind_qpalm
integer, parameter integer_kind
info derived type with component defaults bound to C’s QPALMInfo
settings derived type with component defaults bound to C’s QPALMSettings