libatomprobe
Library for Atom Probe Tomography (APT) computation
misc.h
Go to the documentation of this file.
1 /* misc.cpp : various numerical functions
2  * Copyright (C) 2020 Daniel Haley
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef ATOMPROBE_MATHS_MISC_H
19 #define ATOMPROBE_MATHS_MISC_H
20 
21 #include "gsl/gsl_matrix.h"
22 
23 #include <numeric>
24 #include <vector>
25 #include <limits>
26 #include <cmath>
27 
29 
30 namespace AtomProbe
31 {
32 
36  };
37 
38 //Multiply two matrices naively. If alloc=true, then the input matrix is overwritten, and resultant matrix must be deallocated with gsl_matrix_free().
39 void gsl_matrix_mult(const gsl_matrix *A, const gsl_matrix *B, gsl_matrix* &res,
40  bool alloc=false);
41 
43 // Uses SVD internally. Returns <0 on error.
44 unsigned int estimateRank(const gsl_matrix *m,
45  float tolerance=sqrt(std::numeric_limits<float>::epsilon()));
46 
48 // returns false if constrained. Note that input matrix M is overwritten
49 bool solveLeastSquares(gsl_matrix *m, gsl_vector *b, gsl_vector* &x);
50 
51 template<class T>
52 T weightedMean(const std::vector<T> &values, const std::vector<T> &weight)
53 {
54  //ASSERT(weight.size() == values.size());
55  if(values.empty())
56  return 0.0f;
57 
58  //sum of (value[]*weight[])
59  T sumWiXi=(T)0;
60  // sum of(weight[])
61  T wTotal=(T)0;
62  wTotal= std::accumulate(weight.begin(),weight.end(),(T)0);
63  for(size_t ui=0;ui<values.size();ui++)
64  {
65  //ASSERT(weight[ui] >=0.0f);
66  sumWiXi+=values[ui]*weight[ui];
67  }
68 
69  if(wTotal == 0.0f)
70  return 0.0f;
71 
72  return sumWiXi/wTotal;
73 }
74 
75 template<typename T>
76 void meanAndStdev(const std::vector<T> &f,float &meanVal,
77  float &stdevVal,bool normalCorrection=true)
78 {
79  double meanDbl=0;
80  for(size_t ui=0;ui<f.size();ui++)
81  meanDbl+=f[ui];
82  meanVal =meanDbl/f.size();
83 
84 
85  double stdevDbl=0;
86  for(size_t ui=0;ui<f.size();ui++)
87  {
88  float delta;
89  delta=f[ui]-meanVal;
90  stdevDbl+=delta*delta;
91  }
92  stdevVal = sqrtf( stdevDbl/float(f.size()-1));
93 
94  //Perform bias correction, assuming the input data is normally distributed
95  if(normalCorrection)
96  {
97  float n=f.size();
98  //Approximation to C4 = sqrt(2/(n-1))*gamma(n/2)/gamma((n-1)/2)
99  // multiplier must be applied to 1/(n-1) normalised standard deviation
100  // Citation:
101  // http://support.sas.com/documentation/cdl/en/qcug/63922/HTML/default/qcug_functions_sect007.htm
102  // https://en.wikipedia.org/wiki/Unbiased_estimation_of_standard_deviation
103  stdevVal*=(1.0 - 1.0/(4.0*n) - 7.0/(32.0*n*n) - 19.0/(128.0*n*n*n));
104  }
105 }
106 
108 
111 unsigned int vectorPointDir(const Point3D &pA, const Point3D &pB,
112  const Point3D &vC, const Point3D &vD);
113 
114 //Distance between a line segment and a point in 3D space
115 float distanceToSegment(const Point3D &fA, const Point3D &fB, const Point3D &p);
116 
117 
118 //TODO: Convert to vector input?
120 float signedDistanceToFacet(const Point3D &fA, const Point3D &fB,
121  const Point3D &fC, const Point3D &normal,const Point3D &p);
122 
123 float distanceToFacet(const Point3D &fA, const Point3D &fB,
124  const Point3D &fC, const Point3D &normal,const Point3D &p);
125 
126 
128 inline float dotProduct(float a1, float a2, float a3,
129  float b1, float b2, float b3)
130 {
131  return a1*b1 + a2*b2 + a3* b3;
132 }
133 
134 
135 //Calculate the determinant of a 3x3 matrix, C-order layout.
136 double det3by3(const double *ptArray);
137 
138 //Determines the volume of a quadrilateral pyramid
139 //input points "planarpts" must be adjacent (connected) by
140 //0 <-> 1 <-> 2 <-> 0, all points connected to apex
141 double pyramidVol(const Point3D *planarPts, const Point3D &apex);
142 
143 //Return strue if a triangle is degenerate (has colinear points)
144 bool triIsDegenerate(const Point3D &fA, const Point3D &fB,
145  const Point3D &fC);
146 
147 }
148 
149 #endif
float signedDistanceToFacet(const Point3D &fA, const Point3D &fB, const Point3D &fC, const Point3D &normal, const Point3D &p)
Find the distance between a point, and a triangular facet – may be positive or negative.
Definition: misc.cpp:172
double pyramidVol(const Point3D *planarPts, const Point3D &apex)
Definition: misc.cpp:290
void gsl_matrix_mult(const gsl_matrix *A, const gsl_matrix *B, gsl_matrix *&res, bool alloc=false)
Definition: misc.cpp:24
bool solveLeastSquares(gsl_matrix *m, gsl_vector *b, gsl_vector *&x)
Use an SVD based least-squares solver to solve Mx=b (for x).
Definition: misc.cpp:94
PointDir
Definition: misc.h:33
float distanceToSegment(const Point3D &fA, const Point3D &fB, const Point3D &p)
Definition: misc.cpp:156
void meanAndStdev(const std::vector< T > &f, float &meanVal, float &stdevVal, bool normalCorrection=true)
Definition: misc.h:76
A 3D point data class storage.
Definition: point3D.h:39
T weightedMean(const std::vector< T > &values, const std::vector< T > &weight)
Definition: misc.h:52
double det3by3(const double *ptArray)
Definition: misc.cpp:256
float dotProduct(float a1, float a2, float a3, float b1, float b2, float b3)
Inline func for calculating a(dot)b.
Definition: misc.h:128
unsigned int estimateRank(const gsl_matrix *m, float tolerance=sqrt(std::numeric_limits< float >::epsilon()))
Estimate the rank of the given matrix.
Definition: misc.cpp:58
bool triIsDegenerate(const Point3D &fA, const Point3D &fB, const Point3D &fC)
Definition: misc.cpp:266
float distanceToFacet(const Point3D &fA, const Point3D &fB, const Point3D &fC, const Point3D &normal, const Point3D &p)
Definition: misc.cpp:250
unsigned int vectorPointDir(const Point3D &pA, const Point3D &pB, const Point3D &vC, const Point3D &vD)
Check which way vectors attached to two 3D points "point",.
Definition: misc.cpp:127