1/*-------------------------------------------------------------------------
2 * drawElements C++ Base Library
3 * -----------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Random number generator utilities.
22 *//*--------------------------------------------------------------------*/
23
24#include "deRandom.hpp"
25
26inline bool operator== (const deRandom& a, const deRandom& b)
27{
28	return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;
29}
30
31inline bool operator!= (const deRandom& a, const deRandom& b)
32{
33	return a.x != b.x || a.y != b.y || a.z != b.z || a.w != b.w;
34}
35
36namespace de
37{
38
39bool Random::operator== (const Random& other) const
40{
41	return m_rnd == other.m_rnd;
42}
43
44bool Random::operator!= (const Random& other) const
45{
46	return m_rnd != other.m_rnd;
47}
48
49void Random_selfTest (void)
50{
51	// getBool()
52
53	{
54		static const bool expected[] = { true, false, false, false, true, true, false, false, false, false, false, false, true, false, true, false, false, false, false, true };
55		Random rnd(4789);
56		for (int i = 0; i < DE_LENGTH_OF_ARRAY(expected); i++)
57			DE_TEST_ASSERT(expected[i] == rnd.getBool());
58	}
59
60	// getInt(a, b)
61
62	{
63		static const int expected[] = { -6628, -6483, 802, -7758, -8463, 3165, 9216, 3107, 1851, 8707 };
64		Random rnd(4789);
65		for (int i = 0; i < DE_LENGTH_OF_ARRAY(expected); i++)
66			DE_TEST_ASSERT(expected[i] == rnd.getInt(-10000, 10000));
67	}
68
69	// getUint32()
70
71	{
72		static const deUint32 expected[] = { 3694588092u, 3135240271u, 882874943u, 2108407657u, 376640368u, 1395362929u, 2611849801u, 3151830690u, 901476922u, 989608184u };
73		Random rnd(4789);
74		for (int i = 0; i < DE_LENGTH_OF_ARRAY(expected); i++)
75			DE_TEST_ASSERT(expected[i] == rnd.getUint32());
76	}
77
78	// getUint64()
79
80	{
81		static const deUint64 expected[] = { 15868135030466279503ull, 3791919008751271785ull, 1617658064308767857ull, 11217809480510938786ull, 3871813899078351096ull, 14768747990643252542ull, 8163484985646009214ull, 14928018127607458387ull, 432108271545246292ull, 7318152987070448462ull };
82		Random rnd(4789);
83		for (int i = 0; i < DE_LENGTH_OF_ARRAY(expected); i++)
84			DE_TEST_ASSERT(expected[i] == rnd.getUint64());
85	}
86
87	// getFloat()
88
89	{
90		static const float	expected[]	= { 0.763413f, 0.679680f, 0.288965f, 0.854431f, 0.403095f, 0.198132f, 0.729899f, 0.741484f, 0.358263f, 0.686578f };
91		const float			epsilon		= 0.01f;
92		Random rnd(4789);
93		for (int i = 0; i < DE_LENGTH_OF_ARRAY(expected); i++)
94			DE_TEST_ASSERT(de::abs(expected[i] - rnd.getFloat()) < epsilon);
95	}
96
97	// getFloat(a, b)
98
99	{
100		static const float	expected[] = { 824.996643f, 675.039185f, -24.691774f, 987.999756f, 179.702286f, -187.365463f, 764.975647f, 785.724182f, 99.413582f, 687.392151f };
101		const float			epsilon		= 0.01f;
102		Random rnd(4789);
103		for (int i = 0; i < DE_LENGTH_OF_ARRAY(expected); i++)
104			DE_TEST_ASSERT(de::abs(expected[i] - rnd.getFloat(-542.2f, 1248.7f)) < epsilon);
105	}
106
107	// choose(first, last, resultOut, num)
108
109	{
110		static const int	items[]						= { 3, 42, 45, 123, 654, -123, -90, 0, 43 };
111		const int			numItemsPicked				= 5;
112		static const int	expected[][numItemsPicked]	=
113		{
114			{ -123, 42, -90, 123, 43 },
115			{ 43, 0, -90, 123, -123	},
116			{ 3, 42, 45, 123, 0 },
117			{ 3, 42, 45, -123, 654 },
118			{ 3, 43, 45, -90, -123 },
119			{ -90, 0, 45, -123, 654 },
120			{ 3, 42, 43, 123, -123 },
121			{ -90, 43, 45, 123, 654 },
122			{ 0, 42, 45, 123, 654 },
123			{ 0, -90, 45, -123, 654 }
124		};
125		Random rnd(4789);
126
127		for (int i = 0; i < DE_LENGTH_OF_ARRAY(expected); i++)
128		{
129			int itemsDst[numItemsPicked];
130			rnd.choose(DE_ARRAY_BEGIN(items), DE_ARRAY_END(items), &itemsDst[0], numItemsPicked);
131			for (int j = 0; j < numItemsPicked; j++)
132				DE_TEST_ASSERT(expected[i][j] == itemsDst[j]);
133		}
134	}
135
136	// choose(first, last)
137
138	{
139		static const int items[]		= { 3, 42, 45, 123, 654, -123, -90, 0, 43 };
140		static const int expected[]		= { 43, 123, -90, -90, 0, 3, 43, 0, 654, 43 };
141		Random rnd(4789);
142
143		for (int i = 0; i < DE_LENGTH_OF_ARRAY(expected); i++)
144			DE_TEST_ASSERT(expected[i] == rnd.choose<int>(DE_ARRAY_BEGIN(items), DE_ARRAY_END(items)));
145	}
146
147	// chooseWeighted(first, last, weights)
148
149	{
150		static const int	items[]		= { 3,		42,		45,		123,	654,	-123,	-90,	0 };
151		static const float	weights[]	= { 0.4f,	0.6f,	1.5f,	0.5f,	1.2f,	0.3f,	0.2f,	1.4f };
152		DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(items) == DE_LENGTH_OF_ARRAY(weights));
153		static const int	expected[]	= { -90, 654, 45, 0, 45, 45, -123, -90, 45, 654 };
154		Random rnd(4789);
155
156		for (int i = 0; i < DE_LENGTH_OF_ARRAY(expected); i++)
157			DE_TEST_ASSERT(expected[i] == rnd.chooseWeighted<int>(DE_ARRAY_BEGIN(items), DE_ARRAY_END(items), &weights[0]));
158	}
159
160	// suffle()
161
162	{
163		int					items[]									= { 3, 42, 45, 123, 654, -123, -90, 0, 43 };
164		static const int	expected[][DE_LENGTH_OF_ARRAY(items)]	=
165		{
166			{ 45, 43, 654, -123, 123, 42, -90, 0, 3 },
167			{ 0, 43, 3, 42, -123, -90, 654, 45, 123 },
168			{ 42, 43, 654, 3, 0, 123, -90, -123, 45 },
169			{ 3, 45, 43, 42, 123, 654, 0, -90, -123 },
170			{ 42, 45, -123, 0, -90, 654, 3, 123, 43 },
171			{ 654, -123, 3, 42, 43, 0, -90, 123, 45 },
172			{ 0, 3, 654, 42, -90, 45, -123, 123, 43 },
173			{ 654, 3, 45, 42, -123, -90, 123, 43, 0 },
174			{ -90, 123, 43, 654, 0, 42, 45, 3, -123 },
175			{ 0, -123, 45, 42, 43, 123, 3, -90, 654 }
176		};
177		Random rnd(4789);
178
179		for (int i = 0; i < DE_LENGTH_OF_ARRAY(expected); i++)
180		{
181			rnd.shuffle(DE_ARRAY_BEGIN(items), DE_ARRAY_END(items));
182			for(int j = 0; j < DE_LENGTH_OF_ARRAY(items); j++)
183				DE_TEST_ASSERT(expected[i][j] == items[j]);
184		}
185	}
186}
187
188} // de
189