ExperienceReport-jsachdev - Department of Computer and

advertisement
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
EXPERIENCE REPORT
FOR
CEN5070 TERM PROJECT
QUASI-RANDOM GENERATOR
BY
JASMEET SACHDEVA
APRIL 28, 2006
Acknowledgements
Dr. Edward Jones
Dr. Hongmei Chi
Chris Nowicki
1
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
INTRODUCTION
This report details my work on the Term Project for the CEN5070 – Software
Verification & Validation course taken in Spring, 2006. My term project had the
following requirement specifications:
Quasi-random Test Data Generation Library (qrandLib)
 Develop library of functions for generating quasi-random values based on data type and
ranges.
 Initial data types: integer, long, float, char, bool, string.
 Provide acceptable test of library.
In response to this I created the tool QRG (acronym for Quasi-Random
Generator). This is a library that provides the following functionality:
1. Generate Quasi-Random values.
2. Generate different streams of values in the same program.
3. Generate different streams of values controlled by the system. This ensures
different sequence of values on every run.
4. Generate stream of values based on user-provided initial seed/dimension.
This ensures the same sequence of values on every run.
5. Generate values of different data types – integer, long, float, char, boolean
and string.
6. Generate integer values from 0 to ?????????
7. Generate integer values between a given range.
8. Generate strings of different sizes.
9. Generate strings of different combinations: alphabets only, alphanumeric,
uppercase only, lower case only and mixed case.
In addition to the library I have developed the following:
1. A Test driver program to demonstrate the functionality of the library.
2. A Shell script to extract all the required files.
3. A zip file that contains all the files pertinent to the project.
This report is divided into the following sections:


Introduction – This section introduces the project and describes the agenda
of the report.
Background – This section explains the user’s need for this tool.
2
CEN5070 Term Project
April 28, 2006






Experience Report
Quasi-Random Generators
Research and Related Topics – This section gives a synopsis of the path my
research for this project took. It also deals with a description of related
topics, which are not an integral part of the tool, but need to be addressed
to provide a better understanding of the project.
Tool Architecture – This section gives an overview of the system
architecture.
Implementation – This section explains the detailed design and code for the
tool.
Configuration Details – This section provides a list of all the files pertinent
to this project and where they are available.
Conclusion – This section deals with an overview of what I have
accomplished, the lessons learned during the process and future work that
can expand this tool.
Appendix A – This Appendix gives the listing of the source code for the
test driver program – QRGTest.cpp, the class QRG.cpp and the header file
QRG.h
BACKGROUND
Once I read the requirement specifications, the first question I asked was,
“With all the numerous and advanced pseudo-random number generators readily
available, why did we need to create a library of quasi-random number generator?”
According to Dr. Jones the answer was two-fold. First is the overall project to
provide a fast, convenient and stable testing environment for the students and
instructors in the department. The students need it to test their coded programs
before they submit and the instructors need it to test and grade the submissions.
One of the major bottlenecks in testing is in the area of creating valid test-data.
Currently it is done manually and it requires both time and planning to create
balanced data. Therefore, a library of functions that would provide various data
types of random values would help in creating test data quickly and efficiently.
The second answer has to do with well-balanced test data. Pseudo-random values
though easily available do not guarantee well-distributed values in a given domain.
Hence the need for quasi-random values which fix this problem.
The bottom line was to provide a handy, flexible tool for the user to get different
streams of test data of any type and in any range.
3
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
RESEARCH AND RELATED TOPICS
The first most obvious information target was “Random Numbers” themselves. I
knew what they were but now was the time to convey the meaning in more refined
terms. One of the good definitions of random numbers was:
A sequence of integers or group of numbers, which show absolutely no
relationship to each other anywhere in the sequence. At any point, all numbers
have an equal chance of occurring, and they occur in an unpredictable fashion.
Randomness by its very definition is an attribute found only in natural events.
Some possible sources of randomness in nature are:
 Emissions from radioactive materials
 Quantum effects in semi-conductors
 Atmospheric turbulence
But these are not useful to us in themselves if we need to get a series of random
values. Yes devices can be attached to these events in order to garner the random
values and present them to the users in a suitable form. But these would be
complicated and very expensive. For most of our random-number requirements
these would not be feasible.
So the most obvious choice was to use computers to create random numbers.
Computers, which can only follow instructions, are as such not suitable to produce
randomness. So what we have in computers is contrived randomness i.e. a suitably
complex algorithm is used to calculate values that in their occurrence, mimic
randomness. Since it is not genuine randomness, it has been prefixed with the term
“Pseudo” meaning false. The characteristics of a good algorithm are:
 No Repeatability
 Good Numeric distribution
 Lack of predictability.
