示例#1
0
/**
 * parse_criteria:
 * @crit_val: #GnmValue
 * @date_conv: #GODateConventions
 *
 * Returns: (transfer full): GnmCriteria which caller must free.
 *
 * ">=value"
 * "<=value"
 * "<>value"
 * "<value"
 * ">value"
 * "=value"
 * "pattern"
 **/
GnmCriteria *
parse_criteria (GnmValue const *crit_val, GODateConventions const *date_conv,
		gboolean anchor_end)
{
	int len;
	char const *criteria;
	GnmCriteria *res = g_new0 (GnmCriteria, 1);
	GnmValue *empty;

	res->iter_flags = CELL_ITER_IGNORE_BLANK;
	res->date_conv = date_conv;

	if (VALUE_IS_NUMBER (crit_val)) {
		res->fun = criteria_test_equal;
		res->x = value_dup (crit_val);
		return res;
	}

	criteria = value_peek_string (crit_val);
        if (strncmp (criteria, "<=", 2) == 0) {
		res->fun = criteria_test_less_or_equal;
		len = 2;
	} else if (strncmp (criteria, ">=", 2) == 0) {
		res->fun = criteria_test_greater_or_equal;
		len = 2;
	} else if (strncmp (criteria, "<>", 2) == 0) {
		/* "<>" by itself is special: */
		res->fun = (criteria[2] == 0) ? criteria_test_nonempty : criteria_test_unequal;
		len = 2;
	} else if (*criteria == '<') {
		res->fun = criteria_test_less;
		len = 1;
	} else if (*criteria == '=') {
		/* "=" by itself is special: */
		res->fun = (criteria[1] == 0) ? criteria_test_empty : criteria_test_equal;
		len = 1;
	} else if (*criteria == '>') {
		res->fun = criteria_test_greater;
		len = 1;
	} else {
		res->fun = criteria_test_match;
		res->has_rx = (gnm_regcomp_XL (&res->rx, criteria, GO_REG_ICASE, TRUE, anchor_end) == GO_REG_OK);
		len = 0;
	}

	res->x = format_match_number (criteria + len, NULL, date_conv);
	if (res->x == NULL)
		res->x = value_new_string (criteria + len);
	else if (len == 0 && VALUE_IS_NUMBER (res->x))
		res->fun = criteria_test_equal;

	empty = value_new_empty ();
	if (res->fun (empty, res))
		res->iter_flags &= ~CELL_ITER_IGNORE_BLANK;
	value_release (empty);
	res->ref_count = 1;

	return res;
}
示例#2
0
static GnmExpr const *
contents_as_expr (GnmExprTop const *texpr, GnmValue const *val)
{
	if (texpr)
		return gnm_expr_copy (texpr->expr);
	if (VALUE_IS_EMPTY (val))
		return gnm_expr_new_constant (value_new_float (0.0));
	if (VALUE_IS_NUMBER (val))
		return gnm_expr_new_constant (value_dup (val));
	return NULL;
}
示例#3
0
static GnmValue *
cb_sylk_write_cell (GnmCellIter const *iter, SylkWriter *state)
{
	GnmValue const *v;
	GnmExprTop const *texpr;
	GnmExprArrayCorner const *array;

	if (iter->pp.eval.row != state->cur_row)
		gsf_output_printf (state->output, "C;Y%d;X%d",
			(state->cur_row = iter->pp.eval.row) + 1,
			iter->pp.eval.col + 1);
	else
		gsf_output_printf (state->output, "C;X%d",
			iter->pp.eval.col + 1);

	if (NULL != (v = iter->cell->value)) {
		if (VALUE_IS_STRING (v)) {
			gsf_output_write (state->output, 3, ";K\"");
			sylk_write (state, v->v_str.val->str);
			gsf_output_write (state->output, 1, "\"");
		} else if (VALUE_IS_NUMBER (v) || VALUE_IS_ERROR (v)) {
			GString *res = g_string_sized_new (10);
			value_get_as_gstring (v, res, state->convs);
			gsf_output_write (state->output, 2, ";K");
			gsf_output_write (state->output, res->len, res->str);
			g_string_free (res, TRUE);
		} /* ignore the rest */
	}

	if (NULL != (texpr = iter->cell->base.texpr)) {
		if (NULL != (array = gnm_expr_top_get_array_corner (texpr))) {
			gsf_output_printf (state->output, ";R%d;C%d;M",
				iter->pp.eval.row + array->rows,
				iter->pp.eval.col + array->cols);
		} else if (gnm_expr_top_is_array_elem (texpr, NULL, NULL)) {
			gsf_output_write (state->output, 2, ";I");
			texpr = NULL;
		} else
			gsf_output_write (state->output, 2, ";E");

		if (texpr != NULL) {
			GnmConventionsOut out;
			out.accum = g_string_new (NULL);
			out.pp    = &iter->pp;
			out.convs = state->convs;
			gnm_expr_top_as_gstring (texpr, &out);
			sylk_write (state, out.accum->str);
			g_string_free (out.accum, TRUE);
		}
	}
	gsf_output_write (state->output, 2, "\r\n");
	return NULL;
}
示例#4
0
static gnm_float
get_value (GnmNlsolve *nl)
{
	GnmValue const *v;

	gnm_cell_eval (nl->target);
	v = nl->target->value;

	if (VALUE_IS_NUMBER (v) || VALUE_IS_EMPTY (v)) {
		gnm_float y = value_get_as_float (v);
		return nl->maximize ? 0 - y : y;
	} else
		return gnm_nan;
}
示例#5
0
static void
paste_cell_with_operation (Sheet *dst_sheet,
			   int target_col, int target_row,
			   GnmExprRelocateInfo const *rinfo,
			   GnmCellCopy const *src,
			   int paste_flags)
{
	GnmCell *dst;
	GnmExprOp op;

	if (src->texpr == NULL &&
	    !VALUE_IS_EMPTY (src->val) &&
	    !VALUE_IS_NUMBER (src->val))
		return;

	dst = sheet_cell_fetch (dst_sheet, target_col, target_row);
	if (!cell_has_expr_or_number_or_blank (dst))
		return;

	op = paste_op_to_expr_op (paste_flags);
	/* FIXME : This does not handle arrays, linked cells, ranges, etc. */
	if ((paste_flags & PASTE_CONTENTS) &&
	    (NULL != src->texpr || gnm_cell_has_expr (dst))) {
		GnmExpr const *old_expr    = contents_as_expr (dst->base.texpr, dst->value);
		GnmExpr const *copied_expr = contents_as_expr (src->texpr, src->val);
		GnmExprTop const *res = gnm_expr_top_new (gnm_expr_new_binary (old_expr, op, copied_expr));
		GnmExprTop const *relo = gnm_expr_top_relocate (res, rinfo, FALSE);
		if (relo) {
			gnm_cell_set_expr (dst, relo);
			gnm_expr_top_unref (relo);
		} else
			gnm_cell_set_expr (dst, res);
		gnm_expr_top_unref (res);
	} else {
		GnmValue  *value;
		GnmEvalPos pos;
		GnmExpr const *expr = gnm_expr_new_binary (
			gnm_expr_new_constant (value_dup (dst->value)),
			op,
			gnm_expr_new_constant (value_dup (src->val)));
		GnmExprTop const *texpr = gnm_expr_top_new (expr);

		eval_pos_init_cell (&pos, dst);
		pos.dep = NULL; /* no dynamic deps */
		value = gnm_expr_top_eval (texpr, &pos,
					   GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
		gnm_expr_top_unref (texpr);
		gnm_cell_set_value (dst, value);
	}
}
示例#6
0
static GnmExpr const *
xlsx_func_dist_handler (GnmExprList *args, guint n_args, char const *name, char const *name_p, char const *name_d)
{
	if (gnm_expr_list_length (args) != n_args) {
		GnmFunc  *f = gnm_func_lookup_or_add_placeholder (name);
		return gnm_expr_new_funcall (f, args);
	} else {
		GnmFunc  *f_if = gnm_func_lookup_or_add_placeholder ("if");
		GnmFunc  *f_p = gnm_func_lookup_or_add_placeholder (name_p);
		GnmFunc  *f_d = gnm_func_lookup_or_add_placeholder (name_d);
		GnmExprList *arg_cum, *args_c;
		GnmExpr const *cum;
		GnmValue const *constant;

		arg_cum = g_slist_nth (args, n_args - 1);
		args = g_slist_remove_link (args, arg_cum);
		cum = arg_cum->data;
		gnm_expr_list_free (arg_cum);

		constant = gnm_expr_get_constant (cum);

		if (constant == NULL || !VALUE_IS_NUMBER (constant)) {
			args_c = gnm_expr_list_copy (args);

			return gnm_expr_new_funcall3
				(f_if, cum,
				 gnm_expr_new_funcall (f_p, args),
				 gnm_expr_new_funcall (f_d, args_c));

		} else if (value_is_zero (constant)) {
			gnm_expr_free (cum);
			return gnm_expr_new_funcall (f_d, args);
		} else {
			gnm_expr_free (cum);
			return gnm_expr_new_funcall (f_p, args);
		}
	}
}
gnm_float
datetime_value_to_serial_raw (GnmValue const *v, GODateConventions const *conv)
{
	gnm_float serial;

	if (VALUE_IS_NUMBER (v))
		serial = value_get_as_float (v);
	else {
		char const *str = value_peek_string (v);
		GnmValue *conversion = format_match_number (str, go_format_default_date (), conv);

		if (conversion) {
			serial = value_get_as_float (conversion);
			value_release (conversion);
		} else
			serial = G_MAXINT;
	}

	if (serial < 0 && !gnm_datetime_allow_negative ())
		serial = G_MAXINT;

	return serial;
}
示例#8
0
/**
 * xlsx_func_r_q_output_handler:
 *
 * @out: #GnmConventionsOut
 * @func: #GnmExprFunction
 * @n: last index used for a parameter
 * @n_p: index of the probability argument, usually 0
 * @name:
 *
 * Print the appropriate simple function call
 */
static gboolean
xlsx_func_r_q_output_handler (GnmConventionsOut *out, GnmExprFunction const *func, int n, int n_p,
			      char const *name, char const *name_rt)
{
	GnmExprConstPtr const *ptr = func->argv;
	GString *target = out->accum;
	int use_lower_tail; /* 0: never; 1: always; 2: sometimes */
	int use_log;        /* 0: never; 1: always; 2: sometimes */

	if (func->argc <= n || func->argc > (n+3))
		return FALSE;

	if (func->argc > n+1) {
		GnmValue const *constant = gnm_expr_get_constant (ptr[n+1]);
		if (constant == NULL || !VALUE_IS_NUMBER (constant))
			use_lower_tail = 2;
		else
			use_lower_tail = value_is_zero (constant) ? 0 : 1;
	} else
		use_lower_tail = 1;
	if (func->argc > n+2) {
		GnmValue const *constant = gnm_expr_get_constant (ptr[n+2]);
		if (constant == NULL || !VALUE_IS_NUMBER (constant))
			use_log = 2;
		else
			use_log = value_is_zero (constant) ? 0 : 1;
	} else
		use_log = 0;

	if (use_lower_tail < 2 && use_log == 0) {
		/* R.Qx(a,b,c) --> name(a,b,c) */
		/* R.Qx(a,b,c) --> name(1-a,b,c) */
		xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, use_lower_tail, 0);
		return TRUE;
	} else if (use_lower_tail < 2 && use_log == 1) {
		/* R.Qx(a,b,c) --> name(exp(a),b,c) */
		/* R.Qx(a,b,c) --> name(1-exp(a),b,c) */
		xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, use_lower_tail, 1);
		return TRUE;
	} else if (/* use_lower_tail == 2 && */ use_log == 0) {
		/* R.Qx(a,b,c,d) --> if(d,name(a,b,c), name(1-a,b,c)) */
		g_string_append (target, "if(");
		gnm_expr_as_gstring (ptr[n+1], out);
		g_string_append_c (target, ',');
		xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, 1, 0);
		g_string_append_c (target, ',');
		xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, 0, 0);
		g_string_append_c (target, ')');
		return TRUE;
	} else if (use_lower_tail < 2 /* && use_log == 2 */) {
		/* R.Qx(a,b,c,d,e) -->
                               if(e,name(1-exp(a),b,c),name(1-a,b,c))*/
		/* R.Qx(a,b,c,d,e) -->
                          if(e,name(exp(a),b,c),name(a,b,c))*/
		g_string_append (target, "if(");
		gnm_expr_as_gstring (ptr[n+2], out);
		g_string_append_c (target, ',');
		xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, use_lower_tail, 1);
		g_string_append_c (target, ',');
		xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, use_lower_tail, 0);
		g_string_append_c (target, ')');
		return TRUE;
	} else /*if (use_lower_tail == 2 && use_log == 2 */ {
		/* R.Qx(a,b,c,d,e) -->
                          if(d,if(e,name(exp(a),b,c),name(a,b,c)),
                               if(e,name(1-exp(a),b,c),name(1-a,b,c)))*/
		g_string_append (target, "if(");
		gnm_expr_as_gstring (ptr[n+1], out);
		g_string_append (target, ",if(");
		gnm_expr_as_gstring (ptr[n+2], out);
		g_string_append_c (target, ',');
		xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, 1, 1);
		g_string_append_c (target, ',');
		xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, 1, 0);
		g_string_append (target, "),if(");
		gnm_expr_as_gstring (ptr[n+2], out);
		g_string_append_c (target, ',');
		xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, 0, 1);
		g_string_append_c (target, ',');
		xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, 0, 0);
		g_string_append (target, "))");
		return TRUE;
	}
}
示例#9
0
static gboolean
tool_random_engine_run_discrete_last_check (G_GNUC_UNUSED data_analysis_output_t *dao,
					    tools_data_random_t *info,
					    discrete_random_tool_t *param,
					    discrete_random_tool_local_t **continuity)
{
	discrete_random_tool_local_t *data;
	GnmValue *range = param->range;
	gnm_float cumprob = 0;
	int j = 0;
	int i;

	data = *continuity = g_new0 (discrete_random_tool_local_t, 1);
	data->n = range->v_range.cell.b.row - range->v_range.cell.a.row + 1;
	data->cumul_p = g_new (gnm_float, data->n);
	data->values = g_new0 (GnmValue *, data->n);

	for (i = range->v_range.cell.a.row;
	     i <= range->v_range.cell.b.row;
	     i++, j++) {
		GnmValue *v;
		gnm_float thisprob;
		GnmCell *cell = sheet_cell_get (range->v_range.cell.a.sheet,
					     range->v_range.cell.a.col + 1, i);

		if (cell == NULL ||
		    (v = cell->value) == NULL ||
		    !VALUE_IS_NUMBER (v)) {
			gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->wbc),
					 _("The probability input range "
					   "contains a non-numeric value.\n"
					   "All probabilities must be "
					   "non-negative numbers."));
			goto random_tool_discrete_out;
		}
		if ((thisprob = value_get_as_float (v)) < 0) {
			gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->wbc),
					 _("The probability input range "
					   "contains a negative number.\n"
					   "All probabilities must be "
					   "non-negative!"));
			goto random_tool_discrete_out;
		}

		cumprob += thisprob;
		data->cumul_p[j] = cumprob;

		cell = sheet_cell_get (range->v_range.cell.a.sheet,
				       range->v_range.cell.a.col, i);

		if (cell == NULL || cell->value == NULL) {
			gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->wbc),
					 _("None of the values in the value "
					   "range may be empty!"));
			goto random_tool_discrete_out;
		}

		data->values[j] = value_dup (cell->value);
	}

	if (cumprob != 0) {
		/* Rescale... */
		for (i = 0; i < data->n; i++) {
			data->cumul_p[i] /= cumprob;
		}
		return FALSE;
	}
	gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->wbc),
		_("The probabilities may not all be 0!"));

 random_tool_discrete_out:
	tool_random_engine_run_discrete_clear_continuity (continuity);
	return TRUE;
}