27 #include <almostEqual.hpp>
30 #ifndef PROSHADE_MATHS
31 #define PROSHADE_MATHS
37 extern void dgesdd_ (
char* jobz,
int* m,
int* n,
double* a,
int* lda,
double* s,
double* u,
int* ldu,
double* vt,
int* ldvt,
double* work,
int* lwork,
double* rwork,
int* iwork,
int* info );
39 extern void zgesdd_ (
char* jobz,
int* m,
int* n, std::complex<double>* a,
int* lda,
double* s, std::complex<double>* u,
int* ldu, std::complex<double>* vt,
int* ldvt, std::complex<double>* work,
int* lwork,
double* rwork,
int* iwork,
int* info );
41 extern void dgeev_ (
char* jobvl,
char* jobvr,
int* n,
double* a,
int* lda,
double* wr,
double* wi,
double* vl,
int* ldvl,
double* vr,
int* ldvr,
double* work,
int* lwork,
int* info );
60 proshade_double radius;
61 proshade_double radiusMax;
62 proshade_double radiusMin;
63 proshade_unsign angularDim;
64 proshade_unsign rotFunDim;
65 proshade_double representedAngle;
66 proshade_unsign sphereNumber;
68 proshade_double* axesValues;
69 std::vector< std::pair< proshade_unsign,proshade_unsign > > peaks;
71 ProSHADE_rotFun_sphere ( proshade_double rad, proshade_double radRange, proshade_unsign dim, proshade_unsign rfDim, proshade_double repAng, proshade_unsign sphNo );
82 std::vector<std::pair<proshade_unsign,proshade_unsign>>
getPeaks (
void );
90 void findAllPeaks ( proshade_signed noSmNeighbours, std::vector< proshade_double >* allHeights );
114 proshade_double a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, a30, a31, a32, a33;
115 proshade_double xStartIndex, xRange, yStartIndex, yRange;
125 BicubicInterpolator ( proshade_double** areaToInterpolate, proshade_double xStart, proshade_double yStart )
128 this->xStartIndex = xStart;
129 this->yStartIndex = yStart;
136 this->a00 = areaToInterpolate[1][1];
137 this->a01 = - ( 0.5 * areaToInterpolate[1][0] ) +
138 ( 0.5 * areaToInterpolate[1][2] );
139 this->a02 = areaToInterpolate[1][0] -
140 ( 2.5 * areaToInterpolate[1][1] ) +
141 ( 2.0 * areaToInterpolate[1][2] ) -
142 ( 0.5 * areaToInterpolate[1][3] );
143 this->a03 = - ( 0.5 * areaToInterpolate[1][0] ) +
144 ( 1.5 * areaToInterpolate[1][1] ) -
145 ( 1.5 * areaToInterpolate[1][2] ) +
146 ( 0.5 * areaToInterpolate[1][3] );
147 this->a10 = - ( 0.5 * areaToInterpolate[0][1] ) +
148 ( 0.5 * areaToInterpolate[2][1] );
149 this->a11 = ( 0.25 * areaToInterpolate[0][0] ) -
150 ( 0.25 * areaToInterpolate[0][2] ) -
151 ( 0.25 * areaToInterpolate[2][0] ) +
152 ( 0.25 * areaToInterpolate[2][2] );
153 this->a12 = - ( 0.5 * areaToInterpolate[0][0] ) +
154 ( 1.25 * areaToInterpolate[0][1] ) -
155 areaToInterpolate[0][2] +
156 ( 0.25 * areaToInterpolate[0][3] ) +
157 ( 0.5 * areaToInterpolate[2][0] ) -
158 ( 1.25 * areaToInterpolate[2][1] ) +
159 areaToInterpolate[2][2] -
160 ( 0.25 * areaToInterpolate[2][3] );
161 this->a13 = ( 0.25 * areaToInterpolate[0][0] ) -
162 ( 0.75 * areaToInterpolate[0][1] ) +
163 ( 0.75 * areaToInterpolate[0][2] ) -
164 ( 0.25 * areaToInterpolate[0][3] ) -
165 ( 0.25 * areaToInterpolate[2][0] ) +
166 ( 0.75 * areaToInterpolate[2][1] ) -
167 ( 0.75 * areaToInterpolate[2][2] ) +
168 ( 0.25 * areaToInterpolate[2][3] );
169 this->a20 = areaToInterpolate[0][1] -
170 ( 2.5 * areaToInterpolate[1][1] ) +
171 ( 2.0 * areaToInterpolate[2][1] ) -
172 ( 0.5 * areaToInterpolate[3][1] );
173 this->a21 = - ( 0.5 * areaToInterpolate[0][0] ) +
174 ( 0.5 * areaToInterpolate[0][2] ) +
175 ( 1.25 * areaToInterpolate[1][0] ) -
176 ( 1.25 * areaToInterpolate[1][2] ) -
177 areaToInterpolate[2][0] + areaToInterpolate[2][2] +
178 ( 0.25 * areaToInterpolate[3][0] ) -
179 ( 0.25 * areaToInterpolate[3][2] );
180 this->a22 = areaToInterpolate[0][0] -
181 ( 2.5 * areaToInterpolate[0][1] ) +
182 ( 2.0 * areaToInterpolate[0][2] ) -
183 ( 0.5 * areaToInterpolate[0][3] ) -
184 ( 2.5 * areaToInterpolate[1][0] ) +
185 ( 6.25 * areaToInterpolate[1][1] ) -
186 ( 5.0 * areaToInterpolate[1][2] ) +
187 ( 1.25 * areaToInterpolate[1][3] ) +
188 ( 2.0 * areaToInterpolate[2][0] ) -
189 ( 5.0 * areaToInterpolate[2][1] ) +
190 ( 4.0 * areaToInterpolate[2][2] ) -
191 areaToInterpolate[2][3] -
192 ( 0.5 * areaToInterpolate[3][0] ) +
193 ( 1.25 * areaToInterpolate[3][1] ) -
194 areaToInterpolate[3][2] +
195 ( 0.25 * areaToInterpolate[3][3] );
196 this->a23 = - ( 0.5 * areaToInterpolate[0][0] ) +
197 ( 1.5 * areaToInterpolate[0][1] ) -
198 ( 1.5 * areaToInterpolate[0][2] ) +
199 ( 0.5 * areaToInterpolate[0][3] ) +
200 ( 1.25 * areaToInterpolate[1][0] ) -
201 ( 3.75 * areaToInterpolate[1][1] ) +
202 ( 3.75 * areaToInterpolate[1][2] ) -
203 ( 1.25 * areaToInterpolate[1][3] ) -
204 areaToInterpolate[2][0] +
205 ( 3.0 * areaToInterpolate[2][1] ) -
206 ( 3.0 * areaToInterpolate[2][2] ) +
207 areaToInterpolate[2][3] +
208 ( 0.25 * areaToInterpolate[3][0] ) -
209 ( 0.75 * areaToInterpolate[3][1] ) +
210 ( 0.75 * areaToInterpolate[3][2] ) -
211 ( 0.25 * areaToInterpolate[3][3] );
212 this->a30 = - ( 0.5 * areaToInterpolate[0][1] ) +
213 ( 1.5 * areaToInterpolate[1][1] ) -
214 ( 1.5 * areaToInterpolate[2][1] ) +
215 ( 0.5*areaToInterpolate[3][1] );
216 this->a31 = ( 0.25 * areaToInterpolate[0][0] ) -
217 ( 0.25 * areaToInterpolate[0][2] ) -
218 ( 0.75 * areaToInterpolate[1][0] ) +
219 ( 0.75 * areaToInterpolate[1][2] ) +
220 ( 0.75 * areaToInterpolate[2][0] ) -
221 ( 0.75 * areaToInterpolate[2][2] ) -
222 ( 0.25 * areaToInterpolate[3][0] ) +
223 ( 0.25 * areaToInterpolate[3][2] );
224 this->a32 = - ( 0.5 * areaToInterpolate[0][0] ) +
225 ( 1.25 * areaToInterpolate[0][1] ) -
226 areaToInterpolate[0][2] +
227 ( 0.25 * areaToInterpolate[0][3] ) +
228 ( 1.5 * areaToInterpolate[1][0] ) -
229 ( 3.75 * areaToInterpolate[1][1] ) +
230 ( 3.0 * areaToInterpolate[1][2] ) -
231 ( 0.75 * areaToInterpolate[1][3] ) -
232 ( 1.5 * areaToInterpolate[2][0] ) +
233 ( 3.75 * areaToInterpolate[2][1] ) -
234 ( 3.0 * areaToInterpolate[2][2] ) +
235 ( 0.75 * areaToInterpolate[2][3] ) +
236 ( 0.5 * areaToInterpolate[3][0] ) -
237 ( 1.25 * areaToInterpolate[3][1] ) +
238 areaToInterpolate[3][2] -
239 ( 0.25 * areaToInterpolate[3][3] );
240 this->a33 = ( 0.25 * areaToInterpolate[0][0] ) -
241 ( 0.75 * areaToInterpolate[0][1] ) +
242 ( 0.75 * areaToInterpolate[0][2] ) -
243 ( 0.25 * areaToInterpolate[0][3] ) -
244 ( 0.75 * areaToInterpolate[1][0] ) +
245 ( 2.25 * areaToInterpolate[1][1] ) -
246 ( 2.25 * areaToInterpolate[1][2] ) +
247 ( 0.75 * areaToInterpolate[1][3] ) +
248 ( 0.75 * areaToInterpolate[2][0] ) -
249 ( 2.25 * areaToInterpolate[2][1] ) +
250 ( 2.25 * areaToInterpolate[2][2] ) -
251 ( 0.75 * areaToInterpolate[2][3] ) -
252 ( 0.25 * areaToInterpolate[3][0] ) +
253 ( 0.75 * areaToInterpolate[3][1] ) -
254 ( 0.75 * areaToInterpolate[3][2] ) +
255 ( 0.25 * areaToInterpolate[3][3] );
273 proshade_double
getValue ( proshade_double x, proshade_double y )
276 if ( ( ( x < this->xStartIndex ) || ( x > ( this->xStartIndex + this->xRange ) ) ) ||
277 ( ( y < this->yStartIndex ) || ( y > ( this->yStartIndex + this->yRange ) ) ) )
279 if ( ( x < this->xStartIndex ) || ( x > ( this->xStartIndex + this->xRange ) ) ) { std::cout <<
"PROBLEM WITH LAT" << std::endl; }
280 if ( ( y < this->yStartIndex ) || ( y > ( this->yStartIndex + this->yRange ) ) ) { std::cout <<
"PROBLEM WITH LON" << std::endl; }
282 throw ProSHADE_exception (
"Requested bicubic interpolation outside of pre-computed\n : square.",
"ES00064", __FILE__, __LINE__, __func__,
"The supplied x or y value(s) is outside of the range of\n : the bi-cubic interpolator's pre-computed square. Please\n : make sure the start values were correctly supplied when\n : the constructor was called or create a new interpolator\n : for these values." );
286 proshade_double unitSquareX = ( x - this->xStartIndex ) / this->xRange;
287 proshade_double unitSquareY = ( y - this->yStartIndex ) / this->yRange;
290 proshade_double x2 = std::pow ( unitSquareX, 2.0 );
291 proshade_double x3 = std::pow ( unitSquareX, 3.0 );
292 proshade_double y2 = std::pow ( unitSquareY, 2.0 );
293 proshade_double y3 = std::pow ( unitSquareY, 3.0 );
296 return ( ( this->a00 + this->a01 * unitSquareY + this->a02 * y2 + this->a03 * y3 ) +
297 ( this->a10 + this->a11 * unitSquareY + this->a12 * y2 + this->a13 * y3 ) * unitSquareX +
298 ( this->a20 + this->a21 * unitSquareY + this->a22 * y2 + this->a23 * y3 ) * x2 +
299 ( this->a30 + this->a31 * unitSquareY + this->a32 * y2 + this->a33 * y3 ) * x3 );
303 void complexMultiplication ( proshade_double* r1, proshade_double* i1, proshade_double* r2, proshade_double* i2,
304 proshade_double* retReal, proshade_double* retImag );
306 proshade_double* retReal, proshade_double* retImag );
309 void vectorMeanAndSD ( std::vector<proshade_double>* vec, proshade_double*& ret );
311 void arrayMedianAndIQR ( proshade_double* vec, proshade_unsign vecSize, proshade_double*& ret );
312 proshade_double
pearsonCorrCoeff ( proshade_double* valSet1, proshade_double* valSet2, proshade_unsign length );
314 proshade_unsign noSteps );
315 void getGLPolyAtZero ( proshade_unsign order, proshade_double *polyValue, proshade_double *deriValue );
316 void getGLFirstRealRoot ( proshade_double polyAtZero, proshade_unsign order, proshade_double *abscAtZero,
317 proshade_double *weighAtZero, proshade_unsign taylorSeriesCap );
318 proshade_double
evaluateGLPolynomial ( proshade_double *series, proshade_double target, proshade_unsign terms );
319 proshade_double
advanceGLPolyValue ( proshade_double from, proshade_double to, proshade_double valAtFrom, proshade_unsign order, proshade_unsign noSteps );
321 proshade_unsign noSteps );
323 proshade_double* abscissas, proshade_double* weights, proshade_double integralOverRange,
324 proshade_double maxSphereDists );
326 proshade_double* abscissas, proshade_double* weights, proshade_double integralOverRange,
327 proshade_double maxSphereDists, proshade_double* retReal, proshade_double* retImag );
330 void getEulerZYZFromSOFTPosition ( proshade_signed band, proshade_signed x, proshade_signed y, proshade_signed z, proshade_double* eulerAlpha,
331 proshade_double* eulerBeta, proshade_double* eulerGamma );
332 void getSOFTPositionFromEulerZYZ ( proshade_signed band, proshade_double eulerAlpha, proshade_double eulerBeta, proshade_double eulerGamma,
333 proshade_double* x, proshade_double* y, proshade_double* z );
336 void getAxisAngleFromRotationMatrix ( proshade_double* rotMat, proshade_double* x, proshade_double* y, proshade_double* z, proshade_double* ang, proshade_signed verbose = 1 );
337 void getAxisAngleFromRotationMatrix ( std::vector< proshade_double >* rotMat, proshade_double* x, proshade_double* y, proshade_double* z, proshade_double* ang, proshade_signed verbose = 1 );
340 void getEulerZYZFromRotMatrix ( proshade_double* rotMat, proshade_double* eA, proshade_double* eB, proshade_double* eG );
341 void getEulerZYZFromAngleAxis ( proshade_double axX, proshade_double axY, proshade_double axZ, proshade_double axAng, proshade_double* eA,
342 proshade_double* eB, proshade_double* eG );
343 void multiplyTwoSquareMatrices ( proshade_double* A, proshade_double* B, proshade_double* res, proshade_unsign dim = 3 );
345 proshade_double
normalDistributionValue ( proshade_double mean, proshade_double standardDev, proshade_double value );
346 proshade_double
computeDotProduct ( proshade_double* x1, proshade_double* y1, proshade_double* z1, proshade_double* x2, proshade_double* y2,
347 proshade_double* z2 );
348 proshade_double
computeDotProduct ( proshade_double x1, proshade_double y1, proshade_double z1, proshade_double x2, proshade_double y2,
349 proshade_double z2 );
350 proshade_double*
computeCrossProduct ( proshade_double* x1, proshade_double* y1, proshade_double* z1, proshade_double* x2, proshade_double* y2,
351 proshade_double* z2 );
352 proshade_double*
computeCrossProduct ( proshade_double x1, proshade_double y1, proshade_double z1, proshade_double x2, proshade_double y2,
353 proshade_double z2 );
362 proshade_double*
findRotMatMatchingVectors ( proshade_double x1, proshade_double y1, proshade_double z1, proshade_double x2, proshade_double y2,
363 proshade_double z2 );
365 std::vector < proshade_double >
findVectorFromTwoVAndTwoD ( proshade_double x1, proshade_double y1, proshade_double z1, proshade_double x2, proshade_double y2,
366 proshade_double z2, proshade_double dot1, proshade_double dot2 );
367 std::vector < proshade_double >
findVectorFromThreeVAndThreeD ( proshade_double x1, proshade_double y1, proshade_double z1, proshade_double x2, proshade_double y2,
368 proshade_double z2, proshade_double x3, proshade_double y3, proshade_double z3, proshade_double dot1,
369 proshade_double dot2, proshade_double dot3 );
370 std::vector< proshade_double >
multiplyGroupElementMatrices ( std::vector< proshade_double >* el1, std::vector< proshade_double >* el2 );
371 bool rotationMatrixSimilarity ( std::vector< proshade_double >* mat1, std::vector< proshade_double >* mat2, proshade_double tolerance = 0.1 );
375 bool vectorOrientationSimilarity ( proshade_double a1, proshade_double a2, proshade_double a3, proshade_double b1, proshade_double b2,
376 proshade_double b3, proshade_double tolerance = 0.1 );
378 proshade_double b3, proshade_double tolerance = 0.1 );
379 void optimiseAxisBiCubicInterpolation ( proshade_double* bestLattitude, proshade_double* bestLongitude, proshade_double* bestSum, std::vector<proshade_unsign>* sphereList,
380 std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*>* sphereMappedRotFun, proshade_double step = 0.05 );
382 std::vector<ProSHADE_internal_maths::BicubicInterpolator*>* interpols, std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*>* sphereMappedRotFun );
384 std::vector<ProSHADE_internal_maths::BicubicInterpolator*>* interpols, std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*>* sphereMappedRotFun );
386 std::vector<ProSHADE_internal_maths::BicubicInterpolator*>* interpols, std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*>* sphereMappedRotFun );
388 std::vector<ProSHADE_internal_maths::BicubicInterpolator*>* interpols, std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*>* sphereMappedRotFun );
389 bool isAxisUnique ( std::vector< proshade_double* >* CSymList, proshade_double* axis, proshade_double tolerance = 0.1,
bool improve =
false );
390 bool isAxisUnique ( std::vector< proshade_double* >* CSymList, proshade_double X, proshade_double Y, proshade_double Z, proshade_double fold, proshade_double tolerance );
391 proshade_signed
whichAxisUnique ( std::vector< proshade_double* >* CSymList, proshade_double* axis, proshade_double tolerance );
392 proshade_signed
whichAxisUnique ( std::vector< proshade_double* >* CSymList, proshade_double X, proshade_double Y, proshade_double Z, proshade_double fold, proshade_double tolerance );
393 std::vector< proshade_unsign >
findAllPrimes ( proshade_unsign upTo );
394 bool isPrime ( proshade_unsign toCheck );
395 proshade_double
computeGaussian ( proshade_double val, proshade_double sigma );
396 std::vector < proshade_double >
smoothen1D ( proshade_double step, proshade_signed windowSize, proshade_double sigma, std::vector< proshade_double > data, proshade_signed decRound = 2 );
397 proshade_single
getResolutionOfReflection ( proshade_single h, proshade_single k, proshade_single l, proshade_single xDim, proshade_single yDim, proshade_single zDim );
398 void binReciprocalSpaceReflections ( proshade_unsign xInds, proshade_unsign yInds, proshade_unsign zInds, proshade_single xSize, proshade_single ySize, proshade_single zSize,
399 proshade_signed* noBin, proshade_signed*& binIndexing, std::vector< proshade_single >*& resArray );
400 void cutIndicesToResolution ( proshade_signed xInds, proshade_signed yInds, proshade_signed zInds, proshade_single resolution, proshade_signed* binIndexing,
401 std::vector< proshade_single >* resArray, proshade_signed* cutXDim, proshade_signed* cutYDim,
402 proshade_signed* cutZDim, proshade_signed*& cutBinIndices, proshade_signed*& noBins );
403 void cutArrayToResolution ( proshade_signed xInds, proshade_signed yInds, proshade_signed zInds, proshade_signed noBins, fftw_complex* inputMap, fftw_complex*& cutMap );
404 proshade_double
computeFSC ( fftw_complex *fCoeffs1, fftw_complex *fCoeffs2, proshade_signed xInds, proshade_signed yInds, proshade_signed zInds,
405 proshade_signed noBins, proshade_signed* binIndexing, proshade_double**& binData, proshade_signed*& binCounts, proshade_double*& fscByBin,
406 bool averageByBinSize =
false );
407 void computeFSCWeightByBin ( proshade_double*& weights1, proshade_double*& weights2, proshade_signed* binIndexing, proshade_double* fscByBin, proshade_signed noBins,
408 proshade_signed xDim, proshade_signed yDim, proshade_signed zDim );
409 proshade_double
computeTheFValue ( proshade_complex* fCoeffs, proshade_double* weights, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim );
410 void computeTrFunDerivatives ( proshade_complex* fCoeffs, proshade_double* weights1, proshade_double* weights2, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim,
411 proshade_double*& firstDers, proshade_double*& secondDers );
412 proshade_double*
computeTrFunStep ( proshade_double* firstDers, proshade_double* secondDers );
413 std::vector< proshade_signed >
findPeaks1D ( std::vector< proshade_double > data );
414 proshade_double
findTopGroupSmooth ( std::vector< proshade_double* >* CSym,
size_t peakPos, proshade_double step, proshade_double sigma, proshade_signed windowSize, proshade_double maxLim = 1.0 );
415 proshade_double
findTopGroupSmooth ( std::vector< std::vector< proshade_double > >* CSym,
size_t peakPos, proshade_double step, proshade_double sigma, proshade_signed windowSize,
416 proshade_double maxLim = 1.0 );
417 void combineFourierForTranslation ( fftw_complex* tmpOut1, fftw_complex* tmpOut2, fftw_complex*& resOut, proshade_unsign xD, proshade_unsign yD, proshade_unsign zD );
418 void findHighestValueInMap ( fftw_complex* resIn, proshade_unsign xD, proshade_unsign yD, proshade_unsign zD, proshade_double* trsX,
419 proshade_double* trsY, proshade_double* trsZ, proshade_double* mapPeak );