treewide: Fix memory leaks from calls to relocate().
[pspp.git] / src / math / np.c
blobd297168c5967110f050f7a04de850e3438d4d2d8
1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 #include <config.h>
19 #include "math/np.h"
21 #include <gsl/gsl_cdf.h>
22 #include <math.h>
23 #include <stdlib.h>
25 #include "data/case.h"
26 #include "data/casewriter.h"
27 #include "libpspp/cast.h"
28 #include "libpspp/compiler.h"
29 #include "libpspp/misc.h"
30 #include "math/moments.h"
32 #include "gl/xalloc.h"
34 static void
35 destroy (struct statistic *stat)
37 struct np *np = UP_CAST (stat, struct np, parent.parent);
38 free (np);
41 static void
42 acc (struct statistic *s, const struct ccase *cx UNUSED,
43 double c, double cc, double y)
45 struct np *np = UP_CAST (s, struct np, parent.parent);
46 double rank = np->prev_cc + (c + 1) / 2.0;
48 double ns = gsl_cdf_ugaussian_Pinv (rank / (np->n + 1));
50 double z = (y - np->mean) / np->stddev;
52 double dns = z - ns;
54 maximize (&np->ns_max, ns);
55 minimize (&np->ns_min, ns);
57 maximize (&np->dns_max, dns);
58 minimize (&np->dns_min, dns);
60 maximize (&np->y_max, y);
61 minimize (&np->y_min, y);
63 struct ccase *cp = case_create (casewriter_get_proto (np->writer));
64 *case_num_rw_idx (cp, NP_IDX_Y) = y;
65 *case_num_rw_idx (cp, NP_IDX_NS) = ns;
66 *case_num_rw_idx (cp, NP_IDX_DNS) = dns;
67 casewriter_write (np->writer, cp);
69 np->prev_cc = cc;
72 /* Creates and returns a data structure whose accumulated results can be used
73 to produce a normal probability plot. The caller must supply the weighted
74 sample size N and the mean MEAN and variance VAR of the distribution, then
75 feed in the data with order_stats_accumulate() or
76 order_stats_accumulate_idx().
78 There is no function to produce the results, which appear in "struct np" for
79 passing directly to np_plot_create() or dnp_plot_create().
81 The caller must eventually destroy the returned structure, with
82 statistic_destroy(). */
83 struct np *
84 np_create (double n, double mean, double var)
86 struct caseproto *proto = caseproto_create ();
87 for (size_t i = 0; i < n_NP_IDX; i++)
88 proto = caseproto_add_width (proto, 0);
89 struct casewriter *writer = autopaging_writer_create (proto);
90 caseproto_unref (proto);
92 struct np *np = xmalloc (sizeof *np);
93 *np = (struct np) {
94 .parent = {
95 .parent = {
96 .destroy = destroy,
98 .accumulate = acc,
100 .n = n,
101 .mean = mean,
102 .stddev = sqrt (var),
103 .ns_min = DBL_MAX,
104 .ns_max = -DBL_MAX,
105 .dns_min = DBL_MAX,
106 .dns_max = -DBL_MAX,
107 .y_min = DBL_MAX,
108 .y_max = -DBL_MAX,
109 .writer = writer,
111 return np;