4228e35faae4244bfaf99a8ac6966694586b579a
[alexxy/gromacs.git] / src / gromacs / gmxana / binsearch.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2010,2011,2013,2014, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 #include "gmxpre.h"
36
37 #include "config.h"
38
39 #include <stdio.h>
40
41 #include "gromacs/utility/fatalerror.h"
42 #include "gromacs/utility/real.h"
43
44 /*Make range-array (Permutation identity) for sorting */
45 void rangeArray(int *ar, int size)
46 {
47     int i;
48     for (i = 0; i < size; i++)
49     {
50         ar[i] = i;
51     }
52 }
53
54 void pswap(int *v1, int *v2)
55 {
56     int temp;
57     temp = *v1;
58     *v1  = *v2;
59     *v2  = temp;
60 }
61
62
63 void Swap (real *v1, real *v2)
64 {
65     real temp;
66     temp = *v1;
67     *v1  = *v2;
68     *v2  = temp;
69 }
70
71
72
73 void insertionSort(real *arr, int *perm, int startndx, int endndx, int direction)
74 {
75     int i, j;
76
77     if (direction >= 0)
78     {
79         for (i = startndx; i <= endndx; i++)
80         {
81             j = i;
82
83             while (j > startndx && arr[j - 1] > arr[j])
84             {
85                 Swap(&arr[j], &arr[j-1]);
86                 pswap(&perm[j], &perm[j-1]);
87                 j--;
88             }
89
90         }
91
92     }
93
94     if (direction < 0)
95     {
96         for (i = startndx; i <= endndx; i++)
97         {
98             j = i;
99
100             while (j > startndx && arr[j - 1] < arr[j])
101             {
102                 Swap(&arr[j], &arr[j-1]);
103                 pswap(&perm[j], &perm[j-1]);
104                 j--;
105             }
106
107         }
108     }
109 }
110
111
112 int BinarySearch (real *array, int low, int high, real key, int direction)
113 {
114     int mid, max, min;
115     max = high+2;
116     min = low+1;
117
118 /*Iterative implementation*/
119
120     if (direction >= 0)
121     {
122         while (max-min > 1)
123         {
124             mid = (min+max)>>1;
125             if (key < array[mid-1])
126             {
127                 max = mid;
128             }
129             else
130             {
131                 min = mid;
132             }
133         }
134         return min;
135     }
136
137     else if (direction < 0)
138     {
139         while (max-min > 1)
140         {
141             mid = (min+max)>>1;
142             if (key > array[mid-1])
143             {
144                 max = mid;
145             }
146             else
147             {
148                 min = mid;
149             }
150         }
151         return min-1;
152
153     } /*end -ifelse direction*/
154     return -1;
155 }
156
157
158 int start_binsearch(real *array, int *perm, int low, int high,
159                     real key, int direction)
160 {
161     insertionSort(array, perm, low, high, direction);
162     return BinarySearch(array, low, high, key, direction);
163 }
164
165 int LinearSearch (double *array, int startindx, int stopindx,
166                   double key, int *count, int direction)
167 {
168     /*Iterative implementation - assume elements sorted*/
169     int i;
170     int keyindex;
171
172     if (direction >= 0)
173     {
174         keyindex = startindx;
175         for (i = startindx; i <= stopindx; i++)
176         {
177             (*count)++;
178             if (array[i] > key)
179             {
180                 keyindex = i-1;
181                 return keyindex;
182             }
183         }
184     }
185     else if (direction < 0)
186     {
187         keyindex = stopindx;
188         for (i = stopindx; i >= startindx; i--)
189         {
190             (*count)++;
191             if (array[i] > key)
192             {
193                 keyindex = i+1;
194                 return keyindex;
195             }
196         }
197     }
198
199     else
200     {
201         gmx_fatal(FARGS, "Startindex=stopindex=%d\n", startindx);
202     }
203
204     return -1;
205 }