Added script front-end for primer-design code
[htsworkflow.git] / htswanalysis / MACS / lib / gsl / gsl-1.11 / histogram / pdf2d.c
1 /* histogram/pdf2d.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 #include <gsl/gsl_histogram2d.h>
25
26 #include "find.c"
27
28 int
29 gsl_histogram2d_pdf_sample (const gsl_histogram2d_pdf * p,
30                             double r1, double r2,
31                             double *x, double *y)
32 {
33   size_t k;
34   int status;
35
36 /* Wrap the exclusive top of the bin down to the inclusive bottom of
37    the bin. Since this is a single point it should not affect the
38    distribution. */
39
40   if (r2 == 1.0)
41     {
42       r2 = 0.0;
43     }
44   if (r1 == 1.0)
45     {
46       r1 = 0.0;
47     }
48
49   status = find (p->nx * p->ny, p->sum, r1, &k);
50
51   if (status)
52     {
53       GSL_ERROR ("cannot find r1 in cumulative pdf", GSL_EDOM);
54     }
55   else
56     {
57       size_t i = k / p->ny;
58       size_t j = k - (i * p->ny);
59       double delta = (r1 - p->sum[k]) / (p->sum[k + 1] - p->sum[k]);
60       *x = p->xrange[i] + delta * (p->xrange[i + 1] - p->xrange[i]);
61       *y = p->yrange[j] + r2 * (p->yrange[j + 1] - p->yrange[j]);
62       return GSL_SUCCESS;
63     }
64 }
65
66 gsl_histogram2d_pdf *
67 gsl_histogram2d_pdf_alloc (const size_t nx, const size_t ny)
68 {
69   const size_t n = nx * ny;
70
71   gsl_histogram2d_pdf *p;
72
73   if (n == 0)
74     {
75       GSL_ERROR_VAL ("histogram2d pdf length n must be positive integer",
76                         GSL_EDOM, 0);
77     }
78
79   p = (gsl_histogram2d_pdf *) malloc (sizeof (gsl_histogram2d_pdf));
80
81   if (p == 0)
82     {
83       GSL_ERROR_VAL ("failed to allocate space for histogram2d pdf struct",
84                         GSL_ENOMEM, 0);
85     }
86
87   p->xrange = (double *) malloc ((nx + 1) * sizeof (double));
88
89   if (p->xrange == 0)
90     {
91       free (p);         /* exception in constructor, avoid memory leak */
92
93       GSL_ERROR_VAL ("failed to allocate space for histogram2d pdf xranges",
94                         GSL_ENOMEM, 0);
95     }
96
97   p->yrange = (double *) malloc ((ny + 1) * sizeof (double));
98
99   if (p->yrange == 0)
100     {
101       free (p->xrange);
102       free (p);         /* exception in constructor, avoid memory leak */
103
104       GSL_ERROR_VAL ("failed to allocate space for histogram2d pdf yranges",
105                         GSL_ENOMEM, 0);
106     }
107
108   p->sum = (double *) malloc ((n + 1) * sizeof (double));
109
110   if (p->sum == 0)
111     {
112       free (p->yrange);
113       free (p->xrange);
114       free (p);         /* exception in constructor, avoid memory leak */
115
116       GSL_ERROR_VAL ("failed to allocate space for histogram2d pdf sums",
117                         GSL_ENOMEM, 0);
118     }
119
120   p->nx = nx;
121   p->ny = ny;
122
123   return p;
124 }
125
126 int
127 gsl_histogram2d_pdf_init (gsl_histogram2d_pdf * p, const gsl_histogram2d * h)
128 {
129   size_t i;
130   const size_t nx = p->nx;
131   const size_t ny = p->ny;
132   const size_t n = nx * ny;
133
134   if (nx != h->nx || ny != h->ny)
135     {
136       GSL_ERROR ("histogram2d size must match pdf size", GSL_EDOM);
137     }
138
139   for (i = 0; i < n; i++)
140     {
141       if (h->bin[i] < 0)
142         {
143           GSL_ERROR ("histogram bins must be non-negative to compute"
144                      "a probability distribution", GSL_EDOM);
145         }
146     }
147
148   for (i = 0; i < nx + 1; i++)
149     {
150       p->xrange[i] = h->xrange[i];
151     }
152
153   for (i = 0; i < ny + 1; i++)
154     {
155       p->yrange[i] = h->yrange[i];
156     }
157
158   {
159     double mean = 0, sum = 0;
160
161     for (i = 0; i < n; i++)
162       {
163         mean += (h->bin[i] - mean) / ((double) (i + 1));
164       }
165
166     p->sum[0] = 0;
167
168     for (i = 0; i < n; i++)
169       {
170         sum += (h->bin[i] / mean) / n;
171         p->sum[i + 1] = sum;
172       }
173   }
174
175   return GSL_SUCCESS;
176 }
177
178
179 void
180 gsl_histogram2d_pdf_free (gsl_histogram2d_pdf * p)
181 {
182   free (p->xrange);
183   free (p->yrange);
184   free (p->sum);
185   free (p);
186 }