Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
sampler.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
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/***********************************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***********************************************************************************************
22 * *
23 * Project Name : Sampler *
24 * *
25 * $Archive:: /VSS_Sync/wwlib/sampler.cpp $*
26 * *
27 * Original Author:: Hector Yee *
28 * *
29 * $Author:: Vss_sync $*
30 * *
31 * $Modtime:: 8/29/01 10:25p $*
32 * *
33 * $Revision:: 1 $*
34 * *
35 *---------------------------------------------------------------------------------------------*
36 * Functions: *
37 * RandomSamplingClass::Sample -- Samples randomly over a hypercube using Mersenne Twister *
38 * RegularSamplingClass::Sample -- Samples over a regular hypergrid *
39 * StratifiedSamplingClass::Sample -- samples over a regular hypergrid with random offset *
40 * QMCSamplingClass::Sample -- Samples using the Halton sequence *
41 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
42
43// Use Random Sampling if you're not sure
44// Use Regular Sampling if you're not concerned about bias
45// Use Stratified Sampling if you want good results in low dimensions
46// Use QMC if you want low discrepancy and you want reproduceablility
47
48#include "always.h"
49#include "sampler.h"
50#include "random.h"
51#include <math.h>
52#include <assert.h>
53#include <memory.h>
54
56
57RandomSamplingClass::RandomSamplingClass(unsigned int dimensions,unsigned char divisions):
58 SamplingClass(dimensions,divisions)
59{
60}
61
62/***********************************************************************************************
63 * RandomSamplingClass::Sample -- Samples randomly over a hypercube using Mersenne Twister *
64 * *
65 * *
66 * *
67 * *
68 * INPUT: *
69 * *
70 * OUTPUT: *
71 * *
72 * WARNINGS: *
73 * *
74 * HISTORY: *
75 * 6/11/2001 hy : Created. *
76 *=============================================================================================*/
77void RandomSamplingClass::Sample(float *target)
78{
79 unsigned int i;
80 for (i=0; i<Dimensions; i++)
81 {
82 target[i]=Random.Get_Float();
83 }
84}
85
86RegularSamplingClass::RegularSamplingClass(unsigned int dimensions,unsigned char divisions):
87 SamplingClass(dimensions,divisions)
88{
89 index=W3DNEWARRAY unsigned char[Dimensions];
90 Reset();
91}
92
94{
95 memset(index,0,sizeof(unsigned char)*Dimensions);
96}
97
102
103
104/***********************************************************************************************
105 * RegularSamplingClass::Sample -- Samples over a regular hypergrid *
106 * *
107 * *
108 * *
109 * *
110 * INPUT: *
111 * *
112 * OUTPUT: *
113 * *
114 * WARNINGS: *
115 * *
116 * HISTORY: *
117 * 6/11/2001 hy : Created. *
118 *=============================================================================================*/
120{
121 unsigned int i;
122
123 for (i=0; i<Dimensions; i++)
124 {
125 // minus one because we want to get 1.0f also
126 target[i]=(float) index[i]/(Divisions-1.0f);
127 }
128
129 // index[i] will always be 0..Divisons-1
130 // add 1 and carry mod Divisions
131 // e.g. increase x until x reaches Divisions
132 // then and only then increase y. Now z increases
133 // only when x=Divisions and y=Divisions etc..
134 for (i=0; i<Dimensions; i++)
135 {
136 index[i]++;
137 if (index[i]<Divisions) break;
138 index[i]=0;
139 }
140}
141
142StratifiedSamplingClass::StratifiedSamplingClass(unsigned int dimensions,unsigned char divisions):
143 SamplingClass(dimensions,divisions)
144{
145 index=W3DNEWARRAY unsigned char[Dimensions];
146 Reset();
147}
148
150{
151 memset(index,0,sizeof(unsigned char)*Dimensions);
152}
153
158
159/***********************************************************************************************
160 * StratifiedSamplingClass::Sample -- samples over a regular hypergrid with random offset *
161 * *
162 * *
163 * *
164 * *
165 * INPUT: *
166 * *
167 * OUTPUT: *
168 * *
169 * WARNINGS: *
170 * *
171 * HISTORY: *
172 * 6/11/2001 hy : Created. *
173 *=============================================================================================*/
175{
176 unsigned int i;
177
178 for (i=0; i<Dimensions; i++)
179 {
180 target[i]=(index[i]+Random.Get_Float())/(float) Divisions;
181 }
182
183 // index[i] will always be 0..Divisons-1
184 // add 1 and carry mod Divisions
185 // e.g. increase x until x reaches Divisions
186 // then and only then increase y. Now z increases
187 // only when x=Divisions and y=Divisions etc..
188 for (i=0; i<Dimensions; i++)
189 {
190 index[i]++;
191 if (index[i]<Divisions) break;
192 index[i]=0;
193 }
194}
195
196// first 100 primes
197
198const static int primes[]=
199{
200 2, 3, 5, 7, 11, 13, 17, 19, 23, 29
201, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71
202, 73, 79, 83, 89, 97,101,103,107,109,113
203,127,131,137,139,149,151,157,163,167,173
204,179,181,191,193,197,199,211,223,227,229
205,233,239,241,251,257,263,269,271,277,281
206,283,293,307,311,313,317,331,337,347,349
207,353,359,367,373,379,383,389,397,401,409
208,419,421,431,433,439,443,449,457,461,463
209,467,479,487,491,499,503,509,521,523,541
210};
211
212inline float RadInv(int i,int base)
213// returns the radical inverse of i in base b
214// basically write a number in base b and reverse it over the decimal point
215// e.g. RadInv(1) base 2 = 0.1 base 2 = 0.5
216{
217 float sum=0;
218 int residue;
219 float power=1.0f/base;
220
221 while (i!=0)
222 {
223 residue=i%base;
224 i/=base;
225 sum+=residue*power;
226 power/=base;
227 }
228
229 return sum;
230}
231
232QMCSamplingClass::QMCSamplingClass(unsigned int dimensions,unsigned char divisions):
233 SamplingClass(dimensions,divisions),
234 index(0)
235{
236 assert(Dimensions<100);
237}
238
239
240/***********************************************************************************************
241 * QMCSamplingClass::Sample -- Samples using the Halton sequence *
242 * *
243 * *
244 * *
245 * *
246 * INPUT: *
247 * *
248 * OUTPUT: *
249 * *
250 * WARNINGS: *
251 * *
252 * HISTORY: *
253 * 6/11/2001 hy : Created. *
254 *=============================================================================================*/
255void QMCSamplingClass::Sample(float *target)
256{
257 unsigned int i;
258 for (i=0; i<Dimensions; i++)
259 {
260 target[i]=RadInv(index,primes[i]);
261 }
262
263 index++;
264}
#define W3DNEWARRAY
Definition always.h:110
virtual void Sample(float *target)
Definition sampler.cpp:255
unsigned int index
Definition sampler.h:130
QMCSamplingClass(unsigned int dimensions, unsigned char divisions=0)
Definition sampler.cpp:232
RandomSamplingClass(unsigned int dimensions, unsigned char divisions=0)
Definition sampler.cpp:57
virtual void Sample(float *target)
Definition sampler.cpp:77
unsigned char * index
Definition sampler.h:102
RegularSamplingClass(unsigned int dimensions, unsigned char divisions=3)
Definition sampler.cpp:86
virtual ~RegularSamplingClass()
Definition sampler.cpp:98
virtual void Reset()
Definition sampler.cpp:93
virtual void Sample(float *target)
Definition sampler.cpp:119
unsigned int Dimensions
Definition sampler.h:77
SamplingClass(unsigned int dimensions, unsigned char divisions)
Definition sampler.h:69
unsigned char Divisions
Definition sampler.h:78
virtual void Reset()
Definition sampler.cpp:149
virtual void Sample(float *target)
Definition sampler.cpp:174
unsigned char * index
Definition sampler.h:115
StratifiedSamplingClass(unsigned int dimensions, unsigned char divisions=3)
Definition sampler.cpp:142
virtual ~StratifiedSamplingClass()
Definition sampler.cpp:154
float RadInv(int i, int base)
Definition sampler.cpp:212
Random4Class Random
Definition sampler.cpp:55