
10 changed files with 1178 additions and 0 deletions
Binary file not shown.
@ -0,0 +1,168 @@
@@ -0,0 +1,168 @@
|
||||
// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
|
||||
|
||||
#include <cstring> |
||||
#include <iostream> |
||||
|
||||
#include "auxiliary.h" |
||||
#include "general_functions.h" |
||||
|
||||
using namespace std; |
||||
|
||||
processArguments::processArguments( |
||||
int theArgc, const char* const theArgv[]): |
||||
argc(theArgc), argv(theArgv) |
||||
{ |
||||
checkIfArgcWithinRange(); |
||||
checkIfArg2Is0Or1OnlyAndSetMintOrMelt(); |
||||
checkIfCorrectNumberOfArgumentsForMintOrMelt(); |
||||
checkIf3rdOnwardArgsAreNotPositveInt(); |
||||
setRemainingDataMemberValues(); |
||||
printProcessedArguments(); |
||||
} |
||||
|
||||
void processArguments::checkIfArgcWithinRange() |
||||
{ |
||||
if (argc < 5 or argc > 6) |
||||
{ |
||||
cerr |
||||
<< "For Mint, no. of arguments must be 6 and for Melt no." |
||||
<< " of arguments must be 5 but recived " << argc |
||||
<< " argument(s).\n"; |
||||
exit(1); |
||||
} |
||||
} |
||||
|
||||
void processArguments::checkIfArg2Is0Or1OnlyAndSetMintOrMelt() |
||||
{ |
||||
string secondArgumentIncorrect = |
||||
string("Second argument can be only 0 for Mint and 1 for Melt") |
||||
+ ". But it is '" + argv[1] + "'.\n"; |
||||
if (is_whole_number(argv[1])) |
||||
{ |
||||
mintOrMelt = stoi(argv[1]); |
||||
if (mintOrMelt > 1 or mintOrMelt < 0) |
||||
{ |
||||
cerr << secondArgumentIncorrect; |
||||
exit(1); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
cerr << secondArgumentIncorrect; |
||||
exit(1); |
||||
} |
||||
} |
||||
|
||||
void processArguments::checkIfCorrectNumberOfArgumentsForMintOrMelt() |
||||
{ |
||||
if (mintOrMelt == mint and argc != 6) |
||||
{ |
||||
cerr |
||||
<< "For Mint, no. of arguments can be excatly 6 only. But " |
||||
<< "recived " << argc << ".\n"; |
||||
exit(1); |
||||
} |
||||
else if (mintOrMelt == melt and argc != 5) |
||||
{ |
||||
cerr |
||||
<< "For Melt, no. of arguments can be excatly 5 only. But " |
||||
<< "recived " << argc << ".\n"; |
||||
exit(1); |
||||
} |
||||
} |
||||
|
||||
void processArguments::checkIf3rdOnwardArgsAreNotPositveInt() |
||||
{ |
||||
checkIfArgumentIsNotPositiveInt(argv[2], "3rd"); |
||||
checkIfArgumentIsNotPositiveInt(argv[3], "4th"); |
||||
checkIfArgumentIsNotPositiveInt(argv[4], "5th"); |
||||
if (mintOrMelt == mint) |
||||
{ |
||||
checkIfArgumentIsNotPositiveInt(argv[5], "6th"); |
||||
} |
||||
} |
||||
|
||||
void processArguments::checkIfArgumentIsNotPositiveInt ( |
||||
const char* argument, string itsIndex) |
||||
{ |
||||
if (! is_natural_number(argument)) |
||||
{ |
||||
cerr |
||||
<< "All arguments from 3rd onward must be positive " |
||||
<< "integer but " << itsIndex << " i.e. '" << argument |
||||
<< "' is not.\n"; |
||||
exit(1); |
||||
} |
||||
} |
||||
|
||||
void processArguments::setRemainingDataMemberValues() |
||||
{ |
||||
seed = stoi(argv[2]); |
||||
length= stoi(argv[3]); |
||||
size= stoi(argv[4]); |
||||
if (mintOrMelt == mint) |
||||
{ |
||||
mod= stoi(argv[5]); |
||||
} |
||||
} |
||||
|
||||
|
||||
string processArguments::codewordType() const |
||||
{ |
||||
if (mintOrMelt == mint) |
||||
{ |
||||
return "mint"; |
||||
} |
||||
else if (mintOrMelt == melt) |
||||
{ |
||||
return "melt"; |
||||
} |
||||
else |
||||
{ |
||||
cerr_and_exit( |
||||
2, |
||||
"Unexpected Internal", |
||||
__FILE__, |
||||
__func__, |
||||
__LINE__); |
||||
} |
||||
} |
||||
|
||||
short processArguments::codewordInt() const |
||||
{ |
||||
return mintOrMelt; |
||||
} |
||||
|
||||
int processArguments::randomGeneratorSeed() const |
||||
{ |
||||
return seed; |
||||
} |
||||
|
||||
int processArguments::codewordLength() const |
||||
{ |
||||
return length; |
||||
} |
||||
|
||||
int processArguments::codebookSize() const |
||||
{ |
||||
return size; |
||||
} |
||||
|
||||
int processArguments::modulus() const |
||||
{ |
||||
return mod; |
||||
} |
||||
|
||||
void processArguments::printProcessedArguments() const |
||||
{ |
||||
cout |
||||
<< "Mode: " << codewordType() << " " |
||||
<< "Seed: " << seed << " " |
||||
<< "Codeword Length: " << length << " " |
||||
<< "Codebook size: " << size; |
||||
if (mintOrMelt == mint) |
||||
{ |
||||
cout << " Modulus: " << mod; |
||||
} |
||||
cout << endl; |
||||
} |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
|
||||
|
||||
#ifndef _AUXILIARY_H_ |
||||
#define _AUXILIARY_H_ |
||||
|
||||
#include <string> |
||||
|
||||
class processArguments |
||||
{ |
||||
public: |
||||
processArguments(int theArgc, const char* const theArgv[]); |
||||
std::string codewordType() const; |
||||
short codewordInt() const; |
||||
int randomGeneratorSeed() const; |
||||
int codewordLength() const; |
||||
int codebookSize() const; |
||||
int modulus() const; |
||||
private: |
||||
short mint = 0; |
||||
short melt = 1; |
||||
short mintOrMelt; |
||||
int seed; |
||||
int length; |
||||
int size; |
||||
int mod; |
||||
int argc; |
||||
const char* const *argv; |
||||
// if any of the checks fail, program exits immediately w/
|
||||
// error code 1
|
||||
void checkIfArgcWithinRange(); |
||||
void checkIfArg2Is0Or1Only(); |
||||
void checkIfArg2Is0Or1OnlyAndSetMintOrMelt(); |
||||
void checkIfCorrectNumberOfArgumentsForMintOrMelt(); |
||||
void checkIf3rdOnwardArgsAreNotPositveInt(); |
||||
void checkIfArgumentIsNotPositiveInt( |
||||
const char* argument, std::string itsIndex); |
||||
void setRemainingDataMemberValues(); |
||||
void printProcessedArguments() const; |
||||
}; |
||||
|
||||
#endif |
@ -0,0 +1,153 @@
@@ -0,0 +1,153 @@
|
||||
// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
|
||||
|
||||
#include <ctype.h> |
||||
#include <iostream> |
||||
#include <typeinfo> |
||||
|
||||
#include "cfc.h" |
||||
#include "generateValue.h" |
||||
|
||||
using namespace std; |
||||
|
||||
driver::driver(processArguments &theProgArgs): |
||||
ProgramArguments(theProgArgs) |
||||
{ |
||||
if (ProgramArguments.codewordType() == "mint") |
||||
{ |
||||
Mint aMint(Mint::zeroSymbol, ProgramArguments.modulus()); |
||||
processMintOrMelt(aMint); |
||||
} |
||||
else if (ProgramArguments.codewordType() == "melt") |
||||
{ |
||||
Melt aMelt(Melt::zeroSymbol); |
||||
processMintOrMelt(aMelt); |
||||
} |
||||
else |
||||
{ |
||||
cerr_and_exit( |
||||
2, |
||||
"unexpected", |
||||
__FILE__, |
||||
__func__, |
||||
__LINE__, |
||||
"ProgArgs.codewordType() is neither mint nor melt. Its " |
||||
+ ProgramArguments.codewordType() +'.' |
||||
); |
||||
} |
||||
} |
||||
|
||||
void driver::processMint(Codebook<Codeword<Mint>> &theCodebook) |
||||
{ |
||||
// adding rest of the randomly generated codewords
|
||||
for (int i=1; i < ProgramArguments.codebookSize(); i++) |
||||
{ |
||||
Codeword<Mint> aCodeword; |
||||
for (int j=0; j < ProgramArguments.codewordLength(); j++) |
||||
{ |
||||
int randomNumber = generateMint( |
||||
ProgramArguments.randomGeneratorSeed(), |
||||
ProgramArguments.modulus() |
||||
); |
||||
Mint aMint(randomNumber, ProgramArguments.modulus()); |
||||
aCodeword.push_back(aMint); |
||||
} |
||||
theCodebook.push_back(aCodeword); |
||||
} |
||||
theCodebook.Display(); |
||||
} |
||||
|
||||
void driver::processMelt(Codebook<Codeword<Melt>> &theCodebook) |
||||
{ |
||||
// adding rest of the randomly generated codewords
|
||||
for (int i=1; i < ProgramArguments.codebookSize(); i++) |
||||
{ |
||||
Codeword<Melt> aCodeword; |
||||
for (int j=0; j < ProgramArguments.codewordLength(); j++) |
||||
{ |
||||
char randomCharacter = generateMelt( |
||||
ProgramArguments.randomGeneratorSeed() |
||||
); |
||||
Melt aMelt(randomCharacter); |
||||
aCodeword.push_back(aMelt); |
||||
} |
||||
theCodebook.push_back(aCodeword); |
||||
} |
||||
theCodebook.Display(); |
||||
} |
||||
|
||||
void driver::processMint(Codebook<Codeword<Melt>> &theCodebook) |
||||
{ |
||||
cerr_and_exit( |
||||
2, |
||||
"unexpected", |
||||
__FILE__, |
||||
__func__, |
||||
__LINE__, |
||||
"function called for processing Melt cases." |
||||
); |
||||
} |
||||
|
||||
void driver::processMelt(Codebook<Codeword<Mint>> &theCodebook) |
||||
{ |
||||
cerr_and_exit( |
||||
2, |
||||
"unexpected", |
||||
__FILE__, |
||||
__func__, |
||||
__LINE__, |
||||
"function called for processing Mint cases." |
||||
); |
||||
} |
||||
|
||||
Mint::Mint(int Number, int Modulus) : modulus(Modulus) |
||||
{ |
||||
if (Number < modulus and Number >= 0) |
||||
{ |
||||
number = Number; |
||||
} |
||||
else if (Number > modulus) |
||||
{ |
||||
number = Number%modulus; |
||||
} |
||||
else if (Number < 0) |
||||
{ |
||||
|
||||
} |
||||
} |
||||
|
||||
int Mint::getNumber() const |
||||
{ |
||||
return number; |
||||
} |
||||
|
||||
int Mint::getSymbol() const |
||||
{ |
||||
return getNumber(); |
||||
} |
||||
|
||||
int Mint::operator-(const Mint mint2) const |
||||
{ |
||||
int beforeModulating = number - mint2.getNumber(); |
||||
int afterModulating = modulate(beforeModulating, modulus); |
||||
return afterModulating; |
||||
} |
||||
|
||||
Melt::Melt(char Character) |
||||
{ |
||||
character = tolower(Character); |
||||
} |
||||
|
||||
char Melt::getCharacter() const |
||||
{ |
||||
return character; |
||||
} |
||||
|
||||
char Melt::getSymbol() const |
||||
{ |
||||
return getCharacter(); |
||||
} |
||||
|
||||
int Melt::operator-(const Melt melt2) const |
||||
{ |
||||
return (character != melt2.getCharacter()); |
||||
} |
@ -0,0 +1,457 @@
@@ -0,0 +1,457 @@
|
||||
// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
|
||||
|
||||
#ifndef _CFC_H_ |
||||
#define _CFC_H_ |
||||
|
||||
#include <vector> |
||||
|
||||
#include "auxiliary.h" |
||||
#include "general_functions.h" |
||||
|
||||
class Mint |
||||
{ |
||||
public: |
||||
Mint() {}; |
||||
Mint(int Number, int Modulus); |
||||
int getNumber() const; |
||||
// standard function to be used for template codeword.
|
||||
// it just 'return getNumber();'
|
||||
int getSymbol() const; |
||||
int operator-(const Mint mint2) const; |
||||
static const int zeroSymbol = 0; |
||||
private: |
||||
int number; |
||||
int modulus; |
||||
}; |
||||
|
||||
class Melt |
||||
{ |
||||
public: |
||||
Melt() {}; |
||||
Melt(char Character); |
||||
char getCharacter() const; |
||||
// standard function to be used for template codeword.
|
||||
// it just 'return getCharacter();'
|
||||
char getSymbol() const; |
||||
int operator-(const Melt melt2) const; |
||||
static const char zeroSymbol = 'a'; |
||||
private: |
||||
char character; |
||||
}; |
||||
|
||||
template<typename T> |
||||
class Codeword |
||||
{ |
||||
public: |
||||
Codeword(); |
||||
Codeword(std::vector<T> &aTVector); |
||||
Codeword(const Codeword<T> &aCodeword); |
||||
void push_back(T symbol); |
||||
std::vector<T> getCodeword() const; |
||||
int getWeight() const; |
||||
// return -1 if encounters error i.e.:
|
||||
// If size of own codeword and codeword passed as argument
|
||||
// mismatch However It Will Not Happen Within Runtime Of This
|
||||
// Program. This is just defensive programming.
|
||||
int Distance(const Codeword<T> &aCodeword) const; |
||||
void Display() const; |
||||
int size() const; |
||||
T getSymbolByIndex(int index) const; |
||||
//bool isZeroCodeword() const;
|
||||
private: |
||||
void Weight(); |
||||
void incrementalWeight(); |
||||
//void calculateIfZeroCodeword();
|
||||
std::vector<T> codeword; |
||||
int weight = 0; |
||||
//bool isZerocodeword;
|
||||
}; |
||||
|
||||
template<typename T> |
||||
class Codebook |
||||
{ |
||||
public: |
||||
Codebook(); |
||||
Codebook(std::vector<T> &aTVector); |
||||
Codebook(const Codebook<T> &aCodebook); |
||||
void push_back(T codeword); |
||||
std::vector<T> getCodebook() const; |
||||
void Display() const; |
||||
int getMinimumWeight() const; |
||||
std::vector<std::vector<int>> getDistance() const; |
||||
int getMinimumDistance() const; |
||||
private: |
||||
// this function simply calls other three private functions
|
||||
void doCalculations(); |
||||
void minimumWeight(); |
||||
void calcDistance(); |
||||
void minimumDistance(); |
||||
void doIncrementalCalculations(); |
||||
void minimumIncrementalWeight(); |
||||
void calcIncrementalDistance(); |
||||
void minimumIncrementalDistance(); |
||||
int minWeight = 0; |
||||
std::vector<std::vector<int>> distance; |
||||
int minDistance = 0; |
||||
std::vector<T> codebook; |
||||
inline void updateIfNewMinimumDistance(int aDistance); |
||||
}; |
||||
|
||||
class driver |
||||
{ |
||||
public: |
||||
driver(processArguments &ProgArgs); |
||||
private: |
||||
template<typename U> |
||||
void processMintOrMelt(U aMintOrMelt); |
||||
void processMint(Codebook<Codeword<Mint>> &theCodebook); |
||||
void processMelt(Codebook<Codeword<Melt>> &theCodebook); |
||||
// placeholder functions which are never called and
|
||||
// will print error and quit if called
|
||||
void processMint(Codebook<Codeword<Melt>> &theCodebook); |
||||
void processMelt(Codebook<Codeword<Mint>> &theCodebook); |
||||
processArguments &ProgramArguments; |
||||
}; |
||||
|
||||
|
||||
/******TEMPLATE CLASES AND FUNCTIONS DEFINITION STARTS FROM HERE******/ |
||||
|
||||
|
||||
template<typename U> |
||||
void driver::processMintOrMelt(U aMintOrMelt) |
||||
{ |
||||
Codebook<Codeword<U>> theCodebook; |
||||
Codeword<U> aCodeword; |
||||
for (int i=0; i < 1 &&i < ProgramArguments.codebookSize(); i++) |
||||
{ |
||||
for (int j=0; j < ProgramArguments.codewordLength(); j++) |
||||
{ |
||||
aCodeword.push_back(aMintOrMelt); |
||||
} |
||||
theCodebook.push_back(aCodeword); |
||||
} |
||||
if (typeid(U) == typeid(Mint)) |
||||
{ |
||||
processMint(theCodebook); |
||||
} |
||||
else if (typeid(U) == typeid(Melt)) |
||||
{ |
||||
processMelt(theCodebook); |
||||
} |
||||
} |
||||
|
||||
template<typename T> |
||||
Codeword<T>::Codeword() |
||||
{ |
||||
} |
||||
|
||||
template<typename T> |
||||
Codeword<T>::Codeword(std::vector<T> &aTVector) |
||||
{ |
||||
for (T symbol: aTVector) |
||||
{ |
||||
codeword.push_back(symbol); |
||||
} |
||||
Weight(); |
||||
} |
||||
|
||||
template<typename T> |
||||
Codeword<T>::Codeword(const Codeword<T> &aCodeword) |
||||
{ |
||||
codeword = aCodeword.getCodeword(); |
||||
weight = aCodeword.getWeight(); |
||||
} |
||||
|
||||
template<typename T> |
||||
void Codeword<T>::push_back(T symbol) |
||||
{ |
||||
codeword.push_back(symbol); |
||||
incrementalWeight(); |
||||
} |
||||
|
||||
template<typename T> |
||||
std::vector<T> Codeword<T>::getCodeword() const |
||||
{ |
||||
return codeword; |
||||
} |
||||
|
||||
template<typename T> |
||||
int Codeword<T>::getWeight() const |
||||
{ |
||||
return weight; |
||||
} |
||||
|
||||
template<typename T> |
||||
int Codeword<T>::Distance(const Codeword<T> &aCodeword) const |
||||
{ |
||||
int distance = 0; |
||||
if (codeword.size() != aCodeword.size()) |
||||
{ |
||||
cerr_only( |
||||
"Internal", |
||||
__FILE__, |
||||
__func__, |
||||
__LINE__, |
||||
"For calculating Codeword Distance, no. of symbols in own" |
||||
" codeword and codeword passed as argument mismatch. " |
||||
"Though technically a possiblity, it should not happen " |
||||
"within the run of this program." |
||||
); |
||||
distance = -1; |
||||
} |
||||
else |
||||
{ |
||||
for (int i=0; i < size(); i++) |
||||
{ |
||||
distance += codeword[i] - aCodeword.getSymbolByIndex(i); |
||||
} |
||||
} |
||||
return distance; |
||||
} |
||||
|
||||
template<typename T> |
||||
void Codeword<T>::Display() const |
||||
{ |
||||
for(T symbol: codeword) |
||||
{ |
||||
std::cout << symbol.getSymbol() << " "; |
||||
} |
||||
std::cout << " Weight: " << weight << std::endl; |
||||
} |
||||
|
||||
template<typename T> |
||||
int Codeword<T>::size() const |
||||
{ |
||||
return codeword.size(); |
||||
} |
||||
|
||||
template<typename T> |
||||
T Codeword<T>::getSymbolByIndex(int index) const |
||||
{ |
||||
if (codeword.size() > index) |
||||
{ |
||||
return codeword[index]; |
||||
} |
||||
else |
||||
{ |
||||
cerr_only( |
||||
"internal", |
||||
__FILE__, |
||||
__func__, |
||||
__LINE__, |
||||
"Index symbol requqested is greater than cointainer size " |
||||
"An empty symbol of same type will be returned but this " |
||||
"will therefore give garbage result." |
||||
); |
||||
T emptySymbol; |
||||
return emptySymbol; |
||||
} |
||||
} |
||||
|
||||
template<typename T> |
||||
void Codeword<T>::Weight() |
||||
{ |
||||
weight = 0; |
||||
for (T symbol: codeword) |
||||
{ |
||||
if (symbol.getSymbol() != symbol.zeroSymbol) |
||||
{ |
||||
weight++; |
||||
} |
||||
} |
||||
} |
||||
|
||||
template<typename T> |
||||
void Codeword<T>::incrementalWeight() |
||||
{ |
||||
if (codeword[codeword.size()-1].getSymbol() |
||||
!= codeword[0].zeroSymbol) |
||||
{ |
||||
weight++; |
||||
} |
||||
} |
||||
|
||||
template<typename T> |
||||
Codebook<T>::Codebook() |
||||
{ |
||||
} |
||||
|
||||
template<typename T> |
||||
Codebook<T>::Codebook(std::vector<T> &aTVector) |
||||
{ |
||||
for (T codeword: aTVector) |
||||
{ |
||||
codebook.push_back(codeword); |
||||
} |
||||
doCalculations(); |
||||
} |
||||
|
||||
template<typename T> |
||||
Codebook<T>::Codebook(const Codebook<T> &aCodebook) |
||||
{ |
||||
minWeight = aCodebook.getMinimumWeight(); |
||||
distance = aCodebook.getDistance(); |
||||
minDistance = aCodebook.getMinimumDistance(); |
||||
codebook = aCodebook.getCodebook(); |
||||
} |
||||
|
||||
template<typename T> |
||||
void Codebook<T>::push_back(T codeword) |
||||
{ |
||||
codebook.push_back(codeword); |
||||
doIncrementalCalculations(); |
||||
} |
||||
|
||||
template<typename T> |
||||
std::vector<T> Codebook<T>::getCodebook() const |
||||
{ |
||||
return codebook; |
||||
} |
||||
|
||||
template<typename T> |
||||
void Codebook<T>::Display() const |
||||
{ |
||||
for (T codeword: codebook) |
||||
{ |
||||
codeword.Display(); |
||||
} |
||||
std::cout
|
||||
<< "Minimum Weight: " << minWeight << '\n' |
||||
<< "Minimum Distance: " << minDistance << '\n' |
||||
<< "Distances Table:" << std::endl; |
||||
for (auto row: distance) |
||||
{ |
||||
for (int eachDistance: row) |
||||
{ |
||||
std::cout << eachDistance << " "; |
||||
} |
||||
std::cout << "\b\n"; |
||||
} |
||||
std::cout << std::flush; |
||||
} |
||||
|
||||
template<typename T> |
||||
int Codebook<T>::getMinimumWeight() const |
||||
{ |
||||
return minWeight; |
||||
} |
||||
|
||||
template<typename T> |
||||
std::vector<std::vector<int>> Codebook<T>::getDistance() const |
||||
{ |
||||
return distance; |
||||
} |
||||
|
||||
template<typename T> |
||||
int Codebook<T>::getMinimumDistance() const |
||||
{ |
||||
return minDistance; |
||||
} |
||||
|
||||
template<typename T> |
||||
void Codebook<T>::doCalculations() |
||||
{ |
||||
minimumWeight(); |
||||
calcDistance(); |
||||
minimumDistance(); |
||||
} |
||||
|
||||
template<typename T> |
||||
void Codebook<T>::minimumWeight() |
||||
{ |
||||
for (T codeword: codebook) |
||||
{ |
||||
int weight = codeword.getWeight(); |
||||
if (weight < minWeight or minWeight == 0) |
||||
{ |
||||
minWeight = weight; |
||||
} |
||||
} |
||||
} |
||||
|
||||
template<typename T> |
||||
void Codebook<T>::calcDistance() |
||||
{ |
||||
int i = 0; |
||||
for (T codeword: codebook) |
||||
{ |
||||
distance.emplace_back(); |
||||
for(T otherCodeword: codebook) |
||||
{ |
||||
int aDistance = codeword.Distance(otherCodeword); |
||||
distance[i].push_back(aDistance); |
||||
} |
||||
} |
||||
} |
||||
|
||||
template<typename T> |
||||
void Codebook<T>::minimumDistance() |
||||
{ |
||||
for (std::vector<int> distanceVector: distance) |
||||
{ |
||||
for (int aDistance: distanceVector) |
||||
{ |
||||
if ((aDistance < minDistance |
||||
and aDistance != 0) |
||||
or minDistance == 0) |
||||
{ |
||||
minDistance = aDistance; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
template<typename T> |
||||
void Codebook<T>::doIncrementalCalculations() |
||||
{ |
||||
minimumIncrementalWeight(); |
||||
calcIncrementalDistance(); |
||||
minimumDistance(); |
||||
} |
||||
|
||||
template<typename T> |
||||
void Codebook<T>::minimumIncrementalWeight() |
||||
{ |
||||
int weight = codebook[codebook.size()-1].getWeight(); |
||||
if (weight < minWeight or minWeight == 0) |
||||
{ |
||||
minWeight = weight; |
||||
} |
||||
} |
||||
|
||||
template<typename T> |
||||
void Codebook<T>::calcIncrementalDistance() |
||||
{ |
||||
int lastCodeword = codebook.size()-1; |
||||
|
||||
// Adding new column to table
|
||||
// previous codewords - new codeowrd
|
||||
for (int i=0; i < distance.size(); i++) |
||||
{ |
||||
int aDistance = codebook[i].Distance(codebook[lastCodeword]); |
||||
distance[i].push_back(aDistance); |
||||
} |
||||
|
||||
// Adding new row to table
|
||||
// new codeword - all Codewords
|
||||
distance.emplace_back(); |
||||
for(T aCodeword: codebook) |
||||
{ |
||||
int aDistance = codebook[lastCodeword].Distance(aCodeword); |
||||
distance[distance.size()-1].push_back(aDistance); |
||||
} |
||||
} |
||||
|
||||
template<typename T> |
||||
void Codebook<T>::minimumIncrementalDistance() |
||||
{ |
||||
for (int aDistance: distance[distance.size()-1]) |
||||
{ |
||||
if (aDistance < minDistance or minDistance == 0) |
||||
{ |
||||
minDistance = aDistance; |
||||
} |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
|
||||
|
||||
#include <iostream> |
||||
|
||||
#include "auxiliary.h" |
||||
#include "cfc.h" |
||||
|
||||
using namespace std; |
||||
|
||||
int main (const int argc, const char* const argv[]) |
||||
{ |
||||
processArguments progArgs(argc, argv); |
||||
driver runProgram(progArgs); |
||||
return 0; |
||||
} |
@ -0,0 +1,207 @@
@@ -0,0 +1,207 @@
|
||||
// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
|
||||
|
||||
#include <cstring> |
||||
#include <ctype.h> |
||||
#include <fstream> |
||||
#include <iostream> |
||||
#include <locale> |
||||
#include <random> |
||||
#include <sstream> |
||||
|
||||
#include "general_functions.h" |
||||
|
||||
using namespace std; |
||||
|
||||
bool is_natural_number(const char* c_str) |
||||
{ |
||||
bool answer = false; |
||||
if (is_whole_number(c_str)) |
||||
{ |
||||
if (stoi(c_str) > 0) |
||||
{ |
||||
answer = true; |
||||
} |
||||
} |
||||
return answer; |
||||
} |
||||
|
||||
bool is_whole_number(const char* c_str) |
||||
{ |
||||
bool answer = false; |
||||
int c_str_length = strlen(c_str); |
||||
if (c_str_length < 1) |
||||
{ |
||||
// nothing needs to be done
|
||||
} |
||||
else if (! isdigit(c_str[0])) |
||||
{ |
||||
// nothing needs to be done
|
||||
} |
||||
else |
||||
{ |
||||
answer = true; |
||||
// c_str[0] is checked in else if statement.
|
||||
for (int i=1; i < (c_str_length-1); i++) |
||||
if (! isdigit(c_str[i])) |
||||
{ |
||||
answer = false; |
||||
} |
||||
} |
||||
return answer; |
||||
} |
||||
|
||||
void get_textfile_lines(string filename, vector<string> &file_lines) |
||||
{ |
||||
ifstream file(filename); |
||||
|
||||
if (! file.good()) |
||||
{ |
||||
cerr << "Failed to open/read file: " << filename\
|
||||
<< ". Non-exhaustive list of possible reasons:\n"\
|
||||
<< "1. File does not exist.\n"\
|
||||
<< "2. Unable to read file due to:\n"\
|
||||
<< "2.1 Don't have read access to file\n"\
|
||||
<< "2.2 File is opened elsewhere and some program have a "\
|
||||
<< "lock on file.\n"; |
||||
exit(2); |
||||
} |
||||
|
||||
// cout << "Reading file: " << filename << endl;
|
||||
|
||||
int i=0; |
||||
while (file.good()) |
||||
{ |
||||
file_lines.push_back(""); |
||||
getline(file, file_lines[i]); |
||||
i++; |
||||
} |
||||
|
||||
file.close(); |
||||
} |
||||
|
||||
int random_int(int minimum, int maximum) |
||||
{ |
||||
static random_device seed; |
||||
static mt19937 random_number_generator(seed()); |
||||
uniform_int_distribution<mt19937::result_type> range( |
||||
minimum, maximum); |
||||
return range(random_number_generator); |
||||
} |
||||
|
||||
// SOURCE: cppreference.com
|
||||
float random_float(float minimum, float maximum) |
||||
{ |
||||
static random_device seed; |
||||
static mt19937 random_number_generator(seed()); |
||||
uniform_real_distribution<> range( |
||||
minimum, maximum); |
||||
return range(random_number_generator); |
||||
} |
||||
|
||||
void string_to_vector( |
||||
string &a_string, |
||||
vector<string> &str_vector, |
||||
char delimeter) |
||||
{ |
||||
stringstream str_stream(a_string); |
||||
string str = ""; |
||||
while(getline(str_stream, str, delimeter)) |
||||
{ |
||||
if (str.length() > 1 and str != "\n") |
||||
{ |
||||
str_vector.push_back(str); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void pick_random_string( |
||||
string &str, const vector<string> &str_vector) |
||||
{ |
||||
int vector_size = str_vector.size(); |
||||
if (vector_size < 1) |
||||
{ |
||||
str = ""; |
||||
} |
||||
else |
||||
{ |
||||
int i = random_int(0, vector_size-1); |
||||
str = str_vector[i]; |
||||
} |
||||
} |
||||
|
||||
int modulate(int number, int modulus) |
||||
{ |
||||
int after_modulation; |
||||
if (number >= 0) |
||||
{ |
||||
after_modulation = number % modulus; |
||||
} |
||||
else if (number < 0) |
||||
{ |
||||
after_modulation = ( |
||||
modulus - (absolute_number(number)%modulus)); |
||||
} |
||||
else |
||||
{ |
||||
// OK, I know this is too much
|
||||
cerr_and_exit( |
||||
2, |
||||
"internal", |
||||
__FILE__, |
||||
__func__, |
||||
__LINE__, |
||||
"argument 1 'number' is neither >=0 nor < 0. " |
||||
"NOTE: this is just hypothetical situation following " |
||||
"defensive programming and should never happen in practice" |
||||
); |
||||
} |
||||
return after_modulation; |
||||
} |
||||
|
||||
|
||||
void cerr_and_exit( |
||||
int exit_code, |
||||
string error_name, |
||||
string file_name, |
||||
string function_name, |
||||
int line_number, |
||||
string additional_message) |
||||
{ |
||||
cerr_only( |
||||
error_name, |
||||
file_name, |
||||
function_name, |
||||
line_number, |
||||
additional_message); |
||||
exit(exit_code); |
||||
} |
||||
|
||||
void cerr_only( |
||||
string error_name, |
||||
string file_name, |
||||
string function_name, |
||||
int line_number, |
||||
string additional_message) |
||||
{ |
||||
if (error_name.size() > 0) |
||||
{ |
||||
error_name[0] = toupper(error_name[0]); |
||||
if (error_name[-1] != ' ') |
||||
{ |
||||
error_name += ' '; |
||||
} |
||||
} |
||||
cerr |
||||
<< error_name << "error occured at:\n" |
||||
<< "Source code file name: " << file_name << "\n" |
||||
<< "Function name: " << function_name << "\n" |
||||
<< "Line number: " << line_number << "\n" |
||||
<< additional_message; |
||||
if (additional_message != "") |
||||
{ |
||||
if (additional_message[-1] != '\n') |
||||
{ |
||||
cerr << '\n'; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
|
||||
|
||||
#ifndef _GENERAL_FUNCTIONS_H_ |
||||
#define _GENERAL_FUNCTIONS_H_ |
||||
|
||||
#include <string> |
||||
#include <vector> |
||||
|
||||
bool is_natural_number(const char* c_str); |
||||
|
||||
bool is_whole_number(const char* c_str); |
||||
|
||||
void get_textfile_lines( |
||||
std::string filename, std::vector<std::string> &file_lines); |
||||
|
||||
int random_int(int minimum, int maximum); |
||||
|
||||
float random_float(float minimum, float maximum); |
||||
|
||||
int modulate(int number, int modulus); |
||||
|
||||
void cerr_and_exit( |
||||
int exit_code, |
||||
std::string error_name, |
||||
std::string file_name, |
||||
std::string function_name, |
||||
int line_number, |
||||
std::string additional_message = ""); |
||||
|
||||
void cerr_only( |
||||
std::string error_name, |
||||
std::string file_name, |
||||
std::string function_name, |
||||
int line_number, |
||||
std::string additional_message); |
||||
|
||||
/* Its a good practice to prototype all functions including which are
|
||||
* defined in header file itself such as inline functions before defining |
||||
* any function. This way, even if we use one function in another |
||||
* function, we do not have to worry about function undefined error |
||||
* possibilities. |
||||
*/ |
||||
|
||||
inline int absolute_number(int number); |
||||
|
||||
inline int smaller_number(int a, int b); |
||||
|
||||
inline int bigger_number(int a, int b); |
||||
|
||||
inline int absolute_number(int number) |
||||
{ |
||||
if (number < 0) |
||||
return -(number); |
||||
else |
||||
return number; |
||||
} |
||||
|
||||
inline int smaller_number(int a, int b) |
||||
{ |
||||
if (a > b) |
||||
return b; |
||||
else |
||||
return a; |
||||
} |
||||
|
||||
inline int bigger_number(int a, int b) |
||||
{ |
||||
if (a < b) |
||||
return b; |
||||
else |
||||
return a; |
||||
} |
||||
|
||||
void string_to_vector( |
||||
std::string &a_string, |
||||
std::vector<std::string> &str_vector, |
||||
char delimeter = ','); |
||||
|
||||
void pick_random_string( |
||||
std::string &str, const std::vector<std::string> &str_vector); |
||||
|
||||
#endif |
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
# License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
|
||||
|
||||
compiler = "CC"
|
||||
standardCpp11 = "--std=c++11"
|
||||
|
||||
ifeq ($(compiler), "CC") |
||||
# gcc, g++, clang etc. follows double-dash '--' convention for non one
|
||||
# character arguments but banshee CC uses single dash '-'
|
||||
standardCpp11 = "-std=c++11"
|
||||
endif |
||||
|
||||
CFC: auxiliary.o cfc.o driver.o general_functions.o libgenVal.a |
||||
$(compiler) $(standardCpp11) -o CFC *.o libgenVal.a
|
||||
|
||||
auxiliary.o: auxiliary.cpp general_functions.h |
||||
$(compiler) $(standardCpp11) -c auxiliary.cpp
|
||||
|
||||
cfc.o: cfc.cpp general_functions.h generateValue.h |
||||
$(compiler) $(standardCpp11) -c cfc.cpp
|
||||
|
||||
driver.o: driver.cpp auxiliary.h cfc.h |
||||
$(compiler) $(standardCpp11) -c driver.cpp
|
||||
|
||||
general_functions.o: general_functions.cpp |
||||
$(compiler) $(standardCpp11) -c general_functions.cpp
|
||||
|
||||
clean: |
||||
rm *.o
|
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
# License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html |
||||
|
||||
NOTE: will not compile if libgenVal.a and generateValue.h are missing |
||||
NOTE 2: general_function.h & general_function.cpp files are carried from previous assignments and additional functions related to this assignment added. |
||||
|
||||
Compile on banshee as: |
||||
$ gmake |
||||
OR |
||||
$ gmake CFC |
||||
OR |
||||
$ CC -std=c++11 -o CFC *.cpp libgenVal.a |
||||
|
||||
Assumptions and program behaviour |
||||
In: |
||||
int difference = Mint1 - Mint2; |
||||
both Mint have same modulus, otherwise, it would not make sense. |
||||
Plus In: |
||||
int difference = Melt2 - Melt2; |
||||
Both Mint and Melt, return an int even though usual expected return for operator-() is another object of same type. This is as per specification, Codeword expects an int return when calculating difference bewtween two objects of same type. |
||||
|
||||
If user give number to Mint object higher than its modulus or less than 0 than Mint itself modulates it before storing in int number variable. So, number passed to Mint and returned by calling Mint.getNumber() function may not be same. NOTE: this is a hypothetical scenerio when someone else may use our written classes and functions as library. The program itself gives number which is within modulus range. |
||||
|
||||
Error exit code list: |
||||
[For exact cause, see stderr] |
||||
1 - error related to arguments |
||||
2 - Program internal hypothetical errors which should never happen. |
||||
3 - Technically possible errors but which should not happen within the runtime of this program. |
Loading…
Reference in new issue