From ddac7861b4b2cf0f13392f3b3c961ff5795f797d Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 29 Jan 2022 16:56:30 -0800 Subject: [PATCH] mode: New order statistic. --- src/math/automake.mk | 1 + src/math/mode.c | 66 ++++++++++++++++++++++++++++++++++++++++++++ src/math/mode.h | 46 ++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 src/math/mode.c create mode 100644 src/math/mode.h diff --git a/src/math/automake.mk b/src/math/automake.mk index 5237583b60..fa9fb82ae7 100644 --- a/src/math/automake.mk +++ b/src/math/automake.mk @@ -39,6 +39,7 @@ src_math_libpspp_math_la_SOURCES = \ src/math/levene.c src/math/levene.h \ src/math/linreg.c src/math/linreg.h \ src/math/merge.c src/math/merge.h \ + src/math/mode.c src/math/mode.h \ src/math/moments.c src/math/moments.h \ src/math/np.c src/math/np.h \ src/math/order-stats.c src/math/order-stats.h \ diff --git a/src/math/mode.c b/src/math/mode.c new file mode 100644 index 0000000000..6c9f0c4563 --- /dev/null +++ b/src/math/mode.c @@ -0,0 +1,66 @@ +/* PSPP - a program for statistical analysis. + Copyright (C) 2008, 2009, 2011, 2022 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + 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, see . */ + +#include + +#include "math/mode.h" + +#include "data/casereader.h" +#include "data/val-type.h" +#include "data/variable.h" +#include "libpspp/assertion.h" +#include "libpspp/cast.h" + +#include "gl/xalloc.h" + + +static void +mode_destroy (struct statistic *stat) +{ + struct mode *mode = UP_CAST (stat, struct mode, parent.parent); + free (mode); +} + +static void +mode_accumulate (struct statistic *stat, const struct ccase *cx UNUSED, + double c, double cc UNUSED, double y) +{ + struct mode *mode = UP_CAST (stat, struct mode, parent.parent); + if (c > mode->mode_weight) + { + mode->mode = y; + mode->mode_weight = c; + mode->n_modes = 1; + } + else if (c == mode->mode_weight) + mode->n_modes++; +} + +struct mode * +mode_create (void) +{ + struct mode *mode = xmalloc (sizeof *mode); + *mode = (struct mode) { + .parent = { + .parent = { + mode_destroy, + }, + .accumulate = mode_accumulate, + }, + .mode = SYSMIS, + }; + return mode; +} diff --git a/src/math/mode.h b/src/math/mode.h new file mode 100644 index 0000000000..b2d1441ac7 --- /dev/null +++ b/src/math/mode.h @@ -0,0 +1,46 @@ +/* PSPP - a program for statistical analysis. + Copyright (C) 2004, 2008, 2009, 2022 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + 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, see . */ + +#ifndef MATH_MODE_H +#define MATH_MODE_H 1 + +#include + +#include "order-stats.h" + +/* To calculate the mode: + + - Create a "struct mode" with mode_create(). + - Feed in the data with order_stats_accumulate() or + order_stats_accumulate_idx(). The data must be in sorted order: if + necessary, use one of the sorting functions from sort.h to sort them. + - The members of "struct mode" then designate the mode. + - Destroy the data structure with statistic_destroy(). +*/ + +struct mode +{ + struct order_stats parent; + + /* These are initialized by order_stats_accumulate{_idx}(). */ + double mode; /* The value of the smallest mode, if 'n_modes' > 0. */ + double mode_weight; /* The weight of each mode, if 'n_modes' > 0. */ + size_t n_modes; /* The number of modes. */ +}; + +struct mode *mode_create (void); + +#endif /* mode.h */ -- 2.30.2