/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * gog-log-reg.c : * * Copyright (C) 2005 Jean Brefort (jean.brefort@normalesup.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * USA */ #include #include "gog-log-reg.h" #include #include #include #include static int gog_log_reg_curve_build_values (GogLinRegCurve *rc, double const *x_vals, double const *y_vals, int n) { int i, used; double x, y; double xmin, xmax; gog_reg_curve_get_bounds (&rc->base, &xmin, &xmax); if (rc->x_vals == NULL) rc->x_vals = g_new0 (double*, 1); g_free (*rc->x_vals); *rc->x_vals = g_new (double, n); g_free (rc->y_vals); rc->y_vals = g_new (double, n); for (i = 0, used = 0; i < n; i++) { x = (x_vals)? x_vals[i]: i; y = y_vals[i]; if (x <= 0. || !go_finite (x) || !go_finite (y)) { if (rc->base.skip_invalid) continue; used = 0; break; } if (x < xmin || x > xmax) continue; rc->x_vals[0][used] = x; rc->y_vals[used] = y; used++; } return used; } static double gog_log_reg_curve_get_value_at (GogRegCurve *curve, double x) { return curve->a[0] + curve->a[1] * log (x); } static gchar const* gog_log_reg_curve_get_equation (GogRegCurve *curve) { if (!curve->equation) { GogLinRegCurve *lin = GOG_LIN_REG_CURVE (curve); if (lin->affine) curve->equation = (curve->a[0] < 0.)? ((curve->a[1] < 0)? g_strdup_printf ("y = \xE2\x88\x92%g ln(x) \xE2\x88\x92 %g", -curve->a[1], -curve->a[0]): g_strdup_printf ("y = %g ln(x) \xE2\x88\x92 %g", curve->a[1], -curve->a[0])): ((curve->a[1] < 0)? g_strdup_printf ("y = \xE2\x88\x92%g ln(x) + %g", -curve->a[1], curve->a[0]): g_strdup_printf ("y = %g ln(x) + %g", curve->a[1], curve->a[0])); else curve->equation = (curve->a[1] < 0)? g_strdup_printf ("y = \xE2\x88\x92%g ln(x)", -curve->a[1]): g_strdup_printf ("y = %g ln(x)", curve->a[1]); } return curve->equation; } static char const * gog_log_reg_curve_type_name (G_GNUC_UNUSED GogObject const *item) { /* xgettext : the base for how to name scatter plot objects * eg The 2nd plot in a chart will be called * Logarithmic regression2 */ return N_("Logarithmic regression"); } static void gog_log_reg_curve_class_init (GogRegCurveClass *reg_curve_klass) { GogLinRegCurveClass *lin_reg_klass = (GogLinRegCurveClass *) reg_curve_klass; GogObjectClass *gog_object_klass = (GogObjectClass *) reg_curve_klass; lin_reg_klass->lin_reg_func = go_logarithmic_regression; lin_reg_klass->build_values = gog_log_reg_curve_build_values; reg_curve_klass->get_value_at = gog_log_reg_curve_get_value_at; reg_curve_klass->get_equation = gog_log_reg_curve_get_equation; gog_object_klass->type_name = gog_log_reg_curve_type_name; } GSF_DYNAMIC_CLASS (GogLogRegCurve, gog_log_reg_curve, gog_log_reg_curve_class_init, NULL, GOG_LIN_REG_CURVE_TYPE)