The first characteristic is a must for areas in cryptography and lottery number
generation but may not desired in our area of test data creation.
The following points sum up the Pseudo-Random Numbers quite neatly:
1. A pseudo-random value is created by a deterministic procedure/algorithm.
2. It is usually based on an initial value, called the “seed”.
4
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
3. If we use the same seed then the same sequence of numbers is generated
every time the program is run. In the same token, we could get a different
sequence of numbers by changing the seed.
4. There are no guarantees of a uniform distribution of the numbers in the
given domain.
5. Some of the applications that find use for pseudo-random numbers are:
a. Computer Modeling (e.g. Markov Chains)
b. Statistics
c. Experimental Design
d. Sampling
The natural progression of my research now took me to find out what “QuasiRandom Numbers” are. The following points provide a good description:
1. They are similar to Pseudo-Random Numbers except in their distribution.
2. The successive elements are designed to have a certain structure. Each
elements existence depends on what came before it.
3. They enable covering the probability domain in a uniform manner, which
simply put means that the values are more evenly distributed in a given
domain. This is explained by the two scatter plots in Figure 1 and 2. These
show the distribution pattern for Pseudo-Random Values and Quasi-Random
Values respectively.
4. These values are used in applications where a uniform sampling is desirable.
Hence they would be more suitable for our purposes.
Now that I had some grasp in the area of Random Numbers, I set about to look for
Random Number generators. I found that there was a plethora of Pseudo-Random
Numbers generators available. Most of them did all that was specified in the
requirements for this project. But that was not so in case of Quasi-Random
Generators. Though there were some available, they came with a lot of baggage.
This would make it harder for me to customize them to suit the requirements of
my project. Finally after a couple of weeks of struggle, Dr. Jones referred me to
Dr. Chi who had been a part of a project on Random Number Generators at Florida
State University. Dr. Chi provided me with a simple quasi-random number generator
that produces random numbers of data type double in the range of 0 to 1. This
generator suited our needs very well and formed the kernel of my project.
5
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
Figure 1 - Scatter Plot of Pseudo-Random Numbers
Figure 2 - Scatter Plot of Quasi-Random Numbers
6
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
TOOL ARCHITECTURE
As mentioned in previous section, the Quasi-Random number generator is the
kernel my project. It produces a stream of random numbers of data type double in
the range of 0 to 1. I have created a class called QRG – (Quasi-Random Generator)
that contains the methods to use the random numbers from the generator and
customize them according to the user requirements.
I have also created a test driver program – QRGTest – that provides to user
interface to test the various functions/methods of the class QRG. The details of
the class attributes and methods are provided in the next section.
The system architecture is as follows:
Figure 3 – System Architecture
7
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
IMPLEMENTATION
The QRG class has the following public methods:










QRG(char diff) – This is a constructor that is called if you want the system
to pick a random prime number as the seed/dimension for the sequence of
random values. This would ensure that a different sequence of numbers is
generated each time. It uses the millionth seconds of the time to get the
next prime number, which is then used as the seed/dimension.
QRG(long seed) – This constructor is called if you want the same sequence
of random numbers each time. You would have to give it the same prime
number as an argument.
quasiRandomGen() – This is the kernel function. It is a modified form of the
quasi-random generator given by Dr. Chi. It uses the attribute ‘primeseed’
that is set by the constructor to produce random values of data type double
in the range of 0 to 1.
randomIntGen() – This is the method that generates random numbers of
data type integer in the range of 0 to 2147483647.
randomIntGen(int rangemin, int rangemax) – This is the overloaded method
that will produce random integers within the range whose low end is
rangemin and high end is rangemax – provided as arguments.
randomDoubleGen() – This method generates random numbers of the data
type double in the range of 0.0 to 99999999.0
randomFloatGen() – This method generates random numbers of the data
type float in the range of 0.0 to 999999.0
randomBoolGen() – This method generates random numbers of the data type
boolean i.e. a sequence of 0’s and 1’s.
randomCharGen() – This method generates random values of the data type
char. It takes the random value generated by quasiRandomGen(), converts it
to a valid ASCII code and then converts it to its character.
randomStringGen(int strsize, char strtype) – This method uses the same
procedure as in randomCharGen() to produces the required number of
characters to produce a string of size strsize. In addition based on the
strtype, it will produce strings of mixed alphabets, uppercase alphabets,
lowercase alphabets or alphanumerics.
8
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
The following are the private methods in the class QRG:
 isPrime() – This method determines if the number passed as argument is a
prime or not. It returns 1 if the number is prime and 0 if it is not.
 GetPrimeSeed() – This method calls the get method to get the time in
millionth of a second and then finds the next prime number after that.
 missing??() – This method uses the time class to get the millionth of a
