132 lines
3.8 KiB
C++
132 lines
3.8 KiB
C++
#ifndef AHFINDERDIRECT__LINEAR_MAP_HH
|
|
#define AHFINDERDIRECT__LINEAR_MAP_HH
|
|
namespace AHFinderDirect
|
|
{
|
|
namespace jtutil
|
|
{
|
|
|
|
template <typename fp_t>
|
|
class linear_map
|
|
{
|
|
public:
|
|
// integer bounds info
|
|
int min_int() const { return min_int_; }
|
|
int max_int() const { return max_int_; }
|
|
int N_points() const
|
|
{
|
|
return jtutil::how_many_in_range(min_int_, max_int_);
|
|
}
|
|
bool is_in_range(int i) const
|
|
{
|
|
return (i >= min_int()) && (i <= max_int());
|
|
}
|
|
int clamp(int i) const
|
|
{
|
|
if (i < min_int())
|
|
then return min_int();
|
|
else if (i > max_int())
|
|
then return max_int();
|
|
else
|
|
return i;
|
|
}
|
|
|
|
// convert int --> fp
|
|
fp_t fp_of_int_unchecked(int i) const
|
|
{
|
|
return origin_ + delta_ * i;
|
|
}
|
|
fp_t fp_of_int(int i) const
|
|
{
|
|
assert(is_in_range(i));
|
|
return fp_of_int_unchecked(i);
|
|
}
|
|
|
|
// converg delta_int --> delta_fp
|
|
fp_t delta_fp_of_delta_int(int delta_i) const
|
|
{
|
|
return delta_ * delta_i;
|
|
}
|
|
|
|
// fp bounds info
|
|
fp_t origin() const { return origin_; }
|
|
fp_t delta_fp() const { return delta_; }
|
|
fp_t inverse_delta_fp() const { return inverse_delta_; }
|
|
fp_t min_fp() const { return fp_of_int_unchecked(min_int_); }
|
|
fp_t max_fp() const { return fp_of_int_unchecked(max_int_); }
|
|
bool is_in_range(fp_t x) const
|
|
{
|
|
return fuzzy<fp_t>::GE(x, min_fp()) && fuzzy<fp_t>::LE(x, max_fp());
|
|
}
|
|
fp_t clamp(fp_t x) const
|
|
{
|
|
if (x < min_fp())
|
|
then return min_fp();
|
|
else if (x > max_fp())
|
|
then return max_fp();
|
|
else
|
|
return x;
|
|
}
|
|
|
|
// convert linear map indices <--> C-style 0-origin indices
|
|
int zero_origin_int(int i) const { return i - min_int(); }
|
|
int map_int(int zero_origin_i) { return zero_origin_i + min_int(); }
|
|
|
|
// convert fp --> int coordinate, but return result as fp
|
|
// (which need not be fuzzily integral)
|
|
fp_t fp_int_of_fp(fp_t x) const;
|
|
|
|
// convert fp --> int, check being fuzzily integral
|
|
enum noninteger_action // what to do if "int"
|
|
// isn't fuzzily integral?
|
|
{
|
|
nia_error, // jtutil::error_exit(...)
|
|
nia_warning, // print warning msg,
|
|
// then round to nearest
|
|
nia_round, // (silently) round to nearest
|
|
nia_floor, // (silently) round to -infinity
|
|
nia_ceiling // (silently) round to +infinity
|
|
};
|
|
int int_of_fp(fp_t x, noninteger_action nia = nia_error) const;
|
|
|
|
// convert delta_fp --> delta_int, check being fuzzily integral
|
|
int delta_int_of_delta_fp(fp_t delta_x,
|
|
noninteger_action nia = nia_error)
|
|
const;
|
|
|
|
// constructors
|
|
linear_map(int min_int_in, int max_int_in,
|
|
fp_t min_fp_in, fp_t delta_fp_in, fp_t max_fp_in);
|
|
// ... construct with subrange of existing linear_map
|
|
linear_map(const linear_map<fp_t> &lm_in,
|
|
int min_int_in, int max_int_in);
|
|
|
|
// no need for explicit destructor, compiler-generated no-op is ok
|
|
|
|
// no need for copy constructor or assignment operator,
|
|
// compiler-generated defaults are ok
|
|
|
|
private:
|
|
// common code (argument validation & setup) for all constructors
|
|
// assumes min_int_, max_int_, delta_ already initialized,
|
|
// other class members *not* initialized
|
|
void constructor_common(fp_t min_fp_in, fp_t max_fp_in);
|
|
|
|
// these define the actual mapping
|
|
// via the fp_of_int() function (above)
|
|
fp_t origin_, delta_;
|
|
|
|
// cache of 1.0/delta_
|
|
// ==> avoids fp divide in inverse_delta_fp()
|
|
// ==> also makes fp --> int conversions slightly faster
|
|
fp_t inverse_delta_;
|
|
|
|
const int min_int_, max_int_;
|
|
};
|
|
|
|
//******************************************************************************
|
|
|
|
} // namespace jtutil
|
|
} // namespace AHFinderDirect
|
|
|
|
#endif /* AHFINDERDIRECT__LINEAR_MAP_HH */
|