18 #include <boost/thread/mutex.hpp> 19 #include <boost/weak_ptr.hpp> 27 #include <xmsgrid/geometry/GmPtSearch.h> 28 #include <xmsgrid/matrices/matrix.h> 52 enum { NF_CONSTANT, NF_GRAD_PLANE, NF_QUADRATIC };
72 BSHP<ThreadLoop> q = BDPC<ThreadLoop>(r);
79 std::vector<InterpPtInfo>
93 NodalFuncImpl(
const std::vector<Pt3d>& a_pts,
const std::vector<float>& a_scalar);
96 BSHP<GmPtSearch> a_ptSearch,
97 const std::vector<Pt3d>& a_pts,
98 const std::vector<float>& a_scalar,
102 bool a_modifiedShepardWeights,
109 virtual std::string
ToString()
const override;
132 BSHP<GmPtSearch> a_s,
133 std::vector<int>& nearestPts,
134 std::vector<InterpPtInfo>& matrixPts,
135 std::vector<double>& d2,
136 std::vector<double>& w);
139 void NodalFunc2d(
int a_ptIdx,
const std::vector<InterpPtInfo>& a_pts,
double* a_A);
140 void NodalFunc3d(
int a_ptIdx,
const std::vector<InterpPtInfo>& a_pts,
double* a_A);
190 BSHP<GmPtSearch> a_ptSearch,
191 const std::vector<Pt3d>& a_pts,
192 const std::vector<float>& a_scalar,
196 bool a_modifiedShepardWeights,
200 BSHP<NodalFunc> ptr(
new NodalFuncImpl(a_type, a_2d, a_ptSearch, a_pts, a_scalar, a_nNearest,
201 a_quad_oct, a_power, a_modifiedShepardWeights, a_p,
237 , m_modifiedShepardWeights(true)
239 , m_errorReport(false)
241 , m_natNeigh(nullptr)
265 BSHP<GmPtSearch> a_ptSearch,
266 const std::vector<Pt3d>& a_pts,
267 const std::vector<float>& a_scalar,
271 bool a_modifiedShepardWeights,
276 , m_nNearest(a_nNearest)
277 , m_quadOct(a_quad_oct)
280 , m_ptSearch(a_ptSearch)
284 , m_modifiedShepardWeights(a_modifiedShepardWeights)
286 , m_errorReport(false)
288 , m_natNeigh(a_natNeigh)
290 if (NF_GRAD_PLANE ==
m_type)
292 else if (NF_QUADRATIC ==
m_type)
299 for (
size_t i = 0; i <
m_pts.size(); ++i)
314 if (
m_pts.size() > 500)
317 mgr->SetThreadLoopClass(
NfThread(
this, s).CreateForNewThread());
318 if (
m_pts.size() < 10000)
319 mgr->ExplicitlySetNumThreads(2);
321 mgr->RunThreads((
int)
m_pts.size());
326 std::vector<int> nearestPts;
327 std::vector<InterpPtInfo> matrixPts;
328 std::vector<double> d2, w;
329 for (
size_t i = 0; i <
m_pts.size(); ++i)
331 NfForPt((
int)i, ps, nearestPts, matrixPts, d2, w);
346 std::vector<int>& nearestPts,
347 std::vector<InterpPtInfo>& matrixPts,
348 std::vector<double>& d2,
349 std::vector<double>& w)
357 nearestPts.erase(nearestPts.begin() + a_ptIdx);
360 m_natNeigh->GetNeighbors(a_ptIdx, nearestPts);
367 matrixPts.resize(nearestPts.size());
369 for (
size_t j = 0; j < nearestPts.size(); ++j)
372 matrixPts[j].m_loc =
m_pts[idx];
373 matrixPts[j].m_weight = w[j];
374 matrixPts[j].m_scalar =
m_scalar[idx];
391 double A[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
396 for (
int i = 0; i < 9; ++i)
409 double *M[9], VV[9], *A(a_A), m[9][9];
410 for (
int i = 0; i < 9; ++i)
414 if (!mxSolveBandedEquations(M, A, VV, 5, 5))
420 "Error computing nodal functions. Increase the number " 421 "of points used for nodal function calculation.";
435 double *M[10], VV[10], *A(a_A), m[10][10];
436 for (
int i = 0; i < 10; ++i)
440 if (!mxSolveBandedEquations(M, A, VV, 9, 9))
446 "Error computing nodal functions. Increase the number " 447 "of points used for nodal function calculation.";
463 double A[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
471 double A[3][3], x[3], B[3], *Aptr[3];
472 for (
int i = 0; i < 3; ++i)
476 for (
int j = 0; j < 3; ++j)
481 double dx, dy, dz(0), df, weight;
482 for (
size_t i = 0; i < a_pts.size(); ++i)
484 weight = a_pts[i].m_weight;
485 dx = a_pts[i].m_loc.x - p.
x;
486 dy = a_pts[i].m_loc.y - p.
y;
488 dz = a_pts[i].m_loc.z - p.
z;
489 df = a_pts[i].m_scalar -
m_scalar[a_ptIdx];
491 A[0][0] += weight * dx * dx;
492 A[0][1] += weight * dx * dy;
493 A[0][2] += weight * dx * dz;
494 A[1][1] += weight * dy * dy;
495 A[1][2] += weight * dy * dz;
496 A[2][2] += weight * dz * dz;
498 B[0] += weight * df * dx;
499 B[1] += weight * df * dy;
500 B[2] += weight * df * dz;
508 err = !mxSolveNxN(&Aptr[0], x, B, 2);
510 err = !mxSolve3x3(A, x, B);
513 if (B[0] == 0.0 && B[1] == 0.0 && B[2] == 0.0)
515 x[0] = x[1] = x[2] = 0.0;
523 "Error computing nodal functions. Increase the number " 524 "of points used for nodal function calculation.";
563 double fi = (double)
m_scalar[a_ptIdx];
564 double qi, dx, dy, dz;
565 dx = a_loc.
x -
m_pts[a_ptIdx].x;
566 dy = a_loc.
y -
m_pts[a_ptIdx].y;
575 dz = a_loc.
z -
m_pts[a_ptIdx].z;
591 if (a_ptIdx > 0 && a_ptIdx < (
int)
m_gradient.size())
600 std::stringstream ss;
641 BSHP<GmPtSearch> pts;
642 std::vector<Pt3d> vPts;
643 std::vector<float> vScalar;
645 NodalFunc::New(0,
true, pts, vPts, vScalar, -1,
false, 2,
true,
nullptr,
nullptr);
653 std::vector<Pt3d> p(1,
Pt3d(0, 0, 0));
654 std::vector<float> s(1, 0);
657 std::vector<InterpPtInfo> pInfo(2);
658 pInfo[0].m_loc =
Pt3d(1, 0, 0);
659 pInfo[0].m_scalar = 0;
660 pInfo[0].m_weight = .5;
661 pInfo[1].m_loc =
Pt3d(2, 0, 0);
662 pInfo[1].m_scalar = 0;
663 pInfo[1].m_weight = .5;
665 TS_ASSERT_EQUALS(
Pt3d(0, 0, 0), grad);
666 pInfo[0].m_scalar = 1;
667 pInfo[1].m_scalar = 2;
NfThread(NodalFuncImpl *a_nf, BSHP< GmPtSearch > a_ptSearch)
constructor
virtual int GetType() const override
get the nodal function type 1 = gradient plane, 2 = quadratic
virtual int GetNearestPointsOption() const override
get the nearest points option 0 = nearest points, 1 = natural neighbors
virtual void ComputeNodalFuncs() override
Computes gradients at each point for use in the interpolation process.
std::vector< InterpPtInfo > m_matrixPts
information about each point for nodal function calculation
VecDbl m_w
weight for each point
Implementation of NodalFunc.
std::vector< int > VecInt
std::vector< Pt3d > m_gradient
Calculated gradient coefficients at each point.
virtual double ScalarFromPtIdx(int a_ptIdx, const Pt3d &a_loc) const override
Computes gradients at each point for use in the interpolation process.
int m_type
1 gradient plane, 2 quadratic
void testCreateClass()
test class creation
InterpNatNeigh * m_natNeigh
Pt3d ComputeGradientForPoint(int a_ptIdx, const std::vector< InterpPtInfo > &a_pts)
Computes the gradient for this point.
std::vector< double > VecDbl
virtual int GetNumNearestPoints() const override
get the number of nearest points used in the nodal function calculation
virtual void GradientFromPtIdx(int a_ptIdx, Pt3d &a_grad) const override
Fills in the gradient.
static BSHP< NodalFunc > New(int a_type, bool a_2d, boost::shared_ptr< GmPtSearch > a_ptSearch, const std::vector< Pt3d > &a_pts, const std::vector< float > &a_scalar, int a_nNearest, bool a_quad_oct, double a_power, bool a_modifiedShepardWeights, boost::shared_ptr< Observer > a_p, InterpNatNeigh *a_natNeigh)
Creates a NodalFunc class.
void NodalFunc2d(int a_ptIdx, const std::vector< InterpPtInfo > &a_pts, double *a_A)
Computes the matrix for the passed in point.
int CurrIdx()
Returns the current index of the thread.
VecDbl2d m_quadratic
Calculated quadratic coefficients at each point.
BSHP< GmPtSearch > m_ptSearch
spatial index for searching points
void NfForPt(int a_ptIdx, BSHP< GmPtSearch > a_s, std::vector< int > &nearestPts, std::vector< InterpPtInfo > &matrixPts, std::vector< double > &d2, std::vector< double > &w)
Computes the nodal function for this point.
void VecToStream(std::stringstream &a_ss, const T &a_v, std::string a_label)
VecInt m_nearestPts
indexes of nearest points to location
bool m_errorReport
flag for reporting errors
std::vector< int > m_nearestAll
convenience variable when all points are used in calculation
bool m_modifiedShepardWeights
BSHP< Observer > m_prog
Observer that reports status of interpolation process.
BSHP< GmPtSearch > m_ptSearch
Class used to find nearest points.
void NodalFuncForPtFromMatrixPts(int a_ptIdx, const std::vector< InterpPtInfo > &a_pts)
Computes the nodal function for this point.
std::string GetAndClearStackStr()
void inNodalFuncSetUpMatrixAndVector(double xk, double yk, double fk, const std::vector< InterpPtInfo > &closest, double **M, double *VV)
Sets up matrices for nodal function calculations. Refactored out of GMS.
static BSHP< ThreadMgr > New()
Creates a ThreadMgr.
virtual bool GetUseModifiedShepardWeights() const override
get the option for using Modified Shepard Weights
bool m_2d
flag for computing distances in xy instead of xyz
void inNodalFuncSetUpMatrixAndVector3d(double xk, double yk, double zk, double fk, const std::vector< InterpPtInfo > &closest, double **M, double *vv)
Sets up matrices for nodal function calculations. Refactored out of GMS.
virtual std::string ToString() const override
Write the internals to a string.
void Worker() override
Calculates the nodal function in this thread.
VecDbl m_d2
distance squared from location to each point
const std::vector< float > & m_scalar
Scalars at the points used to interpolate.
const std::vector< Pt3d > & m_pts
Points used to interpolate.
void NodalFunc3d(int a_ptIdx, const std::vector< InterpPtInfo > &a_pts, double *a_A)
Computes the matrix for the passed in point.
Utility functions called by interpolation code.
void inDistanceSquared(const Pt3d &a_pt, const std::vector< int > &a_ptIdxs, const std::vector< Pt3d > &a_ptLoc, bool a_2d, std::vector< double > &a_d2)
Computes the distance squared between the point "a_pt" and the other points. The other points are def...
virtual bool GetUseQuadrantSearch() const override
get the option for using a quadrant (octant in 3d) search for the nearest points
void testComputeGradientForPoint()
test computing a gradient
double m_power
exponent used with inverse distance (1/d^m_power)
std::vector< VecDbl > VecDbl2d
static XmLog & Instance(bool a_delete=false, XmLog *a_new=NULL)
int m_nNearest
number of nearest points to consider in calculations
virtual ~NodalFunc()
Destructor.
Class to compute gradient plane and quadratic nodal functions for interpolation.
bool m_quadOct
flag for performing quadrant(2d) or octant (3d) searching for nearest pts
void inIdwWeights(const std::vector< double > &a_distSquare, double a_power, bool a_modifiedShepardWeights, std::vector< double > &a_w)
Computes the idw weights that would be assigned to points associated with the distance squared that i...
NodalFuncImpl(const std::vector< Pt3d > &a_pts, const std::vector< float > &a_scalar)
this constructor is only used with testing
BSHP< ThreadLoop > CreateForNewThread() override
Creates an instance of this class for the thread manager.
Class that performs natural neighbor interpolation.
NodalFuncImpl * m_nf
pointer to parent class
Threading class to compute nodal functions in parallel.