second.
CONFIGURATION DETAILS
The files that are submitted as part of the project are as follows:
1. QRG.cpp – This is the source code for the class QRG.
2. QRG.h – This is the header file for the class QRG.
3. QRG.o – This is the object file for the class QRG. Anytime you want to use
the class, you would compile your program with this object file. E.g. if your
program is called QRGTest.cpp then you would compile as follows to give an
executable named QRGTest:
> g++ QRGTest.cpp QRG.o -o QRGTest
4. QRGTest.cpp – This is the source code for a test driver program that
provides a user interface to test all the methods of the class QRG.
5. QRGTest – This is the executable for the test driver. To invoke it use:
> ./QRGTest
6. ProgramFiles.zip – This is a zipped file that contains all the above files in
the following directory structure:
QuasiRandomGenerator –|
|- SourceFiles --|
|
|- QRG.cpp
|
|- QRG.h
|
|- QRG.o
|
|- QRGTest.cpp
|
|- Executables --|
9
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
|- QRGTest
7. BuildProject.csh – This is a shell script to unzip the files from
ProgramFiles.zip. To invoke it make sure that the ProgramFiles.zip file is in
the same directory and then enter:
> csh BuildProject.csh
CONCLUSION
This was a very interesting project since it not only involved programming tasks but
also enabled me to know more about certain areas that I was not familiar with. I
think I have accomplished all the requirements that the project specifications
listed. I have tested the class in reference to the various types of random values it
produces. But the true test would be its usefulness in generating actual test data.
This would only happen when instructors and students use this class in real time.
One line of future work that Dr. Jones and I discussed was to do a similar project
for Pseudo-Random Generators. Another item on the to do list would be a
comparison study between the two in order to determine if the Quasi-Random
values have any advantage over the Pseudo-Random Values in the field of test data.
In conclusion, I had fun doing this and for once I finished with without undue
stress or time constraints. I am quite happy with the product and hope it will be
put to good use. I would like to extend a special thanks to Dr. Jones for guiding me
through my meanderings along different paths till I reached the one that suited us
both. I would also like to thank Dr. Chi for her timely provision of the quasi-random
generator. Thanks also to Chris Nowicki for always being there to act as sounding
board as well as helping me out of sticky situations.
10
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
APPENDIX A
//
cout << "(c) 2006, jsachdev Jasmeet Sachdeva" << endl <<
//34567891123456789212345678931234567894123456789512345678961234567897123456
// ----------------------------------------------------------------------// File Name:
QRG.cpp
//
// Program Name:
A class to Generate Quasi Random values
//
// Author:
jsachdev
Jasmeet Sachdeva
//
// Purpose:
This class uses a quasi random number generator to
//
produce values of different data types:
//
- double,
//
- float,
//
- integer,
//
- boolean,
//
- char,
//
- string.
//
// Input Files:
NONE
//
// Keyboard Inputs:
//
(1) diff - (Argument in constructor) char
//
Any char passed to get a random sequence of values
//
(2) seed - (Argument in constructor) long
//
A prime number in order to get a predicted sequence of
//
random numbers.
//
(3) rangemin - (Argument in randomIntGen()) int
//
the lower end of range for integer random numbers
//
(4) rangemax - (Argument in randomIntGen()) int
//
The upper end of range for integer random numbers
//
(5) strsize - (Argument in randomStringGen()) int
//
The size of the string generated as random value
//
(6) strtype - (Argument in randomStringGen()) char
//
The type of string to generate. String type can be //
'a' for mixed alphabets
//
'u' for upper case alphabets
//
'l' for lower case alphabets
//
'n' for alphanumerics
//
// Output Files: NONE.
//
// Outputs: As Returns
//
(1) randomint (Return)
Integer Value Returned
//
(2) randomdouble - (Return)
Double Value Returned
//
(3) randomfloat - (Return)
Float Value Returned
//
(4) randomstring - (Return)
String Value Returned
//
(5) randombool (Return)
Boolean Value Returned
//
(6) randomchar (Return)
Char Value Returned
//
// -----------------------------------------------------------------------
11
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
12
CEN5070 Term Project
April 28, 2006
#include
#include
#include
#include
#include
#include
Experience Report
Quasi-Random Generators
<iostream>
<fstream>
<stdlib.h>
<math.h>
<cmath>
<time.h>
#include "QRG.h"
using namespace std;
// ----------------------------------------------------------------------// Purpose:
This is constructor is called when you want a random
//
sequence of values. This method picks up the clock ticks
//
and finds the next prime number after that to create
//
the seed for the quasi random number generator.
// Arguments:
//
(1) diff - char
//
This argument is used to indicate you want a random sequence
//
Any character as an argument will suffice.
// Results/Circumstance: NONE
// ----------------------------------------------------------------------//34567891123456789212345678931234567894123456789512345678961234567897123456
QRG::QRG(char diff)
{
primeseed = getPrimeSeed();
// Get a seed to initialize the
// stream
nextn1 = 3;
// increment for seed less than
// 100000
nextn2 = 23;
// increment for seed more than
// 100000
}// End Constructor for first instance
//
//
//
//
//
//
//
//
//
//
//
----------------------------------------------------------------------Purpose:
This constructor should be called for every instance after
the first time one. This increments the prime array index
to change the dimension (seed) and pick a different stream
of numbers.
Arguments: NONE.
Results/Circumstance:
(1) PrimeArrayIndex - integer
This is the index to the Prime array and is incremented by 1.
-----------------------------------------------------------------------
QRG::QRG(long seed)
{
while (!isPrime(seed))
{
seed++;
}//End while
primeseed = seed;
}// End Constructor for any instance after first
13
CEN5070 Term Project
April 28, 2006
//
//
//
//
//
//
//
//
//
//
Experience Report
Quasi-Random Generators
----------------------------------------------------------------------Purpose:
This method calls a method to get time in millionth second
and then calls another method to find the next prime number
after it. It then returns the prime number to the calling
program.
Arguments: NONE
Results/Circumstance:
(1)
primeseed - double - RETURNED VALUE
This is the prime number calculated.
-----------------------------------------------------------------------
double QRG::getPrimeSeed()
{
long ticks = getTimeInTicks();
while (!isPrime(ticks))
{
ticks++;
}//End while
primeseed = ticks;
return primeseed;
}// End Method getPrimeSeed()
//
//
//
//
//
//
//
//
----------------------------------------------------------------------Purpose:
This method calculates time in millionth second and returns
it to the calling program.
Arguments: NONE
Results/Circumstance:
(1)
ticks - long int - RETURNED VALUE
This is the calculated time.
-----------------------------------------------------------------------
long QRG::getTimeInTicks()
{
time_t currTime;
// struct to store various components of
// time
currTime = time(NULL);
// call to class _ftime to get time
// components
long int ticks;
// variable to store the time in millionth
// second
ticks = (currTime % 10000000 + 1000);
return ticks;
}//End Method getTimeInTicks()
//
//
//
//
//
//
//
//
//
//
----------------------------------------------------------------------Purpose:
This method takes a number and checks if it prime.
Arguments:
(1) number - integer
The number to be check for Prime ness
Results/Circumstance:
(1) prime - bool
This value is returned to calling program - True if number is
prime, false if not.
-----------------------------------------------------------------------
14
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
bool QRG::isPrime(long number)
{
bool prime = 0;
double num;
num = number;
if (number < 2)
{
prime = 0;
}
else if (number == 2)
{
prime = 1;
}
else if (number % 2 == 0)
{
prime = 0;
}
else
{
prime = 1;
int root = sqrt(num);
for (int i = 3; i <= root && prime; i++)
{
prime = prime && number % i;
}
}
return prime;
}// End Method isPrime
//
//
//
//
//
//
//
//
//
----------------------------------------------------------------------Purpose:
This method of class QRG generates quasi random numbers
of data type double between 0 and 1. It is an adaption of
a quasi random generator provided by Dr. Chi
Arguments: NONE
Results/Circumstance:
(1) rannum - double
The generated random number is returned to the calling method
-----------------------------------------------------------------------
double QRG::quasiRandom()
{
double r = sqrt(primeseed);
double rannum;
int next;
if(primeseed < 100000.0)
{
next = nextn1 * nextn1;
}
else
{
next = nextn2 * nextn2;
}
rannum = r * next;
rannum = rannum - floor(rannum);
15
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
if(primeseed < 100000.0)
{
nextn1++;
}
else
{
nextn2++;
}
return rannum;
}//End Method quasiRandom
//
//
//
//
//
//
//
//
//
----------------------------------------------------------------------Purpose:
Method to Generate random values of integer datatype. It
calls the method quasiRandom to get a double random number
between 0 and 1 and then converts it to integer in the
default range 0 to 2147483647
Arguments: NONE
Results/Circumstance:
(1) randomInt - integer (Return)
Integer Value Returned
-----------------------------------------------------------------------
int QRG::randomIntGen()
{
double qnum = 0.0;
int randomint;
qnum = quasiRandom();
randomint = qnum * 1000000;
return randomint;
}//End Method randomIntGen
//
//
//
//
//
//
//
//
//
//
//
//
//
//
----------------------------------------------------------------------Purpose:
This is the same method randomIntGen overloaded to accept
the minimum and maximum values within which the random
numbers are desired.
Arguments:
(1) rangemin - integer
The minimum value for the range of random numbers to be
generated.
(2) rangemax - integer
The maximum value for the range of random numbers to be
generated.
Results/Circumstance:
(1) randomInt - integer (Return)
Integer Value Returned
-----------------------------------------------------------------------
int QRG::randomIntGen(int rangemin, int rangemax)
{
bool validrandom = 0;
double qnum = 0.0;
int randomint;
while ( !validrandom)
{
qnum = quasiRandom();
16
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
randomint = qnum * 10000000;
randomint = (randomint % rangemax) + 1;
if (randomint >= rangemin)
{
validrandom = 1;
}
else
{
if ((randomint < rangemin) && (randomint + rangemin < rangemax))
{
randomint = randomint + rangemin;
validrandom = 1;
}
}
}
return randomint;
}//End Method randomIntGen
// ----------------------------------------------------------------------// Purpose:
Method to Generate random values of double datatype. It
//
calls the method quasiRandom to get a double random number
//
between 0 and 1 and then converts it to a double in the
//
range 0.00 to 9999.99
// Arguments: NONE
// Results/Circumstance:
//
(1)
randomdouble - double (Return)
Double Value Returned
// ----------------------------------------------------------------------//34567891123456789212345678931234567894123456789512345678961234567897123456
double QRG::randomDoubleGen()
{
double qnum = 0.0;
double randomdouble;
qnum = quasiRandom();
randomdouble = qnum * 10000;
return randomdouble;
}//End Method randomDoubleGen
// ----------------------------------------------------------------------// Purpose:
Method to Generate random values of double datatype. It
//
calls the method quasiRandom to get a double random number
//
between 0 and 1 and then converts it to a float in the
//
range 0.00 to 9999.99
// Arguments: NONE
// Results/Circumstance:
//
(1)
randomfloat - float (Return)
Float Value Returned
// ----------------------------------------------------------------------float QRG::randomFloatGen()
{
double qnum = 0.0;
float randomfloat;
qnum = quasiRandom();
17
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
randomfloat = qnum * 10000;
return randomfloat;
}//End Method randomFloatGen
//34567891123456789212345678931234567894123456789512345678961234567897123456
// ----------------------------------------------------------------------// Purpose:
Method to Generate random values of string datatype. It gets
//
the string size and type of string as arguments. It calls
//
the method quasiRandom to get a double random number between
//
0 and 1 and then converts it to an integer. It compares the
//
integer against the ASCII codes for the upper and lower case
//
alphabets as well as numbers based on the type of string
//
requested. Once it finds a valid integer it converts it to
//
the character and concatenates to the string variable till
//
the string of desired length is formed. It returns that
//
value.
// Arguments:
//
(1)
stringsize - integer
//
The size of the string to be generated.
//
(2)
strtype - char
//
The type of string to be generated - 'a' for alphabets,
//
'u' for uppercase, 'l' for lowercase and 'n' for alphanumric
// Results/Circumstance:
//
(1)
randomstr - string (Return)
String Value Returned
// ----------------------------------------------------------------------string QRG::randomStringGen(int stringsize, char strtype)
{
int loopcount = 0;
double qnum = 0.0;
int randomintnum;
bool validrandom;
string randomstr = "";
if (strtype
{
strtype =
}
if (strtype
{
strtype =
}
if (strtype
{
strtype =
}
if (strtype
{
strtype =
}
== 'A')
'a';
== 'U')
'u';
== 'L')
'l';
== 'N')
'n';
switch (strtype)
{
case 'a':
{
18
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
while (loopcount < stringsize)
{
validrandom = 0;
while (!validrandom)
{
qnum = quasiRandom();
randomintnum = qnum * 1000;
if ((randomintnum > 64 && randomintnum < 91) ||
(randomintnum > 96 && randomintnum < 123))
{
randomstr = randomstr + static_cast<char>(randomintnum);
loopcount++;
validrandom = 1;
}//if
}//while(!validrandom)
}//while (loopcount < stringsize)
break;
}//case 'a'
case 'u':
{
while (loopcount < stringsize)
{
validrandom = 0;
while (!validrandom)
{
qnum = quasiRandom();
randomintnum = qnum * 1000;
if (randomintnum > 64 && randomintnum < 91)
{
randomstr = randomstr + static_cast<char>(randomintnum);
loopcount++;
validrandom = 1;
}
}
}
break;
}
case 'l':
{
while (loopcount < stringsize)
{
validrandom = 0;
while (!validrandom)
{
qnum = quasiRandom();
randomintnum = qnum * 1000;
if (randomintnum > 96 && randomintnum < 123)
{
randomstr = randomstr + static_cast<char>(randomintnum);
loopcount++;
validrandom = 1;
}
}
}
break;
}
19
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
case 'n':
{
while (loopcount < stringsize)
{
validrandom = 0;
while (!validrandom)
{
qnum = quasiRandom();
randomintnum = qnum * 1000;
if ((randomintnum > 47 && randomintnum < 57) ||
(randomintnum > 64 && randomintnum < 91) ||
(randomintnum > 96 && randomintnum < 123))
{
randomstr = randomstr + static_cast<char>(randomintnum);
loopcount++;
validrandom = 1;
}
}
}
break;
}
default:
{
cout << "ERROR: Wrong String Type" << endl;
}
}
return randomstr;
}//End Method randomStringGen()
//
//
//
//
//
//
//
//
//
----------------------------------------------------------------------Purpose:
Method to Generate random values of boolean datatype. It
calls the method quasiRandom to get a double random number
between 0 and 1 and then converts it to an integer. It gets
the modulus of the integer by 2 and returns that value.
Arguments: NONE
Results/Circumstance:
(1)
randombool - bool (Return)
Boolean Value Returned
-----------------------------------------------------------------------
bool QRG::randomBoolGen()
{
double qnum = 0.0;
int randomintnum;
bool randombool;
qnum = quasiRandom();
randomintnum = qnum * 10;
randombool = randomintnum % 2;
return randombool;
}//End Method randomBoolGen()
20
CEN5070 Term Project
April 28, 2006
//
//
//
//
//
//
//
//
//
//
//
Experience Report
Quasi-Random Generators
----------------------------------------------------------------------Purpose:
Method to Generate random values of char datatype. It calls
the method quasiRandom to get a double random number between
0 and 1 and then converts it to an integer. It compares the
integer against the ASCII codes for the upper and lower case
alphabets. Once it finds a valid integer it converts it to
the character and returns that value.
Arguments: NONE
Results/Circumstance:
(1)
randomchar - char (Return)
Char Value Returned
-----------------------------------------------------------------------
char QRG::randomCharGen()
{
double qnum = 0.0;
int randomintnum;
char randomchar;
bool validrandom = 0;
while (!validrandom)
{
qnum = quasiRandom();
randomintnum = qnum * 1000;
if ((randomintnum > 47 && randomintnum < 57) ||
(randomintnum > 64 && randomintnum < 91) ||
(randomintnum > 96 && randomintnum < 123))
{
randomchar = static_cast<char>(randomintnum);
validrandom = 1;
}
}
return randomchar;
}//End Method randomCharGen()
21
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
// ----------------------------------------------------------------------// File Name:
QRG.h
//
// Program Name:
The header file to the class QRG.cpp used to Generate
//
Quasi Random values
//
// Author:
jsachdev
Jasmeet Sachdeva
//
// Purpose:
This is a header file that gives a list of attributes
//
and methods for the class QRG
// Input Files:
NONE
//
// Keyboard Inputs:NONE
//
// Output Files:
NONE.
//
// Screen Outputs: NONE
// ----------------------------------------------------------------------#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <math.h>
#include <cmath>
#include <time.h>
#include <string>
using namespace std;
// QRG Class Definition
class QRG
{
public:
//Constructor to get a random sequence of values. Give any char
//as argument
QRG(char diff);
//
cout << "(c) 2006, jsachdev Jasmeet Sachdeva" << endl <<
//34567891123456789212345678931234567894123456789512345678961234567897123456
//Constructor to get a sequence of random values based on the
//given prime number that is used as a seed/dimension
QRG(long seed);
//Method to generate random sequence of integers. This is used
//when no range is provided.
int randomIntGen();
//Overload Method to generate random sequence of integers within
//a given range. Provide the lower end and high end of the range
//as arguments
int randomIntGen(int rangemin, int rangemax);
//Method to generate random sequence of double numbers.
double randomDoubleGen();
22
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
//Method to generate random sequence of float numbers.
float randomFloatGen();
//Method to generate random sequence of boolean values.
bool randomBoolGen();
//Method to generate random sequence of char values.
char randomCharGen();
//Method to generate random sequence of strings. The arguments dictate
//the size of the string (stringsize) and the type of string (strtype)
//String type can be //'a' for mixed alphabets
//'u' for upper case alphabets
//'l' for lower case alphabets
//'n' for alphanumerics
string randomStringGen(int stringsize, char strtype);
private:
int nextn1;
random
// integer to determine next
// number in sequence if primeseed
// is less than 10000
int nextn2;
determine next
// another integer to
// random number in sequence if
// primeseed is more than 10000
double primeseed;
// the prime number used to as
a
// dimension for random sequence
//Private method to return a random prime number
double getPrimeSeed();
//Private method to return the clock ticks in millionth of a second
long int getTimeInTicks();
//Private method to check if the given number (as argument) is prime.
//Returns 1 if it is and 0 if it is not
bool isPrime(long number);
//Private method to create the quasi random values. Initial program
//provided by Dr. Chi. Customized for this class by Jasmeet Sachdeva
double quasiRandom();
};//End QRG class definition
23
CEN5070 Term Project
April 28, 2006
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
Experience Report
Quasi-Random Generators
----------------------------------------------------------------------File Name:
QRGTest.cpp
Program Name: A Test driver program to test the class QRG.cpp which is
used to Generate Quasi Random values.
Author:
Purpose:
jsachdev
Jasmeet Sachdeva
This test driver provides a user interface to enable the
user to be able to test the class properly. It provides a
menu that allows the user to select the data type of the
random value to be selected.
It then asks the user for the number of random values to
be generated and if the user wants to preset the random
stream of values.
If the datatype is integer, it asks the user for a range
if any.
If the datatype is string then it asks for the size of the
string as well as its type.
It then calls the relevant method and returns the number
of values asked.
Input Files:
NONE
Keyboard Inputs:
(1) randomtype - char
A char to indicate the data type for the random value.
'd' for datatype double
'f' for datatype float
'i' for datatype integer
'b' for datatype boolean
'c' for datatype char
's' for datatype string
(2) randomcount int
The number of random values to be generated
(3) randomstream - char
Whether to generate a random sequence or set sequence
based on the given prime number. values 'y' or 'n'
(4) primenum - double
The prime number to be used as seed if you said 'n' for
randomstream.
(5) range - char
Whether the integer values are generated within a range.
values 'y' or 'n'
(6) rangelow - int
The low end of range if range is desired.
(7) rangehigh - int
The high end of range if range is desired.
(8) strsize - int
The size of the string value to be generated
(9) strtype - char
The type of string to generate. String type can be 'a' for mixed alphabets
'u' for upper case alphabets
'l' for lower case alphabets
'n' for alphanumerics
24
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
// Output Files: NONE.
//
// Outputs: On Screen
//
(1) randomint Integer Value generated
//
(2) randomdouble - Double Value generated
//
(3) randomfloat - Float Value generated
//
(4) randomstring - String Value generated
//
(5) randombool Boolean Value generated
//
(6) randomchar Char Value generated
//
// ----------------------------------------------------------------------#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <math.h>
#include <cmath>
#include <time.h>
#include "QRG.h"
using namespace std;
// --------------------------------------------------------------------// Purpose:
This function takes the random datatype and changes any
//
uppercase values to lower case.
// Arguments: randomtype char - datatype to be generated
//
// Results/Circumstance:
//
(1) randomtype - changed to lowercase
// --------------------------------------------------------------------char changeCase(char randomtype)
{
if (randomtype == 'D')
{
randomtype = 'd';
}
if (randomtype == 'F')
{
randomtype = 'f';
}
if (randomtype == 'I')
{
randomtype = 'i';
}
if (randomtype == 'B')
{
randomtype = 'b';
}
if (randomtype == 'C')
{
randomtype = 'c';
}
if (randomtype == 'S')
{
randomtype = 's';
}
25
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
return randomtype;
}//End changeCase()
//
//
//
//
//
//
//
--------------------------------------------------------------------Purpose:
This is the main program that tests the class QRG.cpp
Arguments: SEE MAIN COMMENT BLOCK
Results/Circumstance:
SEE MAIN COMMENT BLOCK
---------------------------------------------------------------------
int main()
{
cout << endl << endl;
cout << "
WELCOME TO QUASI RANDOM NUMBER GENERATOR
cout << endl << endl << endl;
";
char another = 'y';
//variable to check if user wants another set of
//random values
char randomtype;
int randomcount;
//variable to determine the datatype of random
//values
//number of random values to be generated
char randomstream;
//'y' to generate a random sequence of randoms
//'n' to generate a sequence based on given
//prime number
long primenum;
//the prime number to seed the random generation
char range;
//'y' to generate integers within a range. Else 'n'
int rangelow;
//if 'y' to range then give low end of range
int rangehigh;
//if 'n' to range then give high end of range
int strsize;
//size of string values to be generated
char strtype;
//Type of string to be generated.
//Main while loop to give user chance to generate another set of
//random values
while ((another == 'y') || (another == 'Y'))
{//start Main While loop
//Present Main
cout << "Enter
cout << "d for
cout << "f for
cout << "i for
cout << "b for
cout << "c for
cout << "s for
cout << endl;
menu
the type
datatype
datatype
datatype
datatype
datatype
datatype
of Random Number you want: " << endl << endl;
double" << endl;
float" << endl;
integer" << endl;
boolean" << endl;
char" << endl;
string" << endl;
26
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
cin >> randomtype;
//Handle error when data type is not correct
while ((randomtype != 'd') && (randomtype != 'D') &&
(randomtype != 'f') && (randomtype != 'F') &&
(randomtype != 'i') && (randomtype != 'I') &&
(randomtype != 'b') && (randomtype != 'B') &&
(randomtype != 'c') && (randomtype != 'C') &&
(randomtype != 's') && (randomtype != 'S'))
{//Start while loop 2
cout << endl << "Wrong Data Type!!" << endl;
cout << "Please enter the correct datatype." << endl << endl;
cout << "d for datatype double" << endl;
cout << "f for datatype float" << endl;
cout << "i for datatype integer" << endl;
cout << "b for datatype boolean" << endl;
cout << "c for datatype char" << endl;
cout << "s for datatype string" << endl;
cin >> randomtype;
}//end while loop 2
//Call the function to change the case for randomtype
randomtype = changeCase(randomtype);
//Prompt for count of values to be generated
cout << endl << "How many random numbers you want to generate?
cin >> randomcount;
//Prompt for random sequence or sequence by given prime number
cout << endl << "Do you want a random stream (y or n)? ";
cin >> randomstream;
if ((randomstream != 'y') && (randomstream != 'Y') &&
(randomstream != 'n') && (randomstream != 'N'))
{
randomstream = 'y';
}
if ((randomstream == 'n') || (randomstream == 'N'))
{
cout << endl << "Give a prime number as a seed: ";
cin >> primenum;
}
else
{
primenum = -1;
}
//Generate values based on datatype
switch (randomtype)
{
case 'd': //for datatype double
{
double randouble;
27
";
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
if (primenum == -1)
{
QRG r1('y');
//class instantiation for random sequence
for (int i = 0; i < randomcount; i++)
{
randouble = r1.randomDoubleGen();
cout << endl << "Double Random Number : " << randouble;
}
}
else
{
QRG r1(primenum);
//class instantiation with seed
for (int i = 0; i < randomcount; i++)
{
randouble = r1.randomDoubleGen();
cout << endl << "Double Random Number : " <<
randouble;
}
}
break;
}
case 'f'://for datatype float
{
float ranfloat;
if (primenum == -1)
{
QRG r1('y');
//class instantiation for random sequence
for (int i = 0; i < randomcount; i++)
{
ranfloat = r1.randomFloatGen();
cout << endl << "Float Random Number : " << ranfloat;
}
}
else
{
QRG r1(primenum); //class instantiation with seed
for (int i = 0; i < randomcount; i++)
{
ranfloat = r1.randomFloatGen();
cout << endl << "Float Random Number : " <<
ranfloat;
}
}
break;
}
case 'i':
{
double raninteger;
cout << endl << "Do you want to specify a range (y or n)? ";
cin >> range;
if ((range == 'y') || (range == 'Y'))
{
cout << endl << "Enter the lower end of range: ";
cin >> rangelow;
cout << endl << "Enter the high end of range: ";
cin >> rangehigh;
28
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
if (primenum == -1)
{
QRG r1('y'); //class instantiation for random sequence
for (int i = 0; i < randomcount; i++)
{
raninteger = r1.randomIntGen(rangelow, rangehigh);
cout << endl << "Integer Random Number : " << raninteger;
}
}
else
{
QRG r1(primenum);
//class instantiation with seed
for (int i = 0; i < randomcount; i++)
{
raninteger = r1.randomIntGen(rangelow, rangehigh);
cout << endl << "Integer Random Number : " << raninteger;
}
}
}
else
{
if (primenum == -1)
{
QRG r1('y'); //class instantiation for random sequence
for (int i = 0; i < randomcount; i++)
{
raninteger = r1.randomIntGen();
cout << endl << "Integer Random Value : " << raninteger;
}
}
else
{
QRG r1(primenum);
//class instantiation with seed
for (int i = 0; i < randomcount; i++)
{
raninteger = r1.randomIntGen();
cout << endl << "Integer Random Value : " << raninteger;
}
}
}
break;
}
case 'b':
{
bool ranbool;
if (primenum == -1)
{
QRG r1('y');
//class instantiation for random sequence
for (int i = 0; i < randomcount; i++)
{
ranbool = r1.randomBoolGen();
cout << endl << "Bool Random Number : " << ranbool;
}
}
29
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
else
{
QRG r1(primenum);
//class instantiation with seed
for (int i = 0; i < randomcount; i++)
{
ranbool = r1.randomBoolGen();
cout << endl << "Bool Random Value : " <<
ranbool;
}
}
break;
}
case 'c':
{
char ranchar;
if (primenum == -1)
{
QRG r1('y');
//class instantiation for random sequence
for (int i = 0; i < randomcount; i++)
{
ranchar = r1.randomCharGen();
cout << endl << "Char Random Value : " << ranchar;
}
}
else
{
QRG r1(primenum);
//class instantiation with seed
for (int i = 0; i < randomcount; i++)
{
ranchar = r1.randomCharGen();
cout << endl << "Char Random Value : " <<
ranchar;
}
}
break;
}
case 's':
{
string ranstring;
cout << endl << "Enter the string size : " ;
cin >> strsize;
cout << endl << "Enter the type of string you want:-" << endl;
cout << "a for mixed case alphabets." << endl;
cout << "u for upper case alphabets." << endl;
cout << "l for lower case alphabets." << endl;
cout << "n for alphanumeric." << endl;
cin >> strtype;
if (primenum == -1)
{
QRG r1('y');
//class instantiation for random sequence
for (int i = 0; i < randomcount; i++)
{
ranstring = r1.randomStringGen(strsize, strtype);
cout << endl << "String Random Value : " << ranstring;
}
30
CEN5070 Term Project
April 28, 2006
Experience Report
Quasi-Random Generators
}
else
{
QRG r1(primenum);
//class instantiation with seed
for (int i = 0; i < randomcount; i++)
{
ranstring = r1.randomStringGen(strsize, strtype);
cout << endl << "String Random Value : " << ranstring;
}
}
break;
}
}
cout << endl << endl;
cout << "Do you want to generate another type of Random Number ";
cout << "(y or n)? ";
cin >> another;
}
return 0;
}
31
Download