1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
/* histogram/find.c
*
* Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "include/rb_gsl_histogram.h"
/* determines whether to optimize for linear ranges */
#define LINEAR_OPT 1
int mygsl_find (const size_t n, const double range[], const double x, size_t * i)
{
size_t i_linear, lower, upper, mid;
if (x < range[0]) return -1;
if (x >= range[n]) return +1;
/* optimize for linear case */
#ifdef LINEAR_OPT
{
double u = (x - range[0]) / (range[n] - range[0]);
i_linear = (size_t) (n*u);
}
if (x >= range[i_linear] && x < range[i_linear + 1])
{
*i = i_linear;
return 0;
}
#endif
/* perform binary search */
upper = n;
lower = 0;
while (upper - lower > 1)
{
mid = (upper + lower) / 2;
if (x >= range[mid])
{
lower = mid;
}
else
{
upper = mid;
}
}
*i = lower;
/* sanity check the result */
if (x < range[lower] || x >= range[lower + 1])
{
GSL_ERROR ("x not found in range", GSL_ESANITY);
}
return 0;
}
int mygsl_find2d (const size_t nx, const double xrange[],
const size_t ny, const double yrange[],
const double x, const double y,
size_t * i, size_t * j)
{
int status = mygsl_find (nx, xrange, x, i);
if (status) return status;
status = mygsl_find (ny, yrange, y, j);
if (status) return status;
return 0;
}
int mygsl_find3d (const size_t nx, const double xrange[],
const size_t ny, const double yrange[],
const size_t nz, const double zrange[],
const double x, const double y, const double z,
size_t * i, size_t * j, size_t *k)
{
int status = mygsl_find (nx, xrange, x, i);
if (status) return status;
status = mygsl_find (ny, yrange, y, j);
if (status) return status;
status = mygsl_find (nz, zrange, z, k);
if (status) return status;
return 0;
}
|