00001 #include "biu/DistanceEnergyFunction.hh"
00002 #include <limits.h>
00003
00004 namespace biu
00005 {
00006
00007 DistanceEnergyFunction::~DistanceEnergyFunction()
00008 {
00009 }
00010
00011 }
00012
00013
00014 namespace biu
00015 {
00016
00017 ContactEnergyFunction::ContactEnergyFunction(
00018 const Alphabet* const _alphabet,
00019 const EnergyMatrix* const _energyMat,
00020 const LatticeModel* const _lattice)
00021 : biu::DistanceEnergyFunction(),
00022 alphabet(_alphabet),
00023 energyMat(_energyMat),
00024 lattice(_lattice),
00025 firstBaseVecLength(lattice==NULL?0.0:lattice->getNeighborhood().getElementByIndex(0).distance(IntPoint(0,0,0)))
00026 {
00027 assertbiu( alphabet != NULL, "no alphabet given (NULL)");
00028 assertbiu( energyMat != NULL, "no energy matrix given (NULL)");
00029 assertbiu( lattice != NULL, "no lattice model given (NULL)");
00030 assertbiu( alphabet->getAlphabetSize() == energyMat->numRows()
00031 && alphabet->getAlphabetSize() == energyMat->numColumns(),
00032 "energy matrix has the wrong size for this alphabet size");
00033 }
00034
00035 ContactEnergyFunction::~ContactEnergyFunction()
00036 {
00037 }
00038
00039 double
00040 ContactEnergyFunction::getContactEnergy(
00041 const Alphabet::AlphElem& first,
00042 const Alphabet::AlphElem& second) const {
00043
00044 return energyMat->at( alphabet->getIndex(first),
00045 alphabet->getIndex(second) );
00046 }
00047
00048 double
00049 ContactEnergyFunction::getEnergy( const Alphabet::AlphElem& seq_i,
00050 const Alphabet::AlphElem& seq_j,
00051 const double & distance ) const
00052 {
00053 if (distance == firstBaseVecLength ) {
00054 return getContactEnergy(seq_i, seq_j);
00055 }
00056 return 0.0;
00057 }
00058
00059 double
00060 ContactEnergyFunction::getEnergy( const Alphabet::AlphElem & seq_i,
00061 const Alphabet::AlphElem & seq_j,
00062 const IntPoint & cor_i,
00063 const IntPoint & cor_j ) const
00064 {
00065 if (lattice->areNeighbored( cor_i, cor_j ) ) {
00066 return getContactEnergy( seq_i, seq_j );
00067 }
00068 return 0.0;
00069 }
00070
00071 double
00072 ContactEnergyFunction::getEnergy( const Alphabet::AlphElem & seq_i,
00073 const Alphabet::AlphElem & seq_j,
00074 const DblPoint & cor_i,
00075 const DblPoint & cor_j ) const
00076 {
00077
00078 return this->getEnergy(seq_i,seq_j,cor_i.distance(cor_j));
00079 }
00080
00081 bool
00082 ContactEnergyFunction::operator == (const DistanceEnergyFunction& ef2) const {
00083 if (this == &ef2)
00084 return true;
00085
00086 const ContactEnergyFunction* cef2 = dynamic_cast<const ContactEnergyFunction*> (&ef2);
00087
00088 return (alphabet == cef2->alphabet || *alphabet == *(cef2->alphabet))
00089 && (energyMat == cef2->energyMat || *energyMat == *(cef2->energyMat))
00090 && (lattice == cef2->lattice || *lattice == *(cef2->lattice));
00091 }
00092
00093 bool
00094 ContactEnergyFunction::operator != (const DistanceEnergyFunction& ef2) const {
00095 return !(this->operator ==(ef2));
00096 }
00097
00098
00099 }
00100
00101
00102 #include <algorithm>
00103
00104 namespace biu
00105 {
00106
00107 IntervalEnergyFunction::IntervalEnergyFunction( const Alphabet* const alph_)
00108 : biu::DistanceEnergyFunction(),
00109 alphabet(alph_),
00110 energyMat(),
00111 intervalMax()
00112 {
00113
00114 }
00115
00116 IntervalEnergyFunction::IntervalEnergyFunction( const biu::IntervalEnergyFunction & toCopy)
00117 : biu::DistanceEnergyFunction(),
00118 alphabet(toCopy.alphabet),
00119 energyMat(),
00120 intervalMax(toCopy.intervalMax)
00121 {
00122 for (size_t i=0; i<toCopy.energyMat.size(); i++) {
00123 energyMat.push_back(new biu::EnergyMatrix(*(toCopy.energyMat[i])));
00124 }
00125 assertbiu(energyMat.size() == intervalMax.size(),
00126 "different numbers of energy tables and interval boundaries");
00127 }
00128
00129
00130 IntervalEnergyFunction::~IntervalEnergyFunction()
00131 {
00132
00133 for (size_t i=0; i<energyMat.size(); i++) {
00134 delete energyMat[i];
00135 }
00136
00137 energyMat.clear();
00138 intervalMax.clear();
00139 }
00140
00141 const Alphabet* const
00142 IntervalEnergyFunction::getAlphabet() const
00143 {
00144 return alphabet;
00145 }
00146
00147 double
00148 IntervalEnergyFunction::getEnergy( const Alphabet::AlphElem& first,
00149 const Alphabet::AlphElem& second,
00150 const double & distance ) const
00151 {
00152 assertbiu( distance < *(intervalMax.rbegin()), "given distance is out of interval bounds");
00153
00154 return (*energyMat[getInterval(distance)])[alphabet->getIndex(first)][alphabet->getIndex(second)];;
00155 }
00156
00157 double
00158 IntervalEnergyFunction::getEnergy( const Alphabet::AlphElem & seq_i,
00159 const Alphabet::AlphElem & seq_j,
00160 const IntPoint & cor_i,
00161 const IntPoint & cor_j ) const
00162 {
00163
00164 return this->getEnergy(seq_i, seq_j, cor_i.distance(cor_j));
00165 }
00166
00167 double
00168 IntervalEnergyFunction::getEnergy( const Alphabet::AlphElem & seq_i,
00169 const Alphabet::AlphElem & seq_j,
00170 const DblPoint & cor_i,
00171 const DblPoint & cor_j ) const
00172 {
00173
00174 return this->getEnergy(seq_i, seq_j, cor_i.distance(cor_j));
00175 }
00176
00177
00178 bool
00179 IntervalEnergyFunction::operator == (const DistanceEnergyFunction& ef2) const
00180 {
00181 if (&ef2 == this)
00182 return true;
00183
00184 bool retVal = false;
00185
00186 const IntervalEnergyFunction* ief = dynamic_cast<const IntervalEnergyFunction*>(&ef2);
00187 if (ief != NULL) {
00188 retVal = (alphabet == ief->alphabet || *alphabet == *(ief->alphabet))
00189 && ief->intervalMax.size() == this->intervalMax.size()
00190 && ief->energyMat.size() == this->energyMat.size();
00191
00192 for (size_t i=0; retVal && i<intervalMax.size(); i++) {
00193 retVal = ief->intervalMax[i] == this->intervalMax[i]
00194 && *(ief->energyMat[i]) == *(this->energyMat[i]);
00195 }
00196 }
00197
00198 return retVal;
00199 }
00200
00201 bool
00202 IntervalEnergyFunction::operator != (const DistanceEnergyFunction& ef2) const
00203 {
00204 return !(this->operator ==(ef2));
00205 }
00206
00207 size_t
00208 IntervalEnergyFunction::addInterval( const biu::EnergyMatrix& energies,
00209 const double upperBound )
00210 {
00211 assertbiu( intervalMax.size() == 0 || upperBound > *(intervalMax.rbegin()),
00212 "given upperBound is NOT greater than the last in use");
00213 assertbiu( alphabet->getAlphabetSize() == energies.numRows()
00214 && alphabet->getAlphabetSize() == energies.numColumns(),
00215 "energy matrix has the wrong size for this alphabet size");
00216
00217
00218 energyMat.push_back(new biu::EnergyMatrix(energies));
00219
00220 intervalMax.push_back(upperBound);
00221
00222 return intervalMax.size()-1;
00223 }
00224
00225 size_t
00226 IntervalEnergyFunction::getIntervalNum(void) const {
00227 return intervalMax.size();
00228 }
00229
00230 double
00231 IntervalEnergyFunction::getIntervalMax(const size_t index) const {
00232 assertbiu(index < intervalMax.size(), "index out of bound");
00233 return intervalMax[index];
00234 }
00235
00236 const biu::EnergyMatrix* const
00237 IntervalEnergyFunction::getIntervalMatrix(const size_t index) const {
00238 assertbiu(index < intervalMax.size(), "index out of bound");
00239 return energyMat[index];
00240 }
00241
00242 size_t
00243 IntervalEnergyFunction::getInterval( double distance) const {
00244 if (intervalMax.size() == 0 || distance > *(intervalMax.rbegin())) {
00245 return UINT_MAX;
00246 }
00247
00248 size_t index = 0;
00249 while (distance > intervalMax[index]) {
00250 index++;
00251 }
00252 return index;
00253 }
00254
00255
00256 }