/* * Copyright 2011, Ben Langmead * * This file is part of Bowtie 2. * * Bowtie 2 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. * * Bowtie 2 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 Bowtie 2. If not, see . */ #ifndef SIMPLE_FUNC_H_ #define SIMPLE_FUNC_H_ #include #include #include #include "tokenize.h" #define SIMPLE_FUNC_CONST 1 #define SIMPLE_FUNC_LINEAR 2 #define SIMPLE_FUNC_SQRT 3 #define SIMPLE_FUNC_LOG 4 /** * A simple function of one argument, parmeterized by I, X, C and L: min * value, max value, constant term, and coefficient respectively: * * 1. Constant: f(x) = max(I, min(X, C + L * 0)) * 2. Linear: f(x) = max(I, min(X, C + L * x)) * 3. Square root: f(x) = max(I, min(X, C + L * sqrt(x))) * 4. Log: f(x) = max(I, min(X, C + L * ln(x))) * * Clearly, the return value of the Constant function doesn't depend on x. */ class SimpleFunc { public: SimpleFunc() : type_(0), I_(0.0), X_(0.0), C_(0.0), L_(0.0) { } SimpleFunc(int type, double I, double X, double C, double L) { init(type, I, X, C, L); } void init(int type, double I, double X, double C, double L) { type_ = type; I_ = I; X_ = X; C_ = C; L_ = L; } void init(int type, double C, double L) { type_ = type; C_ = C; L_ = L; I_ = -std::numeric_limits::max(); X_ = std::numeric_limits::max(); } void setType (int type ) { type_ = type; } void setMin (double mn) { I_ = mn; } void setMax (double mx) { X_ = mx; } void setConst(double co) { C_ = co; } void setCoeff(double ce) { L_ = ce; } int getType () const { return type_; } double getMin () const { return I_; } double getMax () const { return X_; } double getConst() const { return C_; } double getCoeff() const { return L_; } void mult(double x) { if(I_ < std::numeric_limits::max()) { I_ *= x; X_ *= x; C_ *= x; L_ *= x; } } bool initialized() const { return type_ != 0; } void reset() { type_ = 0; } bool alwaysPositive() const { return f(1.0) > 0 && (SIMPLE_FUNC_CONST || L_ >= 0.0); } template T f(double x) const { assert(type_ >= SIMPLE_FUNC_CONST && type_ <= SIMPLE_FUNC_LOG); double X; if(type_ == SIMPLE_FUNC_CONST) { X = 0.0; } else if(type_ == SIMPLE_FUNC_LINEAR) { X = x; } else if(type_ == SIMPLE_FUNC_SQRT) { X = sqrt(x); } else if(type_ == SIMPLE_FUNC_LOG) { X = log(x); } else { throw 1; } double ret = std::max(I_, std::min(X_, C_ + L_ * X)); if(ret == std::numeric_limits::max()) { return std::numeric_limits::max(); } else if(ret == std::numeric_limits::min()) { return std::numeric_limits::min(); } else { return (T)ret; } } static int parseType(const std::string& otype); static SimpleFunc parse( const std::string& s, double defaultConst = 0.0, double defaultLinear = 0.0, double defaultMin = 0.0, double defaultMax = std::numeric_limits::max()); protected: int type_; double I_, X_, C_, L_; }; #endif /*ndef SIMPLE_FUNC_H_*/