From d15cdebbb00fedc6c6a57f4e1328bb1ea46f544f Mon Sep 17 00:00:00 2001 From: jthorn Date: Fri, 15 Jun 2001 16:28:45 +0000 Subject: initial import into cvs source is JT personal cvs ~/src/libmisc++/ git-svn-id: http://svn.einsteintoolkit.org/cactus/EinsteinAnalysis/AHFinderDirect/trunk@31 f88db872-0e4f-0410-b76b-b9085cfa78c5 --- src/jtutil/linear_map.hh | 132 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 src/jtutil/linear_map.hh (limited to 'src/jtutil/linear_map.hh') diff --git a/src/jtutil/linear_map.hh b/src/jtutil/linear_map.hh new file mode 100644 index 0000000..f7ae2a8 --- /dev/null +++ b/src/jtutil/linear_map.hh @@ -0,0 +1,132 @@ +// linear_map.hh -- linear mapping from integers <--> floating point values +// $Id$ +// +// linear_map - linear mapping from integers <--> floating point values +// + +// +// prerequisites +// +// // for fuzzy:: +// + +// +// The template defined in this file represents a linear mapping between +// a contiguous range of integers, and an arithmetic progression of +// floating point values, parameterized by the floating point data type. +// + +#ifndef NDEBUG +// +// Full bounds checking is done on the mapping in both directions +// +#endif + +//***************************************************************************** + +template +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 HOW_MANY_IN_RANGE(min_int_,max_int_); } + bool 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 fp_of_int_unchecked(int i) const + { return offset_ + delta_*i; } + fp fp_of_int(int i) const + { + assert(in_range(i)); + return fp_of_int_unchecked(i); + } + + // converg delta_int --> delta_fp + fp delta_fp_of_delta_int(int delta_i) const + { return delta_ * delta_i; } + + // fp bounds info + fp min_fp() const { return fp_of_int_unchecked(min_int_); } + fp delta_fp() const { return delta_; } + fp inverse_delta_fp() const { return inverse_delta_; } + fp max_fp() const { return fp_of_int_unchecked(max_int_); } + bool in_range(fp x) const + { + return fuzzy::GE(x,min_fp()) && fuzzy::LE(x,max_fp()); + } + fp clamp(fp 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 fp_int_of_fp(fp x) const; + + // convert fp --> int, check being fuzzily integral + enum noninteger_action // what to do if `int' + // isn't fuzzily integral? + { + error, // error_exit(...) + warning, // print warning msg, then round to nearest + round, // (silently) round to nearest + floor, // (silently) round to -infinity + ceiling // (silently) round to +infinity + }; + int int_of_fp(fp x, noninteger_action nia = error) const; + + // convert delta_fp --> delta_int, check being fuzzily integral + int delta_int_of_delta_fp(fp delta_x, noninteger_action nia = error) + const; + + // constructors + linear_map(int min_int_in, int max_int_in, + fp min_fp_in, fp delta_fp_in, fp max_fp_in); + // ... construct with subrange of existing linear_map + linear_map(const linear_map &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 min_fp_in, fp max_fp_in); + + // these define the actual mapping + // via the fp_of_int() function (above) + fp offset_, delta_; + + // cache of 1.0/delta_ + // ==> avoids fp divide in inverse_delta_fp() + // ==> also makes fp --> int conversions slightly faster + fp inverse_delta_; + + // bounds (inclusive) + const int min_int_, max_int_; + }; -- cgit v1.2.3