1 #ifndef _TOOLS_GNM_SOLVER_H_
2 #define _TOOLS_GNM_SOLVER_H_
5 #include <glib-object.h>
12 /* ------------------------------------------------------------------------- */
15 GNM_SOLVER_RESULT_NONE
,
16 GNM_SOLVER_RESULT_FEASIBLE
,
17 GNM_SOLVER_RESULT_OPTIMAL
,
18 GNM_SOLVER_RESULT_INFEASIBLE
,
19 GNM_SOLVER_RESULT_UNBOUNDED
20 } GnmSolverResultQuality
;
23 GType
gnm_solver_status_get_type (void);
24 #define GNM_SOLVER_STATUS_TYPE (gnm_solver_status_get_type ())
27 GNM_SOLVER_STATUS_READY
,
28 GNM_SOLVER_STATUS_PREPARING
,
29 GNM_SOLVER_STATUS_PREPARED
,
30 GNM_SOLVER_STATUS_RUNNING
,
31 GNM_SOLVER_STATUS_DONE
,
32 GNM_SOLVER_STATUS_ERROR
,
33 GNM_SOLVER_STATUS_CANCELLED
43 } GnmSolverConstraintType
;
47 GNM_SOLVER_LP
, GNM_SOLVER_QP
, GNM_SOLVER_NLP
51 GType
gnm_solver_problem_type_get_type (void);
52 #define GNM_SOLVER_PROBLEM_TYPE_TYPE (gnm_solver_problem_type_get_type ())
55 GNM_SOLVER_MINIMIZE
, GNM_SOLVER_MAXIMIZE
56 } GnmSolverProblemType
;
58 /* -------------------------------------------------------------------------- */
60 struct GnmSolverConstraint_
{
61 GnmSolverConstraintType type
;
63 /* Must be a range. */
66 /* Must be a constant or a range. */
70 GType
gnm_solver_constraint_get_type (void);
72 GnmSolverConstraint
*gnm_solver_constraint_new (Sheet
*sheet
);
73 void gnm_solver_constraint_free (GnmSolverConstraint
*c
);
74 GnmSolverConstraint
*gnm_solver_constraint_dup (GnmSolverConstraint
*c
,
76 gboolean
gnm_solver_constraint_equal (GnmSolverConstraint
const *a
,
77 GnmSolverConstraint
const *b
);
79 void gnm_solver_constraint_set_old (GnmSolverConstraint
*c
,
80 GnmSolverConstraintType type
,
81 int lhs_col
, int lhs_row
,
82 int rhs_col
, int rhs_row
,
85 gboolean
gnm_solver_constraint_has_rhs (GnmSolverConstraint
const *c
);
86 gboolean
gnm_solver_constraint_valid (GnmSolverConstraint
const *c
,
87 GnmSolverParameters
const *sp
);
88 gboolean
gnm_solver_constraint_get_part (GnmSolverConstraint
const *c
,
89 GnmSolverParameters
const *sp
, int i
,
90 GnmCell
**lhs
, gnm_float
*cl
,
91 GnmCell
**rhs
, gnm_float
*cr
);
93 GnmValue
const *gnm_solver_constraint_get_lhs (GnmSolverConstraint
const *c
);
94 GnmValue
const *gnm_solver_constraint_get_rhs (GnmSolverConstraint
const *c
);
96 void gnm_solver_constraint_set_lhs (GnmSolverConstraint
*c
, GnmValue
*v
);
97 void gnm_solver_constraint_set_rhs (GnmSolverConstraint
*c
, GnmValue
*v
);
99 void gnm_solver_constraint_side_as_str (GnmSolverConstraint
const *c
,
101 GString
*buf
, gboolean lhs
);
102 char *gnm_solver_constraint_as_str (GnmSolverConstraint
const *c
, Sheet
*sheet
);
103 char *gnm_solver_constraint_part_as_str (GnmSolverConstraint
const *c
, int i
,
104 GnmSolverParameters
*sp
);
106 /* ------------------------------------------------------------------------- */
111 GnmSolverFactory
*algorithm
;
112 GnmSolverModelType model_type
;
113 gboolean assume_non_negative
;
114 gboolean assume_discrete
;
115 gboolean automatic_scaling
;
116 gboolean program_report
;
117 gboolean sensitivity_report
;
118 gboolean add_scenario
;
119 gchar
*scenario_name
;
120 unsigned gradient_order
;
123 #define GNM_SOLVER_PARAMETERS_TYPE (gnm_solver_param_get_type ())
124 #define GNM_SOLVER_PARAMETERS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GNM_SOLVER_PARAMETERS_TYPE, GnmSolverParameters))
125 #define GNM_IS_SOLVER_PARAMETERS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNM_SOLVER_PARAMETERS_TYPE))
127 struct GnmSolverParameters_
{
130 /* Default parsing sheet. No ref held. */
133 GnmSolverProblemType problem_type
;
137 GnmSolverOptions options
;
141 GObjectClass parent_class
;
142 } GnmSolverParametersClass
;
144 GType
gnm_solver_param_get_type (void);
146 /* Creates a new GnmSolverParameters object. */
147 GnmSolverParameters
*gnm_solver_param_new (Sheet
*sheet
);
149 /* Duplicate a GnmSolverParameters object. */
150 GnmSolverParameters
*gnm_solver_param_dup (GnmSolverParameters
*src
,
153 gboolean
gnm_solver_param_equal (GnmSolverParameters
const *a
,
154 GnmSolverParameters
const *b
);
156 GnmValue
const *gnm_solver_param_get_input (GnmSolverParameters
const *sp
);
157 void gnm_solver_param_set_input (GnmSolverParameters
*sp
, GnmValue
*v
);
158 GPtrArray
*gnm_solver_param_get_input_cells (GnmSolverParameters
const *sp
);
160 const GnmCellRef
*gnm_solver_param_get_target (GnmSolverParameters
const *sp
);
161 void gnm_solver_param_set_target (GnmSolverParameters
*sp
,
162 GnmCellRef
const *cr
);
163 GnmCell
*gnm_solver_param_get_target_cell (GnmSolverParameters
const *sp
);
165 void gnm_solver_param_set_algorithm (GnmSolverParameters
*sp
,
166 GnmSolverFactory
*algo
);
168 gboolean
gnm_solver_param_valid (GnmSolverParameters
const *sp
, GError
**err
);
170 /* -------------------------------------------------------------------------- */
172 #define GNM_SOLVER_RESULT_TYPE (gnm_solver_result_get_type ())
173 #define GNM_SOLVER_RESULT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GNM_SOLVER_RESULT_TYPE, GnmSolverResult))
178 GnmSolverResultQuality quality
;
180 /* Objective value, if any */
183 /* Array value of solution, if any */
188 GObjectClass parent_class
;
189 } GnmSolverResultClass
;
191 GType
gnm_solver_result_get_type (void);
193 /* ------------------------------------------------------------------------- */
195 #define GNM_SOLVER_SENSITIVITY_TYPE (gnm_solver_sensitivity_get_type ())
196 #define GNM_SOLVER_SENSITIVITY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GNM_SOLVER_SENSITIVITY_TYPE, GnmSolverSensitivity))
203 struct GnmSolverSensitivityVars_
{
204 gnm_float low
, high
; // Allowable range
205 gnm_float reduced_cost
;
208 struct GnmSolverSensitivityConstraints_
{
209 gnm_float low
, high
; // Allowable range
210 gnm_float shadow_price
;
212 } GnmSolverSensitivity
;
215 GObjectClass parent_class
;
216 } GnmSolverSensitivityClass
;
218 GType
gnm_solver_sensitivity_get_type (void);
220 GnmSolverSensitivity
*gnm_solver_sensitivity_new (GnmSolver
*sol
);
222 /* ------------------------------------------------------------------------- */
223 /* Generic Solver class. */
225 #define GNM_SOLVER_TYPE (gnm_solver_get_type ())
226 #define GNM_SOLVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GNM_SOLVER_TYPE, GnmSolver))
227 #define GNM_IS_SOLVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNM_SOLVER_TYPE))
232 GnmSolverStatus status
;
235 GnmSolverParameters
*params
;
236 GnmSolverResult
*result
;
237 GnmSolverSensitivity
*sensitivity
;
238 double starttime
, endtime
;
241 /* Derived information */
243 GPtrArray
*input_cells
;
244 GHashTable
*index_from_cell
;
250 int gradient_status
; // 0: not tried; 1: ok; 2: fail
254 int hessian_status
; // 0: not tried; 1: ok; 2: fail
259 GObjectClass parent_class
;
261 gboolean (*prepare
) (GnmSolver
*sol
,
262 WorkbookControl
*wbc
, GError
**err
);
263 gboolean (*start
) (GnmSolver
*sol
,
264 WorkbookControl
*wbc
, GError
**err
);
265 gboolean (*stop
) (GnmSolver
*sol
, GError
**err
);
268 GType
gnm_solver_get_type (void);
270 gboolean
gnm_solver_prepare (GnmSolver
*sol
,
271 WorkbookControl
*wbc
, GError
**err
);
272 gboolean
gnm_solver_start (GnmSolver
*sol
,
273 WorkbookControl
*wbc
, GError
**err
);
274 gboolean
gnm_solver_stop (GnmSolver
*sol
, GError
**err
);
276 void gnm_solver_set_status (GnmSolver
*solver
, GnmSolverStatus status
);
278 void gnm_solver_set_reason (GnmSolver
*solver
, const char *reason
);
280 void gnm_solver_store_result (GnmSolver
*solver
);
282 void gnm_solver_create_report (GnmSolver
*solver
, const char *name
);
284 double gnm_solver_elapsed (GnmSolver
*solver
);
286 gboolean
gnm_solver_check_timeout (GnmSolver
*solver
);
288 gboolean
gnm_solver_finished (GnmSolver
*solver
);
290 gboolean
gnm_solver_has_solution (GnmSolver
*solver
);
292 gboolean
gnm_solver_check_constraints (GnmSolver
*solver
);
294 gboolean
gnm_solver_saveas (GnmSolver
*solver
, WorkbookControl
*wbc
,
296 const char *templ
, char **filename
,
299 gboolean
gnm_solver_debug (void);
301 int gnm_solver_cell_index (GnmSolver
*solver
, GnmCell
const *cell
);
303 gnm_float
gnm_solver_get_target_value (GnmSolver
*solver
);
304 void gnm_solver_set_var (GnmSolver
*sol
, int i
, gnm_float x
);
305 void gnm_solver_set_vars (GnmSolver
*sol
, gnm_float
const *xs
);
307 GPtrArray
*gnm_solver_save_vars (GnmSolver
*sol
);
308 void gnm_solver_restore_vars (GnmSolver
*sol
, GPtrArray
*vals
);
310 gboolean
gnm_solver_has_analytic_gradient (GnmSolver
*sol
);
311 gnm_float
*gnm_solver_compute_gradient (GnmSolver
*sol
, gnm_float
const *xs
);
313 gboolean
gnm_solver_has_analytic_hessian (GnmSolver
*sol
);
314 GnmMatrix
*gnm_solver_compute_hessian (GnmSolver
*sol
, gnm_float
const *xs
);
316 gnm_float
gnm_solver_line_search (GnmSolver
*sol
,
317 gnm_float
const *x0
, gnm_float
const *dir
,
318 gboolean try_reverse
,
319 gnm_float step
, gnm_float max_step
, gnm_float eps
,
322 void gnm_solver_pick_lp_coords (GnmSolver
*sol
,
323 gnm_float
**px1
, gnm_float
**px2
);
325 gnm_float
*gnm_solver_get_lp_coeffs (GnmSolver
*sol
, GnmCell
*ycell
,
326 gnm_float
const *x1
, gnm_float
const *x2
,
329 /* ------------------------------------------------------------------------- */
330 /* Solver subclass for subprocesses. */
332 #define GNM_SUB_SOLVER_TYPE (gnm_sub_solver_get_type ())
333 #define GNM_SUB_SOLVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GNM_SUB_SOLVER_TYPE, GnmSubSolver))
334 #define GNM_IS_SUB_SOLVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNM_SUB_SOLVER_TYPE))
339 char *program_filename
;
341 /* Hashes between char* and cell*. */
342 GHashTable
*cell_from_name
;
343 GHashTable
*name_from_cell
;
345 GHashTable
*constraint_from_name
;
351 GIOChannel
*channels
[3];
352 guint channel_watches
[3];
354 gpointer io_funcs_data
[3];
358 GnmSolverClass parent_class
;
360 void (*child_exit
) (GnmSubSolver
*subsol
, gboolean normal
, int code
);
363 GType
gnm_sub_solver_get_type (void);
365 void gnm_sub_solver_clear (GnmSubSolver
*subsol
);
367 gboolean gnm_sub_solver_spawn
368 (GnmSubSolver
*subsol
,
370 GSpawnChildSetupFunc child_setup
, gpointer setup_data
,
371 GIOFunc io_stdout
, gpointer stdout_data
,
372 GIOFunc io_stderr
, gpointer stderr_data
,
375 void gnm_sub_solver_flush (GnmSubSolver
*subsol
);
377 const char *gnm_sub_solver_name_cell (GnmSubSolver
*subsol
,
380 GnmCell
*gnm_sub_solver_find_cell (GnmSubSolver
*subsol
, const char *name
);
381 const char *gnm_sub_solver_get_cell_name (GnmSubSolver
*subsol
,
382 GnmCell
const *cell
);
384 const char *gnm_sub_solver_name_constraint (GnmSubSolver
*subsol
,
387 int gnm_sub_solver_find_constraint (GnmSubSolver
*subsol
, const char *name
);
389 char *gnm_sub_solver_locate_binary (const char *binary
, const char *solver
,
393 /* ------------------------------------------------------------------------- */
395 typedef struct GnmIterSolver_ GnmIterSolver
;
396 typedef struct GnmSolverIterator_ GnmSolverIterator
;
398 /* Utility class for single iteration in a solving process. */
400 #define GNM_SOLVER_ITERATOR_TYPE (gnm_solver_iterator_get_type ())
401 #define GNM_SOLVER_ITERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GNM_SOLVER_ITERATOR_TYPE, GnmSolverIterator))
402 #define GNM_IS_SOLVER_ITERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNM_SOLVER_ITERATOR_TYPE))
404 struct GnmSolverIterator_
{
409 GObjectClass parent_class
;
411 gboolean (*iterate
) (GnmSolverIterator
*iter
);
412 } GnmSolverIteratorClass
;
414 GType
gnm_solver_iterator_get_type (void);
416 GnmSolverIterator
*gnm_solver_iterator_new_func (GCallback iterate
, gpointer user
);
417 GnmSolverIterator
*gnm_solver_iterator_new_polish (GnmIterSolver
*isol
);
418 GnmSolverIterator
*gnm_solver_iterator_new_gradient (GnmIterSolver
*isol
);
420 gboolean
gnm_solver_iterator_iterate (GnmSolverIterator
*iter
);
424 #define GNM_SOLVER_ITERATOR_COMPOUND_TYPE (gnm_solver_iterator_compound_get_type ())
425 #define GNM_SOLVER_ITERATOR_COMPOUND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GNM_SOLVER_ITERATOR_COMPOUND_TYPE, GnmSolverIteratorCompound))
426 #define GNM_IS_SOLVER_ITERATOR_COMPOUND(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNM_SOLVER_ITERATOR_COMPOUND_TYPE))
429 GnmSolverIterator parent
;
433 GPtrArray
*iterators
;
435 unsigned next
, next_counter
, cycle
;
436 gboolean cycle_progress
;
437 } GnmSolverIteratorCompound
;
440 GnmSolverIteratorClass parent_class
;
441 } GnmSolverIteratorCompoundClass
;
443 GType
gnm_solver_iterator_compound_get_type (void);
444 void gnm_solver_iterator_compound_add (GnmSolverIteratorCompound
*ic
,
445 GnmSolverIterator
*iter
,
448 /* ------------------------------------------------------------------------- */
449 /* Solver subclass for iterative in-process solvers. */
451 #define GNM_ITER_SOLVER_TYPE (gnm_iter_solver_get_type ())
452 #define GNM_ITER_SOLVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GNM_ITER_SOLVER_TYPE, GnmIterSolver))
453 #define GNM_IS_ITER_SOLVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNM_ITER_SOLVER_TYPE))
455 struct GnmIterSolver_
{
461 GnmSolverIterator
*iterator
;
470 GnmSolverClass parent_class
;
471 } GnmIterSolverClass
;
473 GType
gnm_iter_solver_get_type (void);
475 void gnm_iter_solver_set_iterator (GnmIterSolver
*isol
, GnmSolverIterator
*iterator
);
477 gboolean
gnm_iter_solver_get_initial_solution (GnmIterSolver
*isol
, GError
**err
);
478 void gnm_iter_solver_set_solution (GnmIterSolver
*isol
);
480 /* ------------------------------------------------------------------------- */
482 #define GNM_SOLVER_FACTORY_TYPE (gnm_solver_factory_get_type ())
483 #define GNM_SOLVER_FACTORY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GNM_SOLVER_FACTORY_TYPE, GnmSolverFactory))
484 #define GNM_IS_SOLVER_FACTORY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNM_SOLVER_FACTORY_TYPE))
486 typedef GnmSolver
* (*GnmSolverCreator
) (GnmSolverFactory
*factory
,
487 GnmSolverParameters
*param
,
489 typedef gboolean (*GnmSolverFactoryFunctional
) (GnmSolverFactory
*factory
,
493 struct GnmSolverFactory_
{
498 char *name
; /* Already translated */
499 GnmSolverModelType type
;
500 GnmSolverCreator creator
;
501 GnmSolverFactoryFunctional functional
;
503 GDestroyNotify notify
;
507 GObjectClass parent_class
;
508 } GnmSolverFactoryClass
;
510 GType
gnm_solver_factory_get_type (void);
512 GnmSolverFactory
*gnm_solver_factory_new (const char *id
,
514 GnmSolverModelType type
,
515 GnmSolverCreator creator
,
516 GnmSolverFactoryFunctional functional
,
518 GDestroyNotify notify
);
519 GnmSolver
*gnm_solver_factory_create (GnmSolverFactory
*factory
,
520 GnmSolverParameters
*param
);
521 gboolean
gnm_solver_factory_functional (GnmSolverFactory
*factory
,
524 GSList
*gnm_solver_db_get (void);
525 void gnm_solver_db_register (GnmSolverFactory
*factory
);
526 void gnm_solver_db_unregister (GnmSolverFactory
*factory
);
528 /* ------------------------------------------------------------------------- */
532 #endif /* _TOOLS_GNM_SOLVER_H_ */