/*
Copyright 2009-2012 Andreas Biegert, Christof Angermueller
This file is part of the CS-BLAST package.
The CS-BLAST package is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The CS-BLAST package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef CS_PROFILE_INL_H_
#define CS_PROFILE_INL_H_
#include "profile.h"
#include
namespace cs {
template
Profile::Profile() : nn(0), v(NULL) {}
template
Profile::Profile(size_t n) : nn(n), v(n>0 ? new double*[n] : NULL) {
size_t i,nel=n*Abc::kSizeAny;
if (v) v[0] = nel>0 ? new double[nel] : NULL;
for (i=1;i
Profile::Profile(size_t n, const double &a)
: nn(n), v(n>0 ? new double*[n] : NULL) {
size_t i,j,nel=n*Abc::kSizeAny;
if (v) v[0] = nel>0 ? new double[nel] : NULL;
for (i=1; i< n; i++) v[i] = v[i-1] + Abc::kSizeAny;
for (i=0; i< n; i++) for (j=0; j
Profile::Profile(size_t n, const double *a)
: nn(n), v(n>0 ? new double*[n] : NULL) {
size_t i,nel=n*Abc::kSizeAny;
if (v) v[0] = nel>0 ? new double[nel] : NULL;
for (i=1; i< n; i++) v[i] = v[i-1] + Abc::kSizeAny;
memcpy(v[0], a, nel * sizeof(double));
}
template
Profile::Profile(const Profile &rhs)
: nn(rhs.nn), v(nn>0 ? new double*[nn] : NULL) {
size_t i,nel=nn*Abc::kSizeAny;
if (v) v[0] = nel>0 ? new double[nel] : NULL;
for (i=1; i< nn; i++) v[i] = v[i-1] + Abc::kSizeAny;
memcpy(v[0], rhs[0], nel * sizeof(double));
}
template
Profile::Profile(const CountProfile& cp)
: nn(cp.length()), v(nn>0 ? new double*[nn] : NULL) {
size_t i,j,nel=nn*Abc::kSizeAny;
if (v) v[0] = nel>0 ? new double[nel] : NULL;
for (i=1; i< nn; i++) v[i] = v[i-1] + Abc::kSizeAny;
for (i=0; i< nn; i++)
for (j=0; j 0 ? cp.counts[i][j] / cp.neff[i] : 0.0;
}
template
Profile & Profile::operator=(const Profile &rhs) {
if (this != &rhs) {
size_t i,nel;
nel = rhs.nn*Abc::kSizeAny;
if (nn != rhs.nn) {
if (v != NULL) {
delete[] v[0];
delete[] v;
}
nn=rhs.nn;
v = nn>0 ? new double*[nn] : NULL;
if (v) v[0] = nel>0 ? new double[nel] : NULL;
for (i=1; i< nn; i++) v[i] = v[i-1] + Abc::kSizeAny;
}
memcpy(v[0], rhs[0], nel * sizeof(double));
}
return *this;
}
template
inline double* Profile::operator[](const size_t i) {
#ifdef CHECKBOUNDS
if (i<0 || i>=nn) {
throw Exception("Profile subscript out of bounds");
}
#endif
return v[i];
}
template
inline const double* Profile::operator[](const size_t i) const {
#ifdef CHECKBOUNDS
if (i<0 || i>=nn) {
throw Exception("Profile subscript out of bounds");
}
#endif
return v[i];
}
template
void Profile::Resize(size_t newn) {
size_t i,nel;
if (newn != nn) {
if (v != NULL) {
delete[] v[0];
delete[] v;
}
nn = newn;
v = nn>0 ? new double*[nn] : NULL;
nel = nn*Abc::kSizeAny;
if (v) v[0] = nel>0 ? new double[nel] : NULL;
for (i=1; i< nn; i++) v[i] = v[i-1] + Abc::kSizeAny;
}
}
template
void Profile::Assign(size_t newn, const double& a) {
size_t i,j,nel;
if (newn != nn) {
if (v != NULL) {
delete[] v[0];
delete[] v;
}
nn = newn;
v = nn>0 ? new double*[nn] : NULL;
nel = nn*Abc::kSizeAny;
if (v) v[0] = nel>0 ? new double[nel] : NULL;
for (i=1; i< nn; i++) v[i] = v[i-1] + *Abc::kSizeAny;
}
for (i=0; i< nn; i++) for (j=0; j<*Abc::kSizeAny; j++) v[i][j] = a;
}
template
void Profile::Insert(size_t idx, const Profile& other) {
size_t n = MIN(other.length(), length() - idx);
memcpy(v[idx], other[0], n * Abc::kSizeAny * sizeof(double));
}
template
Profile::~Profile() {
if (v != NULL) {
delete[] v[0];
delete[] v;
}
}
// Assigns given constant value or default to all entries in matrix
template
inline void Assign(Profile& p, double val) {
for (size_t i = 0; i < p.length(); ++i)
for (size_t j = 0; j < Abc::kSizeAny; ++j)
p[i][j] = val;
}
// Normalizes all profile columns to fixed value. Iff 'incl_any' is true,
// normalization also includes values for ANY letter
template
inline void Normalize(Profile& p, double val, bool incl_any) {
const size_t abc_size = incl_any ? Abc::kSizeAny : Abc::kSize;
for (size_t i = 0; i < p.length(); ++i) {
double sum = 0.0;
for (size_t a = 0; a < abc_size; ++a) sum += p[i][a];
if (fabs(val - sum) > kNormalize && sum != 0.0) {
double fac = val / sum;
for (size_t a = 0; a < abc_size; ++a) p[i][a] *= fac;
}
}
}
// Normalizes all profile columns to corresponding value in vector 'norm'.
// Iff 'incl_any' is true, normalization also includes values for ANY letter.
template
inline void Normalize(Profile& p, const Vector& norm, bool incl_any) {
const size_t abc_size = incl_any ? Abc::kSizeAny : Abc::kSize;
for (size_t i = 0; i < p.length(); ++i) {
double sum = 0.0;
for (size_t a = 0; a < abc_size; ++a) sum += p[i][a];
if (fabs(norm[i] - sum) > kNormalize && sum != 0.0) {
double fac = norm[i] / sum;
for (size_t a = 0; a < abc_size; ++a) p[i][a] *= fac;
}
}
}
// Prints profile in human-readable format for debugging.
template
std::ostream& operator<< (std::ostream& out, const Profile& p) {
out << "Profile" << std::endl;
for (size_t a = 0; a < Abc::kSizeAny; ++a)
out << "\t" << Abc::kIntToChar[a];
out << std::endl;
for (size_t i = 0; i < p.length(); ++i) {
out << i+1;
for (size_t a = 0; a < Abc::kSizeAny; ++a)
out << strprintf("\t%6.4f", p[i][a]);
out << std::endl;
}
return out;
}
// Calculates the entropy of the given profile using logarithm base 2.
template
inline double Entropy(const Profile& p) {
double rv = 0.0;
for (size_t i = 0; i < p.length(); ++i) {
for (size_t a = 0; a < Abc::kSize; ++a)
if (p[i][a] > FLT_MIN) rv -= p[i][a] * log2(p[i][a]);
}
return rv;
}
// Calculates the Neff in the given profile.
template
inline double Neff(const Profile& p) {
return p.length() > 0 ? pow(2, Entropy(p) / p.length()) : 0;
}
} // namespace cs
#endif // CS_PROFILE_INL_H_