2
* common.h - Common functionality header
3
* Copyright (C) 2010, D Haley
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.
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.
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/>.
21
#include "wxPreprec.h"
22
#include <wx/treectrl.h>
24
//TODO: split this between wx and non-wx stuff
34
#include "mathfuncs.h"
36
#define wxCStr(a) wxString(a,*wxConvCurrent)
37
#define wxStr(a) wxString(a.c_str(),*wxConvCurrent)
39
#define stlStr(a) (const char *)a.mb_str()
42
extern const char *DTD_NAME;
43
extern const char *PROGRAM_NAME;
44
extern const char *PROGRAM_VERSION;
45
extern const char *FONT_FILE;
48
//OK, this is a bit tricky. We override the operators to call
49
//a callback, so the UI updates keep happening, even inside the STL function
52
class GreaterWithCallback
55
bool (*callback)(void);
56
//!Reduction frequency (use callback every k its)
58
//!Current reduction counter
59
unsigned int reduction;
60
//!pointer to progress value
63
//!Second argument is a "reduction" value to set the number of calls
64
//to the random functor before initiating a callback
65
GreaterWithCallback( bool (*ptr)(void),unsigned int red)
66
{ callback=ptr; reduction=redMax=red;};
68
bool operator()(const T &a, const T &b)
83
class EqualWithCallback
86
bool (*callback)(void);
87
//!Reduction frequency (use callback every k its)
89
//!Current reduction counter
90
unsigned int reduction;
91
//!pointer to progress value
94
//!Second argument is a "reduction" value to set the number of calls
95
//to the random functor before initiating a callback
96
EqualWithCallback( bool (*ptr)(void),unsigned int red)
97
{ callback=ptr; reduction=redMax=red;};
99
bool operator()(const T &a, const T &b)
114
//!Property types for wxPropertyGrid
117
PROPERTY_TYPE_BOOL=1,
118
PROPERTY_TYPE_INTEGER,
120
PROPERTY_TYPE_COLOUR,
121
PROPERTY_TYPE_STRING,
122
PROPERTY_TYPE_POINT3D,
123
PROPERTY_TYPE_CHOICE,
126
//!Allowable export ion formats
132
//Randomly select subset. Subset will be (somewhat) sorted on output
133
template<class T> size_t randomSelect(std::vector<T> &result, const std::vector<T> &source,
134
RandNumGen &rng, size_t num,unsigned int &progress,bool (*callback)())
136
//If there are not enough points, just copy it across in whole
137
if(source.size() < num)
140
result.resize(source.size());
141
for(size_t ui=0; ui<num; ui++)
142
result[ui] = source[ui];
150
size_t numTicksNeeded;
151
//If the number of items is larger than half the source size,
152
//switch to tracking vacancies, rather than data
153
if(num < source.size()/2)
156
numTicksNeeded=source.size()-num;
158
//Randomly selected items
160
std::vector<size_t> ticks;
161
ticks.resize(numTicksNeeded);
163
//Create an array of numTicksNeededbers and fill
164
for(size_t ui=0; ui<numTicksNeeded; ui++)
165
ticks[ui]=(size_t)(rng.genUniformDev()*(source.size()-1));
167
//Remove duplicates. Intersperse some callbacks to be nice
168
GreaterWithCallback<size_t> gFunctor(callback,50000);
169
std::sort(ticks.begin(),ticks.end(),gFunctor);
170
EqualWithCallback<size_t> eqFunctor(callback,50000);
171
std::unique(ticks.begin(),ticks.end(),eqFunctor);
173
std::vector<size_t> moreTicks;
174
//Top up with unique entries
175
while(ticks.size() +moreTicks.size() < numTicksNeeded)
179
//This is actually not too bad. the collision probability is at most 50%
180
//due the switching behaviour above, for any large number of items
181
//So this is at worst case nlog(n) (I think)
182
index =rng.genUniformDev()*(source.size()-1);
183
if(!binary_search(ticks.begin(),ticks.end(),index) &&
184
std::find(moreTicks.begin(),moreTicks.end(),index) ==moreTicks.end())
185
moreTicks.push_back(index);
189
ticks.reserve(numTicksNeeded);
190
for(size_t ui=0;ui<moreTicks.size();ui++)
191
ticks.push_back(moreTicks[ui]);
195
ASSERT(ticks.size() == numTicksNeeded);
199
//Transfer the output
200
unsigned int curProg=70000;
202
if(num < source.size()/2)
204
for(std::vector<size_t>::iterator it=ticks.begin();it!=ticks.end();it++)
207
result[pos]=source[*it];
211
progress= (unsigned int)((float)(curProg)/((float)num)*100.0f);
219
//Sort the ticks properly (mostly sorted anyway..)
220
std::sort(ticks.begin(),ticks.end(),gFunctor);
222
unsigned int curTick=0;
223
for(size_t ui=0;ui<num; ui++)
225
//Don't copy if this is marked
226
if(ui == ticks[curTick])
229
result[ui-curTick]=source[ui];
233
progress= (unsigned int)((float)(curProg)/((float)num)*100.0f);
245
//Randomly select subset. Subset will be (somewhat) sorted on output
246
template<class T> size_t randomDigitSelection(std::vector<T> &result, const size_t max,
247
RandNumGen &rng, size_t num,unsigned int &progress,bool (*callback)())
249
//If there are not enough points, just copy it across in whole
254
for(size_t ui=0; ui<num; ui++)
263
size_t numTicksNeeded;
264
//If the number of items is larger than half the source size,
265
//switch to tracking vacancies, rather than data
269
numTicksNeeded=max-num;
271
//Randomly selected items
273
std::vector<size_t> ticks;
274
ticks.resize(numTicksNeeded);
276
//Create an array of numTicksNeededbers and fill
277
for(size_t ui=0; ui<numTicksNeeded; ui++)
278
ticks[ui]=(size_t)(rng.genUniformDev()*(max-1));
280
//Remove duplicates. Intersperse some callbacks to be nice
281
GreaterWithCallback<size_t> gFunctor(callback,50000);
282
std::sort(ticks.begin(),ticks.end(),gFunctor);
283
EqualWithCallback<size_t> eqFunctor(callback,50000);
284
std::unique(ticks.begin(),ticks.end(),eqFunctor);
286
std::vector<size_t> moreTicks;
287
//Top up with unique entries
288
while(ticks.size() +moreTicks.size() < numTicksNeeded)
292
//This is actually not too bad. the collision probability is at most 50%
293
//due the switching behaviour above, for any large number of items
294
//So this is at worst case nlog(n) (I think)
295
index =rng.genUniformDev()*(max-1);
296
if(!binary_search(ticks.begin(),ticks.end(),index) &&
297
std::find(moreTicks.begin(),moreTicks.end(),index) ==moreTicks.end())
298
moreTicks.push_back(index);
302
ticks.reserve(numTicksNeeded);
303
for(size_t ui=0;ui<moreTicks.size();ui++)
304
ticks.push_back(moreTicks[ui]);
308
ASSERT(ticks.size() == numTicksNeeded);
312
//Transfer the output
313
unsigned int curProg=70000;
317
for(std::vector<size_t>::iterator it=ticks.begin();it!=ticks.end();it++)
324
progress= (unsigned int)((float)(curProg)/((float)num)*100.0f);
332
//Sort the ticks properly (mostly sorted anyway..)
333
std::sort(ticks.begin(),ticks.end(),gFunctor);
335
unsigned int curTick=0;
336
for(size_t ui=0;ui<num; ui++)
338
//Don't copy if this is marked
339
if(ui == ticks[curTick])
342
result[ui-curTick]=ui;
346
progress= (unsigned int)((float)(curProg)/((float)num)*100.0f);