static gboolean check_program (GnmSolver *sol, GError **err) { unsigned ui; const GnmSolverParameters *params = sol->params; GSList *l; for (l = params->constraints; l; l = l->next) { GnmSolverConstraint *c = l->data; switch (c->type) { case GNM_SOLVER_EQ: /* * This catches also equalities where the sides are not * input variables. */ goto no_equal; default: break; } } for (ui = 0; ui < sol->input_cells->len; ui++) { if (sol->discrete[ui]) goto no_discrete; /* * This also catches using two inequality constraints used * to emulate equality. */ if (sol->min[ui] == sol->max[ui]) goto no_equal; } return TRUE; no_discrete: g_set_error (err, go_error_invalid (), 0, _("This solver does not handle discrete variables.")); return FALSE; no_equal: g_set_error (err, go_error_invalid (), 0, _("This solver does not handle equality constraints.")); return FALSE; }
void go_cmd_context_error_invalid (GOCmdContext *context, char const *msg, char const *val) { GError *err = g_error_new (go_error_invalid(), 0, "Invalid %s : '%s'", msg, val); go_cmd_context_error (context, err); g_error_free (err); }
static gboolean gnm_nlsolve_get_initial_solution (GnmNlsolve *nl, GError **err) { GnmSolver *sol = nl->parent; const int n = nl->vars->len; int i; if (gnm_solver_check_constraints (sol)) goto got_it; /* More? */ g_set_error (err, go_error_invalid (), 0, _("The initial values do not satisfy the constraints.")); return FALSE; got_it: for (i = 0; i < n; i++) { GnmCell *cell = g_ptr_array_index (nl->vars, i); nl->xk[i] = nl->x0[i] = value_get_as_float (cell->value); } nl->yk = get_value (nl); gnm_nlsolve_set_solution (nl); return TRUE; }
static gboolean cb_set_export_option (const char *key, const char *value, GError **err, gpointer user) { Workbook *wb = user; GnmStfExport *stfe = gnm_stf_get_stfe (G_OBJECT (wb)); const char *errtxt; if (strcmp (key, "sheet") == 0) { Sheet *sheet = workbook_sheet_by_name (wb, value); if (!sheet) { errtxt = _("There is no such sheet"); goto error; } gnm_stf_export_options_sheet_list_add (stfe, sheet); return FALSE; } if (strcmp (key, "eol") == 0) { const char *eol; if (g_ascii_strcasecmp ("unix", value) == 0) eol = "\n"; else if (g_ascii_strcasecmp ("mac", value) == 0) eol = "\r"; else if (g_ascii_strcasecmp ("windows", value) == 0) eol = "\r\n"; else { errtxt = _("eol must be one of unix, mac, and windows"); goto error; } g_object_set (G_OBJECT (stfe), "eol", eol, NULL); return FALSE; } if (strcmp (key, "charset") == 0 || strcmp (key, "locale") == 0 || strcmp (key, "quote") == 0 || strcmp (key, "separator") == 0 || strcmp (key, "format") == 0 || strcmp (key, "transliterate-mode") == 0 || strcmp (key, "quoting-mode") == 0 || strcmp (key, "quoting-on-whitespace") == 0) return go_object_set_property (G_OBJECT (stfe), key, key, value, err, (_("Invalid value for option %s: \"%s\""))); errtxt = _("Invalid option for stf exporter"); error: if (err) *err = g_error_new (go_error_invalid (), 0, "%s", errtxt); return TRUE; }
GError * go_val_bucketer_validate (GOValBucketer *bucketer) { GError *failure = NULL; if (bucketer->type >= GO_VAL_BUCKET_SERIES_LINEAR) { if (bucketer->details.dates.minimum >= bucketer->details.dates.maximum) failure = g_error_new (go_error_invalid (), 0, _("minima must be < maxima")); else if (bucketer->details.series.step <= 0) failure = g_error_new (go_error_invalid (), 0, _("step must be > 0")); } else if (bucketer->type != GO_VAL_BUCKET_NONE) { if (bucketer->details.dates.minimum >= bucketer->details.dates.maximum) failure = g_error_new (go_error_invalid (), 0, _("minima must be < maxima")); } return failure; }
void dialog_data_table (WBCGtk *wbcg) { GnmDialogDataTable *state; GnmRange const *r; GnmRange input_range; SheetView *sv; Sheet *sheet; g_return_if_fail (wbcg != NULL); if (wbc_gtk_get_guru (wbcg) || gnm_dialog_raise_if_exists (wbcg, DIALOG_DATA_TABLE_KEY)) return; sv = wb_control_cur_sheet_view (GNM_WBC (wbcg)); r = selection_first_range (sv, GO_CMD_CONTEXT (wbcg), _("Create Data Table")); if (NULL == r) return; if (range_width (r) <= 1 || range_height (r) <= 1) { GError *msg = g_error_new (go_error_invalid(), 0, _("The selection must have more than 1 column and row to create a Data Table.")); go_cmd_context_error (GO_CMD_CONTEXT (wbcg), msg); g_error_free (msg); return; } input_range = *r; input_range.start.col++; input_range.start.row++; sheet = sv_sheet (sv); if (sheet_range_splits_region (sheet, &input_range, NULL, GO_CMD_CONTEXT (wbcg), _("Data Table"))) return; if (cmd_cell_range_is_locked_effective (sheet, &input_range, GNM_WBC (wbcg), _("Data Table"))) return; state = g_new0 (GnmDialogDataTable, 1); state->wbcg = wbcg; state->sheet = sheet; state->input_range = input_range; if (data_table_init (state, wbcg)) { go_gtk_notice_dialog (wbcg_toplevel (wbcg), GTK_MESSAGE_ERROR, _("Could not create the Data Table definition dialog.")); g_free (state); } }
static gboolean check_program (const GnmSolverParameters *params, GError **err) { GSList *l; if (params->options.assume_discrete) goto no_discrete; for (l = params->constraints; l; l = l->next) { GnmSolverConstraint *c = l->data; if (c->type == GNM_SOLVER_INTEGER || c->type == GNM_SOLVER_BOOLEAN) goto no_discrete; } return TRUE; no_discrete: g_set_error (err, go_error_invalid (), 0, _("This solver does not handle discrete variables.")); return FALSE; }
/** * stf_text_to_columns: * @wbc: The control making the request * @cc: * * Main routine, handles importing a file including all dialog mumbo-jumbo **/ void stf_text_to_columns (WorkbookControl *wbc, GOCmdContext *cc) { DialogStfResult_t *dialogresult = NULL; SheetView *sv; Sheet *src_sheet, *target_sheet; GnmRange const *src; GnmRange target; GsfOutput *buf; guint8 const *data; size_t data_len; sv = wb_control_cur_sheet_view (wbc); src_sheet = sv_sheet (sv); src = selection_first_range (sv, cc, _("Text to Columns")); if (src == NULL) return; if (range_width (src) > 1) { go_cmd_context_error (cc, g_error_new (go_error_invalid (), 0, _("Only one column of input data can be parsed at a time"))); return; } /* FIXME : how to do this cleanly ? */ if (!GNM_IS_WBC_GTK (wbc)) return; #warning Add UI for this target_sheet = src_sheet; target = *src; range_translate (&target, target_sheet, 1, 0); buf = gsf_output_memory_new (); sheet_foreach_cell_in_range (src_sheet, CELL_ITER_ALL, src->start.col, src->start.row, src->end.col, src->end.row, (CellIterFunc) &cb_get_content, buf); gsf_output_close (buf); data = gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (buf)); data_len = (size_t)gsf_output_size (buf); if (data_len == 0) { go_cmd_context_error_import (GO_CMD_CONTEXT (cc), _("There is no data " "to convert")); } else { dialogresult = stf_dialog (WBC_GTK (wbc), NULL, FALSE, NULL, FALSE, _("Text to Columns"), data, data_len); } if (dialogresult != NULL) { GnmCellRegion *cr = stf_parse_region (dialogresult->parseoptions, dialogresult->text, NULL, target_sheet->workbook); if (cr != NULL) { stf_dialog_result_attach_formats_to_cr (dialogresult, cr); target.end.col = target.start.col + cr->cols - 1; target.end.row = target.start.row + cr->rows - 1; } if (cr == NULL || cmd_text_to_columns (wbc, src, src_sheet, &target, target_sheet, cr)) go_cmd_context_error_import (GO_CMD_CONTEXT (cc), _("Error while trying to " "parse data into sheet")); stf_dialog_result_free (dialogresult); } g_object_unref (buf); }
static GString * glpk_create_program (GnmSubSolver *ssol, GOIOContext *io_context, GError **err) { GnmSolver *sol = GNM_SOLVER (ssol); GnmSolverParameters *sp = sol->params; GString *prg = NULL; GString *constraints = g_string_new (NULL); GString *bounds = g_string_new (NULL); GString *binaries = g_string_new (NULL); GString *integers = g_string_new (NULL); GString *objfunc = g_string_new (NULL); GSList *l; GnmCell *target_cell = gnm_solver_param_get_target_cell (sp); GPtrArray *input_cells = sol->input_cells; gsize progress; GPtrArray *old = NULL; gnm_float *x1 = NULL, *x2 = NULL; int cidx = 0; /* ---------------------------------------- */ if (sp->options.model_type != GNM_SOLVER_LP) { g_set_error (err, go_error_invalid (), 0, _("Only linear programs are handled.")); goto fail; } /* ---------------------------------------- */ if (ssol) { unsigned ui; for (ui = 0; ui < input_cells->len; ui++) { GnmCell *cell = g_ptr_array_index (input_cells, ui); char *name = g_strdup_printf ("X_%u", ui + 1); gnm_sub_solver_name_cell (ssol, cell, name); g_free (name); } } /* ---------------------------------------- */ progress = 3; /* assume_non_negative */ progress++; if (sp->options.assume_discrete) progress++; progress += g_slist_length (sp->constraints); go_io_count_progress_set (io_context, progress, 1); /* ---------------------------------------- */ old = gnm_solver_save_vars (sol); gnm_solver_pick_lp_coords (sol, &x1, &x2); go_io_count_progress_update (io_context, 1); /* ---------------------------------------- */ switch (sp->problem_type) { case GNM_SOLVER_MINIMIZE: g_string_append (objfunc, "Minimize\n"); break; case GNM_SOLVER_MAXIMIZE: g_string_append (objfunc, "Maximize\n"); break; default: g_assert_not_reached (); } go_io_count_progress_update (io_context, 1); g_string_append (objfunc, " obj: "); if (!glpk_affine_func (objfunc, target_cell, ssol, x1, x2, TRUE, 0, err)) goto fail; g_string_append (objfunc, "\n"); go_io_count_progress_update (io_context, 1); /* ---------------------------------------- */ { unsigned ui; for (ui = 0; ui < input_cells->len; ui++) { GnmCell *cell = g_ptr_array_index (input_cells, ui); const char *name = glpk_var_name (ssol, cell); if (sp->options.assume_non_negative) g_string_append_printf (bounds, " %s >= 0\n", name); else g_string_append_printf (bounds, " %s free\n", name); } go_io_count_progress_update (io_context, 1); } if (sp->options.assume_discrete) { unsigned ui; for (ui = 0; ui < input_cells->len; ui++) { GnmCell *cell = g_ptr_array_index (input_cells, ui); g_string_append_printf (integers, " %s\n", glpk_var_name (ssol, cell)); } go_io_count_progress_update (io_context, 1); } for (l = sp->constraints; l; l = l->next) { GnmSolverConstraint *c = l->data; const char *op = NULL; int i; gnm_float cl, cr; GnmCell *lhs, *rhs; GString *type = NULL; switch (c->type) { case GNM_SOLVER_LE: op = "<="; break; case GNM_SOLVER_GE: op = ">="; break; case GNM_SOLVER_EQ: op = "="; break; case GNM_SOLVER_INTEGER: type = integers; break; case GNM_SOLVER_BOOLEAN: type = binaries; break; default: g_assert_not_reached (); } for (i = 0; gnm_solver_constraint_get_part (c, sp, i, &lhs, &cl, &rhs, &cr); i++, cidx++) { if (type) { g_string_append_printf (type, " %s\n", glpk_var_name (ssol, lhs)); } else { gboolean ok; char *name; g_string_append_c (constraints, ' '); name = g_strdup_printf ("C_%d", cidx); gnm_sub_solver_name_constraint (ssol, cidx, name); g_string_append (constraints, name); g_string_append (constraints, ": "); g_free (name); ok = glpk_affine_func (constraints, lhs, ssol, x1, x2, FALSE, cl, err); if (!ok) goto fail; g_string_append_c (constraints, ' '); g_string_append (constraints, op); g_string_append_c (constraints, ' '); ok = glpk_affine_func (constraints, rhs, ssol, x1, x2, FALSE, cr, err); if (!ok) goto fail; g_string_append (constraints, "\n"); } } go_io_count_progress_update (io_context, 1); } /* ---------------------------------------- */ prg = g_string_new (NULL); g_string_append_printf (prg, "\\ Created by Gnumeric %s\n\n", GNM_VERSION_FULL); go_string_append_gstring (prg, objfunc); g_string_append (prg, "\nSubject to\n"); go_string_append_gstring (prg, constraints); g_string_append (prg, "\nBounds\n"); go_string_append_gstring (prg, bounds); if (integers->len > 0) { g_string_append (prg, "\nGeneral\n"); go_string_append_gstring (prg, integers); } if (binaries->len > 0) { g_string_append (prg, "\nBinary\n"); go_string_append_gstring (prg, binaries); } g_string_append (prg, "\nEnd\n"); fail: g_string_free (objfunc, TRUE); g_string_free (constraints, TRUE); g_string_free (bounds, TRUE); g_string_free (integers, TRUE); g_string_free (binaries, TRUE); g_free (x1); g_free (x2); if (old) gnm_solver_restore_vars (sol, old); return prg; }