libatomprobe
Library for Atom Probe Tomography (APT) computation
sampling.h
Go to the documentation of this file.
1 /*
2  * helper/sampling.h - statistical sampling functions
3  * Copyright (C) 2015, D Haley
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
8  * (at your option) any later version.
9 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU 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, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #ifndef ATOMPROBE_SAMPLING_H
20 #define ATOMPROBE_SAMPLING_H
21 #include <vector>
22 
24 #include "atomprobe/atomprobe.h"
25 #include "maths/lfsr.h"
26 
27 #include <gsl/gsl_randist.h>
28 #include <gsl/gsl_rng.h>
29 
30 namespace AtomProbe
31 {
32  //TODO : Deprecate me
33  //Randomly sample, without replacement.
34  void sampleIons(const std::vector<IonHit> &ions, float sampleFactor,
35  std::vector<IonHit> &sampled, bool strongRandom=true);
36 
37  //Randomly select subset. Subset ordering is not guaranteed to be either random or ordered
38  // Returns -1 on abort, otherwise returns number of randomly selected items
39  // if the supplied RNG is null, a "fast" linear shift algorithm, with bad randomisation will be used
40  template<class T> size_t randomSelect(std::vector<T> &result,
41  const std::vector<T> &source, size_t num,gsl_rng *rng)
42  {
43  //If there are not enough points, just copy it across in whole
44  if(source.size() <= num)
45  {
46  num=source.size();
47  result.resize(source.size());
48 #pragma omp parallel for
49  for(size_t ui=0; ui<num; ui++)
50  result[ui] = source[ui];
51 
52  return num;
53  }
54 
55  result.resize(num);
56 
57  if(rng)
58  {
59  result.resize(num);
60 
61  gsl_ran_choose (rng, &(result[0]), num, (void*)&(source[0]), source.size(), sizeof(IonHit));
62 
63  }
64  else
65  {
66  //Use a weak randomisation
68 
69  //work out the mask level we need to use
70  size_t i=1;
71  unsigned int j=0;
72  while(i < (source.size()<<1))
73  {
74  i=i<<1;
75  j++;
76  }
77 
78  //linear shift table starts at 3.
79  if(j<3) {
80  j=3;
81  i = 1 << j;
82  }
83 
84  size_t start;
85  //start at a random position in the linear state
86  start =(size_t)((double)rand()/RAND_MAX*i);
87  l.setMaskPeriod(j);
88  l.setState(start);
89 
90  size_t ui=0;
91  //generate unique weak random numbers.
92  while(ui<num)
93  {
94  size_t res;
95  res= l.clock();
96 
97  //use the source if it lies within range.
98  //drop it silently if it is out of range
99  if(res< source.size())
100  {
101  result[ui] =source[res];
102  ui++;
103  }
104  }
105 
106  }
107 
108  return num;
109  }
110 
111  //This function will not be efficient if num is close to nMax, and nMax is alrge
112  // Should have inversion detection to improve efficiency
113  template<class T> void randomIndices(std::vector<T> &res, size_t num, size_t nMax, gsl_rng *rng)
114  {
115  num = std::min(num,nMax);
116  res.resize(num);
117 
118  //Use reservoir sampling
119  for(auto i=0; i<num; i++)
120  res[i]=i;
121 
122  for(auto i=num; i<nMax;i++)
123  {
124  unsigned int j;
125  j = gsl_rng_uniform_int(rng,i);
126 
127  if(j <num)
128  res[j]=i;
129 
130  }
131 
132  }
133 
134 
135 
136 #ifdef DEBUG
137 //Unit tests
138 bool testSampling();
139 #endif
140 }
141 #endif
This class implements a Linear Feedback Shift Register (in software)
Definition: lfsr.h:30
void setState(size_t newState)
Set the internal lfsr state. Note 0 is the lock-up state.
Definition: lfsr.h:39
void setMaskPeriod(unsigned int newMask)
Set the mask to use such that the period is 2^n-1. 3 is minimum 60 is maximum.
Definition: lfsr.cpp:98
void sampleIons(const std::vector< IonHit > &ions, float sampleFactor, std::vector< IonHit > &sampled, bool strongRandom=true)
Definition: sampling.cpp:30
size_t randomSelect(std::vector< T > &result, const std::vector< T > &source, size_t num, gsl_rng *rng)
Definition: sampling.h:40
size_t clock()
Get a value from the shift register, and advance.
Definition: lfsr.cpp:152
void randomIndices(std::vector< T > &res, size_t num, size_t nMax, gsl_rng *rng)
Definition: sampling.h:113
This is a data holding class for POS file ions, from.
Definition: ionHit.h:36