1# Copyright (C) 2010 Jelmer Ypma. All Rights Reserved.
2# This code is published under the Eclipse Public License.
3#
4# File:   get.option.types.R
5# Author: Jelmer Ypma
6# Date:   18 April 2010
7#
8# This function converts a list with ipopt options into
9# three sub-lists, where the options are sorted into
10# the different value types (integer, numeric, string).
11#
12# Input: list of ipopt options and their values
13# Output: list containing three sub-lists by type with ipopt options and their values
14
15get.option.types <- function(opts) {
16
17	# define types of ipopt options
18    ipopt.option.types <- list(
19
20        # Output
21              "print_level"="integer",
22              "print_user_options"="string",
23              "print_options_documentation"="string",
24              "output_file"="string",
25              "file_print_level"="integer",
26              "option_file_name"="string",
27
28        # Termination
29              "tol"="numeric",
30              "max_iter"="integer",
31              "max_cpu_time"="numeric",
32              "dual_inf_tol"="numeric",
33              "constr_viol_tol"="numeric",
34              "compl_inf_tol"="numeric",
35              "acceptable_tol"="numeric",
36              "acceptable_iter"="integer",
37              "acceptable_constr_viol_tol"="numeric",
38              "acceptable_dual_inf_tol"="numeric",
39              "acceptable_compl_inf_tol"="numeric",
40              "acceptable_obj_change_tol"="numeric",
41              "diverging_iterates_tol"="numeric",
42
43        # NLP Scaling
44              "obj_scaling_factor"="numeric",
45              "nlp_scaling_method"="string",
46              "nlp_scaling_max_gradient"="numeric",
47
48        # NLP
49              "bound_relax_factor"="numeric",
50              "honor_original_bounds"="string",
51              "check_derivatives_for_naninf"="string",
52              "nlp_lower_bound_inf"="numeric",
53              "nlp_upper_bound_inf"="numeric",
54              "fixed_variable_treatment"="string",
55              "jac_c_constant"="string",
56              "jac_d_constant"="string",
57              "hessian_constant"="string",
58
59        # Initialization
60              "bound_frac"="numeric",
61              "bound_push"="numeric",
62              "slack_bound_frac"="numeric",
63              "slack_bound_push"="numeric",
64              "bound_mult_init_val"="numeric",
65              "constr_mult_init_max"="numeric",
66              "bound_mult_init_method"="string",
67
68        # Barrier Parameter
69              "mehrotra_algorithm"="string",
70              "mu_strategy"="string",
71              "mu_oracle"="string",
72              "quality_function_max_section_steps"="integer",
73              "fixed_mu_oracle"="string",
74              "mu_init"="numeric",
75              "mu_max_fact"="numeric",
76              "mu_max"="numeric",
77              "mu_min"="numeric",
78              "barrier_tol_factor"="numeric",
79              "mu_linear_decrease_factor"="numeric",
80              "mu_superlinear_decrease_power"="numeric",
81
82        # Multiplier Updates
83              "alpha_for_y"="string",
84              "alpha_for_y_tol"="numeric",
85              "recalc_y"="string",
86              "recalc_y_feas_tol"="numeric",
87
88        # Line Search
89              "max_soc"="integer",
90              "watchdog_shortened_iter_trigger"="integer",
91              "watchdog_trial_iter_max"="integer",
92              "accept_every_trial_step"="string",
93              "corrector_type"="string",
94
95        # Warm Start
96              "warm_start_init_point"="string",
97              "warm_start_bound_push"="numeric",
98              "warm_start_bound_frac"="numeric",
99              "warm_start_slack_bound_frac"="numeric",
100              "warm_start_slack_bound_push"="numeric",
101              "warm_start_mult_bound_push"="numeric",
102              "warm_start_mult_init_max"="numeric",
103
104        # Restoration Phase
105              "expect_infeasible_problem"="string",
106              "expect_infeasible_problem_ctol"="numeric",
107              "expect_infeasible_problem_ytol"="numeric",
108              "start_with_resto"="string",
109              "soft_resto_pderror_reduction_factor"="numeric",
110              "required_infeasibility_reduction"="numeric",
111              "bound_mult_reset_threshold"="numeric",
112              "constr_mult_reset_threshold"="numeric",
113              "evaluate_orig_obj_at_resto_trial"="string",
114
115        # Linear Solver
116              "linear_solver"="string",
117              "linear_system_scaling"="string",
118              "linear_scaling_on_demand"="string",
119              "max_refinement_steps"="integer",
120              "min_refinement_steps"="integer",
121
122        # Hessian Perturbation
123              "max_hessian_perturbation"="numeric",
124              "min_hessian_perturbation"="numeric",
125              "first_hessian_perturbation"="numeric",
126              "perturb_inc_fact_first"="numeric",
127              "perturb_inc_fact"="numeric",
128              "perturb_dec_fact"="numeric",
129              "jacobian_regularization_value"="numeric",
130
131        # Quasi-Newton
132              "hessian_approximation"="string",
133              "limited_memory_max_history"="integer",
134              "limited_memory_max_skipping"="integer",
135
136        # Derivative Test
137              "derivative_test"="string",
138              "derivative_test_perturbation"="numeric",
139              "derivative_test_tol"="numeric",
140              "derivative_test_print_all"="string",
141              "point_perturbation_radius"="numeric",
142
143        # MA27 Linear Solver
144              "ma27_pivtol"="numeric",
145              "ma27_pivtolmax"="numeric",
146              "ma27_liw_init_factor"="numeric",
147              "ma27_la_init_factor"="numeric",
148              "ma27_meminc_factor"="numeric",
149
150        # MA57 Linear Solver
151              "ma57_pivtol"="numeric",
152              "ma57_pivtolmax"="numeric",
153              "ma57_pre_alloc"="numeric",
154              "ma57_pivot_order"="integer",
155
156        # MUMPS Linear Solver
157              "mumps_pivtol"="numeric",
158              "mumps_pivtolmax"="numeric",
159              "mumps_mem_percent"="integer",
160              "mumps_permuting_scaling"="integer",
161              "mumps_pivot_order"="integer",
162              "mumps_scaling"="integer",
163
164        # Pardis"Linear Solver
165              "pardiso_msglvl"="integer",
166              "pardiso_matching_strategy"="string",
167              "pardiso_out_of_core_power"="integer",
168
169        # WSMP Linear Solver
170              "wsmp_num_threads"="integer",
171              "wsmp_ordering_option"="integer",
172              "wsmp_pivtol"="numeric",
173              "wsmp_pivtolmax"="numeric",
174              "wsmp_scaling"="integer",
175              "wsmp_singularity_threshold"="numeric"
176    )
177
178
179
180	# initialize list with options sorted by type
181	converted.opts <- list( "integer"=list(), "string"=list(), "numeric"=list() )
182
183	is.wholenumber <- function(x, tol = .Machine$double.eps^0.5)  abs(x - round(x)) < tol
184
185	# check if we have at least 1 element in the list, otherwise the
186    # loop runs from 1 to down 0 and we get errors
187    if ( length( opts ) > 0 ) {
188
189        # loop over all options and give them the correct type
190        for ( i in 1:length( opts ) ) {
191            tmp.type <- ipopt.option.types[[match( names(opts)[i], names(ipopt.option.types) )]]
192            if ( is.null( tmp.type ) ) {
193                # determine type
194                if ( is.character(opts[[i]]) ) {
195                    tmp.type <- "string"
196                } else if ( is.wholenumber(opts[[i]]) ) {
197                    tmp.type <- "integer"
198                } else {
199                    tmp.type <- "numeric"
200                }
201                cat( paste( "Warning: ", names(opts)[i], " is not a recognized option, we try to pass it to Ipopt as ", tmp.type, "\n" ) )
202            }
203
204            if ( tmp.type=="string" ) {
205                converted.opts$string[[ names(opts)[i] ]] <- as.character(opts[[i]])
206            } else if ( tmp.type=="integer" ) {
207                converted.opts$integer[[ names(opts)[i] ]] <- as.integer(opts[[i]])
208            } else if ( tmp.type=="numeric" ) {
209                converted.opts$numeric[[ names(opts)[i] ]] <- as.numeric(opts[[i]])
210            } else {
211                stop(paste("Type of option ", names(opts)[i], " not recognized"))
212            }
213        }
214    }
215
216	return ( converted.opts )
217}
218