aboutsummaryrefslogtreecommitdiff
path: root/src/jtutil/linear_map.hh
diff options
context:
space:
mode:
authorjthorn <jthorn@f88db872-0e4f-0410-b76b-b9085cfa78c5>2001-06-15 16:28:45 +0000
committerjthorn <jthorn@f88db872-0e4f-0410-b76b-b9085cfa78c5>2001-06-15 16:28:45 +0000
commitd15cdebbb00fedc6c6a57f4e1328bb1ea46f544f (patch)
tree1058f8c14d5a600b88ae48766ddca66040d82eca /src/jtutil/linear_map.hh
parent7670654a6844a5b729d64dea35405463cf90a2e5 (diff)
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
Diffstat (limited to 'src/jtutil/linear_map.hh')
-rw-r--r--src/jtutil/linear_map.hh132
1 files changed, 132 insertions, 0 deletions
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
+// <assert.h>
+// <jt/util++.hh> // 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 fp>
+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<fp>::GE(x,min_fp()) && fuzzy<fp>::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<fp> &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_;
+ };