isce3  0.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
LUT2d.h
1 // Source Author: Bryan Riel
2 // Co-Author: Joshua Cohen
3 // Copyright 2017
4 //
5 
6 #pragma once
7 
8 #include "forward.h"
9 
10 #include <valarray>
11 #include "Constants.h"
12 #include "Matrix.h"
13 #include "Utilities.h"
14 
17 template <typename T>
18 class isce3::core::LUT2d {
19 
20  public:
21  // Constructors
22  inline LUT2d();
23  inline LUT2d(isce3::core::dataInterpMethod method);
24  LUT2d(double xstart, double ystart, double dx, double dy,
25  const isce3::core::Matrix<T> & data,
26  isce3::core::dataInterpMethod method = isce3::core::BILINEAR_METHOD,
27  bool boundsError = true);
28  LUT2d(const std::valarray<double> & xcoord,
29  const std::valarray<double> & ycoord,
30  const isce3::core::Matrix<T> & data,
31  isce3::core::dataInterpMethod method = isce3::core::BILINEAR_METHOD,
32  bool boundsError = true);
33 
34  // Deep copy constructor
35  inline LUT2d(const LUT2d<T> & lut);
36 
37  // Deep assignment operator
38  inline LUT2d & operator=(const LUT2d<T> & lut);
39 
40  // Set data from external data
41  void setFromData(const std::valarray<double> & xcoord,
42  const std::valarray<double> & ycoord,
43  const isce3::core::Matrix<T> & data);
44 
45  // Get interpolator method
46  isce3::core::dataInterpMethod interpMethod() const;
47 
48  // Set interpolator method
49  void interpMethod(isce3::core::dataInterpMethod method);
50 
51  // Get starting X-coordinate
52  inline double xStart() const { return _xstart; }
53  // Get starting Y-coordinate
54  inline double yStart() const { return _ystart; }
55  // Get X-spacing
56  inline double xSpacing() const { return _dx; }
57  // Get Y-spacing
58  inline double ySpacing() const { return _dy; }
59  // Get LUT length (number of lines)
60  inline size_t length() const { return _data.length(); }
61  // Get LUT width (number of samples)
62  inline size_t width() const { return _data.width(); }
63  // Get the reference value
64  inline T refValue() const { return _refValue; }
65  // Get flag for having data
66  inline bool haveData() const { return _haveData; }
67  // Get bounds error flag
68  inline bool boundsError() const { return _boundsError; }
69  // Get read-only reference to data
70  inline const isce3::core::Matrix<T> & data() const { return _data; }
71 
72  // Set bounds error floag
73  inline void boundsError(bool flag) { _boundsError = flag; }
74 
75  // Evaluate LUT
76  T eval(double y, double x) const;
77 
79  inline bool contains(double y, double x) const
80  {
81  const auto i = (y - _ystart) / _dy;
82  const auto j = (x - _xstart) / _dx;
83  return (i >= 0.0) && (i < _data.length()) &&
84  (j >= 0.0) && (j < _data.width());
85  }
86 
87  private:
88  // Flags
89  bool _haveData, _boundsError;
90  T _refValue;
91  // Data
92  double _xstart, _ystart, _dx, _dy;
94  // Interpolation method
96 
97  private:
102  void _setInterpolator(dataInterpMethod method);
103 
104  // BVR: I'm placing the comparison operator implementations inline here because
105  // it wasn't clear to me how to handle the template arguments out-of-line
106  public:
107 
108  // Comparison operator for floating point
109  template <typename U = T, std::enable_if_t<!std::is_compound<U>::value, int> = 0>
110  inline bool operator==(const isce3::core::LUT2d<T> & other) const {
111  // Check coordinates and dimensions first
112  bool equal = _data.width() == other.width();
113  equal *= _data.length() == other.length();
114  if (!equal) {
115  return false;
116  }
117  equal *= isce3::core::compareFloatingPoint(_xstart, other.xStart());
118  equal *= isce3::core::compareFloatingPoint(_ystart, other.yStart());
119  equal *= isce3::core::compareFloatingPoint(_dx, other.xSpacing());
120  equal *= isce3::core::compareFloatingPoint(_dy, other.ySpacing());
121  if (!equal) {
122  return false;
123  }
124  // If we made it this far, check contents
125  const isce3::core::Matrix<T> & otherMat = other.data();
126  for (size_t i = 0; i < _data.length(); ++i) {
127  for (size_t j = 0; j < _data.width(); ++j) {
128  equal *= isce3::core::compareFloatingPoint(_data(i,j), otherMat(i,j));
129  }
130  }
131  return equal;
132  }
133 
134  // Comparison operator for complex
135  template <typename U = T, std::enable_if_t<std::is_compound<U>::value, int> = 0>
136  inline bool operator==(const isce3::core::LUT2d<T> & other) const {
137  // Check coordinates and dimensions first
138  bool equal = _data.width() == other.width();
139  equal *= _data.length() == other.length();
140  if (!equal) {
141  return false;
142  }
143  equal *= isce3::core::compareFloatingPoint(_xstart, other.xStart());
144  equal *= isce3::core::compareFloatingPoint(_ystart, other.yStart());
145  equal *= isce3::core::compareFloatingPoint(_dx, other.xSpacing());
146  equal *= isce3::core::compareFloatingPoint(_dy, other.ySpacing());
147  if (!equal) {
148  return false;
149  }
150  // If we made it this far, check contents
151  const isce3::core::Matrix<T> & otherMat = other.data();
152  for (size_t i = 0; i < _data.length(); ++i) {
153  for (size_t j = 0; j < _data.width(); ++j) {
154  equal *= isce3::core::compareComplex(_data(i,j), otherMat(i,j));
155  }
156  }
157  return equal;
158  }
159 };
160 
161 // Default constructor using bilinear interpolator
162 template <typename T>
164 LUT2d() : _haveData(false), _boundsError(true), _refValue(0.0) {
165  _setInterpolator(isce3::core::BILINEAR_METHOD);
166 }
167 
168 // Constructor with specified interpolator
169 template <typename T>
171 LUT2d(isce3::core::dataInterpMethod method) : _haveData(false), _boundsError(true),
172  _refValue(0.0) {
173  _setInterpolator(method);
174 }
175 
176 // Deep copy constructor
177 template <typename T>
179 LUT2d(const isce3::core::LUT2d<T> & lut) : _haveData(lut.haveData()),
180  _boundsError(lut.boundsError()),
181  _refValue(lut.refValue()),
182  _xstart(lut.xStart()), _ystart(lut.yStart()),
183  _dx(lut.xSpacing()), _dy(lut.ySpacing()),
184  _data(lut.data()) {
185  _setInterpolator(lut.interpMethod());
186 }
187 
188 // Deep assignment operator
189 template <typename T>
192 operator=(const LUT2d<T> & lut) {
193  _refValue = lut.refValue();
194  _xstart = lut.xStart();
195  _ystart = lut.yStart();
196  _dx = lut.xSpacing();
197  _dy = lut.ySpacing();
198  _data = lut.data();
199  _haveData = lut.haveData();
200  _boundsError = lut.boundsError();
201  _setInterpolator(lut.interpMethod());
202  return *this;
203 }
bool contains(double y, double x) const
Check if point resides in domain of LUT.
Definition: LUT2d.h:79
bool compareComplex(std::complex< T > first, std::complex< T > second)
Tolerance test for real and imaginary components for scalar value.
Definition: Utilities.h:237
dataInterpMethod
Enumeration type to indicate interpolation method.
Definition: Constants.h:23
bool compareFloatingPoint(T first, T second)
Combined absolute and relative tolerance test.
Definition: Utilities.h:226
Data structure to store 2D Lookup table.
Definition: forward.h:30
void setFromData(const std::valarray< double > &xcoord, const std::valarray< double > &ycoord, const isce3::core::Matrix< T > &data)
Definition: LUT2d.cpp:52
size_t length() const
Get matrix length.
Definition: Matrix.icc:357
T eval(double y, double x) const
Definition: LUT2d.cpp:108
size_t width() const
Get matrix width.
Definition: Matrix.icc:349

Generated for ISCE3.0 by doxygen 1.8.5.