Added script front-end for primer-design code
[htsworkflow.git] / htswanalysis / MACS / lib / gsl / gsl-1.11 / histogram / pdf.c
1 /* histogram/pdf.c
2  * 
3  * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or (at
8  * your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19
20 #include <config.h>
21 #include <stdlib.h>
22 #include <gsl/gsl_errno.h>
23 #include <gsl/gsl_histogram.h>
24
25 #include "find.c"
26
27 double
28 gsl_histogram_pdf_sample (const gsl_histogram_pdf * p, double r)
29 {
30   size_t i;
31   int status;
32
33 /* Wrap the exclusive top of the bin down to the inclusive bottom of
34    the bin. Since this is a single point it should not affect the
35    distribution. */
36
37   if (r == 1.0)
38     {
39       r = 0.0;
40     }
41
42   status = find (p->n, p->sum, r, &i);
43
44   if (status)
45     {
46       GSL_ERROR_VAL ("cannot find r in cumulative pdf", GSL_EDOM, 0);
47     }
48   else
49     {
50       double delta = (r - p->sum[i]) / (p->sum[i + 1] - p->sum[i]);
51       double x = p->range[i] + delta * (p->range[i + 1] - p->range[i]);
52       return x;
53     }
54 }
55
56 gsl_histogram_pdf *
57 gsl_histogram_pdf_alloc (const size_t n)
58 {
59   gsl_histogram_pdf *p;
60
61   if (n == 0)
62     {
63       GSL_ERROR_VAL ("histogram pdf length n must be positive integer",
64                         GSL_EDOM, 0);
65     }
66
67   p = (gsl_histogram_pdf *) malloc (sizeof (gsl_histogram_pdf));
68
69   if (p == 0)
70     {
71       GSL_ERROR_VAL ("failed to allocate space for histogram pdf struct",
72                         GSL_ENOMEM, 0);
73     }
74
75   p->range = (double *) malloc ((n + 1) * sizeof (double));
76
77   if (p->range == 0)
78     {
79       free (p);         /* exception in constructor, avoid memory leak */
80
81       GSL_ERROR_VAL ("failed to allocate space for histogram pdf ranges",
82                         GSL_ENOMEM, 0);
83     }
84
85   p->sum = (double *) malloc ((n + 1) * sizeof (double));
86
87   if (p->sum == 0)
88     {
89       free (p->range);
90       free (p);         /* exception in constructor, avoid memory leak */
91
92       GSL_ERROR_VAL ("failed to allocate space for histogram pdf sums",
93                         GSL_ENOMEM, 0);
94     }
95
96   p->n = n;
97
98   return p;
99 }
100
101 int 
102 gsl_histogram_pdf_init (gsl_histogram_pdf * p, const gsl_histogram * h)
103 {
104   size_t i;
105   size_t n = p->n;
106
107   if (n != h->n)
108     {
109       GSL_ERROR ("histogram length must match pdf length", GSL_EINVAL);
110     }
111
112   for (i = 0; i < n; i++)
113     {
114       if (h->bin[i] < 0)
115         {
116           GSL_ERROR ("histogram bins must be non-negative to compute"
117                      "a probability distribution", GSL_EDOM);
118         }
119     }
120
121   for (i = 0; i < n + 1; i++)
122     {
123       p->range[i] = h->range[i];
124     }
125
126   {
127     double mean = 0, sum = 0;
128
129     for (i = 0; i < n; i++)
130       {
131         mean += (h->bin[i] - mean) / ((double) (i + 1));
132       }
133
134     p->sum[0] = 0;
135
136     for (i = 0; i < n; i++)
137       {
138         sum += (h->bin[i] / mean) / n;
139         p->sum[i + 1] = sum;
140       }
141   }
142
143   return GSL_SUCCESS;
144 }
145
146
147 void
148 gsl_histogram_pdf_free (gsl_histogram_pdf * p)
149 {
150   free (p->range);
151   free (p->sum);
152   free (p);
153 }