You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
457 lines
10 KiB
457 lines
10 KiB
// 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
|
|
|