[gnumeric] solver: by default, select a solver for which we have the executable.
- From: Morten Welinder <mortenw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnumeric] solver: by default, select a solver for which we have the executable.
- Date: Wed, 25 Nov 2009 19:13:20 +0000 (UTC)
commit 3e2b36ac8137b3ca03e47fcc2719ad3593bdc2c5
Author: Morten Welinder <terra gnome org>
Date: Wed Nov 25 14:12:27 2009 -0500
solver: by default, select a solver for which we have the executable.
plugins/glpk/gnm-glpk.c | 16 +++++++++++++++-
plugins/lpsolve/gnm-lpsolve.c | 16 +++++++++++++++-
src/dialogs/dialog-solver.c | 16 ++++++++++++++++
src/gnm-plugin.c | 33 +++++++++++++++++++++++++++++++--
src/gnm-plugin.h | 1 +
src/tools/gnm-solver.c | 16 +++++++++++++---
src/tools/gnm-solver.h | 8 ++++++--
7 files changed, 97 insertions(+), 9 deletions(-)
---
diff --git a/plugins/glpk/gnm-glpk.c b/plugins/glpk/gnm-glpk.c
index ed6528b..04f7437 100644
--- a/plugins/glpk/gnm-glpk.c
+++ b/plugins/glpk/gnm-glpk.c
@@ -14,6 +14,7 @@
#include <string.h>
#include <unistd.h>
+#define SOLVER_PROGRAM "glpsol"
#define PRIVATE_KEY "::glpk::"
typedef struct {
@@ -259,7 +260,7 @@ gnm_glpk_start (GnmSolver *sol, WorkbookControl *wbc, GError **err,
g_return_val_if_fail (sol->status == GNM_SOLVER_STATUS_PREPARED, FALSE);
- argv[argc++] = (gchar *)"glpsol";
+ argv[argc++] = (gchar *)SOLVER_PROGRAM;
argv[argc++] = (gchar *)(param->options.automatic_scaling
? "--scale"
: "--noscale");
@@ -291,6 +292,19 @@ gnm_glpk_stop (GnmSolver *sol, GError *err, GnmGlpk *lp)
return TRUE;
}
+gboolean
+glpk_solver_factory_functional (GnmSolverFactory *factory);
+
+gboolean
+glpk_solver_factory_functional (GnmSolverFactory *factory)
+{
+ char *full_path = g_find_program_in_path (SOLVER_PROGRAM);
+ gboolean res= (full_path != NULL);
+ g_free (full_path);
+ return res;
+}
+
+
GnmSolver *
glpk_solver_factory (GnmSolverFactory *factory, GnmSolverParameters *params);
diff --git a/plugins/lpsolve/gnm-lpsolve.c b/plugins/lpsolve/gnm-lpsolve.c
index f41e5d4..9926ad0 100644
--- a/plugins/lpsolve/gnm-lpsolve.c
+++ b/plugins/lpsolve/gnm-lpsolve.c
@@ -9,6 +9,7 @@
#include <glib/gi18n-lib.h>
#include <string.h>
+#define SOLVER_PROGRAM "lp_solve"
#define PRIVATE_KEY "::lpsolve::"
typedef struct {
@@ -256,7 +257,7 @@ gnm_lpsolve_start (GnmSolver *sol, WorkbookControl *wbc, GError **err,
g_return_val_if_fail (sol->status == GNM_SOLVER_STATUS_PREPARED, FALSE);
- argv[argc++] = (gchar *)"lp_solve";
+ argv[argc++] = (gchar *)SOLVER_PROGRAM;
argv[argc++] = (gchar *)"-i";
argv[argc++] = (gchar *)(param->options.automatic_scaling
? "-s1"
@@ -286,6 +287,19 @@ gnm_lpsolve_stop (GnmSolver *sol, GError *err, GnmLPSolve *lp)
return TRUE;
}
+gboolean
+lpsolve_solver_factory_functional (GnmSolverFactory *factory);
+
+gboolean
+lpsolve_solver_factory_functional (GnmSolverFactory *factory)
+{
+ char *full_path = g_find_program_in_path (SOLVER_PROGRAM);
+ gboolean res= (full_path != NULL);
+ g_free (full_path);
+ return res;
+}
+
+
GnmSolver *
lpsolve_solver_factory (GnmSolverFactory *factory, GnmSolverParameters *params);
diff --git a/src/dialogs/dialog-solver.c b/src/dialogs/dialog-solver.c
index beedf35..5ce1e81 100644
--- a/src/dialogs/dialog-solver.c
+++ b/src/dialogs/dialog-solver.c
@@ -1163,11 +1163,27 @@ void
dialog_solver (WBCGtk *wbcg, Sheet *sheet)
{
SolverState *state;
+ GnmSolverParameters *old_params = sheet->solver_parameters;
/* Only pop up one copy per workbook */
if (gnumeric_dialog_raise_if_exists (wbcg, SOLVER_KEY))
return;
+ /* First time around, pick a functional algorithm. */
+ if (!gnm_solver_factory_functional (old_params->options.algorithm)) {
+ GSList *l;
+ for (l = gnm_solver_db_get (); l; l = l->next) {
+ GnmSolverFactory *factory = l->data;
+ if (old_params->options.model_type != factory->type)
+ continue;
+ if (gnm_solver_factory_functional (factory)) {
+ gnm_solver_param_set_algorithm (old_params,
+ factory);
+ break;
+ }
+ }
+ }
+
state = g_new0 (SolverState, 1);
state->wbcg = wbcg;
state->sheet = sheet;
diff --git a/src/gnm-plugin.c b/src/gnm-plugin.c
index 240462c..ef139c6 100644
--- a/src/gnm-plugin.c
+++ b/src/gnm-plugin.c
@@ -512,6 +512,26 @@ cb_load_and_create (GnmSolverFactory *factory, GnmSolverParameters *param)
return res;
}
+static gboolean
+cb_load_and_functional (GnmSolverFactory *factory)
+{
+ PluginServiceSolver *ssol =
+ g_object_get_data (G_OBJECT (factory), "ssol");
+ GOPluginService *service = GO_PLUGIN_SERVICE (ssol);
+ GOErrorInfo *ignored_error = NULL;
+ GnmSolverFactoryFunctional functional;
+
+ go_plugin_service_load (service, &ignored_error);
+ if (ignored_error != NULL) {
+ go_error_info_print (ignored_error);
+ go_error_info_free (ignored_error);
+ return FALSE;
+ }
+
+ functional = ssol->cbs.functional;
+ return (functional == NULL || functional (factory));
+}
+
static void
plugin_service_solver_init (PluginServiceSolver *ssol)
{
@@ -572,7 +592,8 @@ plugin_service_solver_read_xml (GOPluginService *service, xmlNode *tree,
ssol->factory = gnm_solver_factory_new (CXML2C (s_id),
CXML2C (s_name),
type,
- cb_load_and_create);
+ cb_load_and_create,
+ cb_load_and_functional);
g_object_set_data (G_OBJECT (ssol->factory), "ssol", ssol);
}
xmlFree (s_id);
@@ -815,6 +836,7 @@ gnm_plugin_loader_module_load_service_solver (GOPluginLoader *loader,
PluginServiceSolverCallbacks *cbs;
char *symname;
GnmSolverCreator creator;
+ GnmSolverFactoryFunctional functional;
g_return_if_fail (IS_GNM_PLUGIN_SERVICE_SOLVER (service));
@@ -825,7 +847,6 @@ gnm_plugin_loader_module_load_service_solver (GOPluginLoader *loader,
NULL);
g_module_symbol (loader_module->handle, symname, (gpointer)&creator);
g_free (symname);
-
if (!creator) {
*ret_error = go_error_info_new_printf (
_("Module file \"%s\" has invalid format."),
@@ -833,8 +854,15 @@ gnm_plugin_loader_module_load_service_solver (GOPluginLoader *loader,
return;
}
+ symname = g_strconcat (go_plugin_service_get_id (service),
+ "_solver_factory_functional",
+ NULL);
+ g_module_symbol (loader_module->handle, symname, (gpointer)&functional);
+ g_free (symname);
+
cbs = go_plugin_service_get_cbs (service);
cbs->creator = creator;
+ cbs->functional = functional;
}
static gboolean
@@ -864,6 +892,7 @@ gplm_service_unload (GOPluginLoader *l, GOPluginService *s, GOErrorInfo **err)
PluginServiceSolverCallbacks *cbs =
go_plugin_service_get_cbs (s);
cbs->creator = NULL;
+ cbs->functional = NULL;
} else
return FALSE;
return TRUE;
diff --git a/src/gnm-plugin.h b/src/gnm-plugin.h
index ee13ee3..3513567 100644
--- a/src/gnm-plugin.h
+++ b/src/gnm-plugin.h
@@ -56,6 +56,7 @@ GType plugin_service_solver_get_type (void);
typedef struct _PluginServiceSolver PluginServiceSolver;
typedef struct {
GnmSolverCreator creator;
+ GnmSolverFactoryFunctional functional;
} PluginServiceSolverCallbacks;
/**************************************************************************/
diff --git a/src/tools/gnm-solver.c b/src/tools/gnm-solver.c
index 5579da9..9397b54 100644
--- a/src/tools/gnm-solver.c
+++ b/src/tools/gnm-solver.c
@@ -638,8 +638,6 @@ gnm_solver_param_constructor (GType type,
sp->options.max_time_sec = 30;
sp->options.assume_non_negative = TRUE;
sp->options.scenario_name = g_strdup ("Optimal");
- gnm_solver_param_set_algorithm
- (sp, g_slist_nth_data (gnm_solver_db_get (), 0));
return obj;
}
@@ -1396,7 +1394,8 @@ GnmSolverFactory *
gnm_solver_factory_new (const char *id,
const char *name,
GnmSolverModelType type,
- GnmSolverCreator creator)
+ GnmSolverCreator creator,
+ GnmSolverFactoryFunctional functional)
{
GnmSolverFactory *res;
@@ -1409,6 +1408,7 @@ gnm_solver_factory_new (const char *id,
res->name = g_strdup (name);
res->type = type;
res->creator = creator;
+ res->functional = functional;
return res;
}
@@ -1420,6 +1420,16 @@ gnm_solver_factory_create (GnmSolverFactory *factory,
return factory->creator (factory, param);
}
+gboolean
+gnm_solver_factory_functional (GnmSolverFactory *factory)
+{
+ if (factory == NULL)
+ return FALSE;
+
+ return (factory->functional == NULL ||
+ factory->functional (factory));
+}
+
static int
cb_compare_factories (GnmSolverFactory *a, GnmSolverFactory *b)
{
diff --git a/src/tools/gnm-solver.h b/src/tools/gnm-solver.h
index 83722de..675fb91 100644
--- a/src/tools/gnm-solver.h
+++ b/src/tools/gnm-solver.h
@@ -207,7 +207,7 @@ typedef struct {
gboolean (*start) (GnmSolver *solver,
WorkbookControl *wbc, GError **err);
gboolean (*stop) (GnmSolver *solver, GError **err);
- gboolean (*child_exit) (GnmSolver *solver, gboolean normal, int code);
+ void (*child_exit) (GnmSolver *solver, gboolean normal, int code);
} GnmSolverClass;
GType gnm_solver_get_type (void);
@@ -291,6 +291,7 @@ const char *gnm_sub_solver_get_cell_name (GnmSubSolver *subsol,
typedef GnmSolver * (*GnmSolverCreator) (GnmSolverFactory *,
GnmSolverParameters *);
+typedef gboolean (*GnmSolverFactoryFunctional) (GnmSolverFactory *);
struct GnmSolverFactory_ {
GObject parent;
@@ -299,6 +300,7 @@ struct GnmSolverFactory_ {
char *name; /* Already translated */
GnmSolverModelType type;
GnmSolverCreator creator;
+ GnmSolverFactoryFunctional functional;
};
typedef struct {
@@ -310,9 +312,11 @@ GType gnm_solver_factory_get_type (void);
GnmSolverFactory *gnm_solver_factory_new (const char *id,
const char *name,
GnmSolverModelType type,
- GnmSolverCreator creator);
+ GnmSolverCreator creator,
+ GnmSolverFactoryFunctional funct);
GnmSolver *gnm_solver_factory_create (GnmSolverFactory *factory,
GnmSolverParameters *param);
+gboolean gnm_solver_factory_functional (GnmSolverFactory *factory);
GSList *gnm_solver_db_get (void);
void gnm_solver_db_register (GnmSolverFactory *factory);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]