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