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