41 *retReal = (*r1)*(*r2) - (*i1)*(*i2);
42 *retImag = (*r1)*(*i2) + (*i1)*(*r2);
65 *retReal = (*r1)*(*r2) + (*i1)*(*i2);
66 *retImag = -(*r1)*(*i2) + (*i1)*(*r2);
86 proshade_double ret = (*r1)*(*r2) - (*i1)*(*i2);
106 proshade_double ret = (*r1)*(*r2) + (*i1)*(*i2);
124 ret[0] = std::accumulate ( vec->begin(), vec->end(), 0.0 ) /
static_cast<proshade_double
> ( vec->size() );
127 proshade_double squaredSum = std::inner_product ( vec->begin(), vec->end(), vec->begin(), 0.0 );
128 ret[1] = std::sqrt ( ( squaredSum /
static_cast<proshade_double
> ( vec->size() ) ) - std::pow ( ret[0], 2.0 ) );
131 const FloatingPoint< proshade_double > lhs1 ( ret[0] );
132 const FloatingPoint< proshade_double > lhs2 ( ret[1] );
133 if ( !lhs1.AlmostEquals ( lhs1 ) ) { ret[0] = 0.0; }
134 if ( !lhs2.AlmostEquals ( lhs2 ) ) { ret[1] = 0.0; }
152 if ( vec->size() < 3 ) { ret[0] = 0.0; ret[1] = 0.0;
return; }
155 std::sort ( vec->begin(), vec->end() );
158 if (
static_cast<proshade_unsign
> ( vec->size() ) % 2 == 0)
160 ret[0] = ( vec->at( (
static_cast<proshade_unsign
> ( vec->size() ) / 2 ) - 1 ) +
161 vec->at(
static_cast<proshade_unsign
> ( vec->size() ) / 2 ) ) / 2.0;
165 ret[0] = vec->at(
static_cast<proshade_unsign
> ( vec->size() ) / 2 );
169 proshade_double Q1, Q3;
170 if (
static_cast<proshade_unsign
> ( vec->size() ) % 2 == 0)
172 Q1 = ( vec->at( (
static_cast<proshade_unsign
> ( vec->size() ) / 4 ) - 1 ) +
173 vec->at(
static_cast<proshade_unsign
> ( vec->size() ) / 4 ) ) / 2.0;
174 Q3 = ( vec->at( ( (
static_cast<proshade_unsign
> ( vec->size() ) / 4 ) * 3 ) - 1 ) +
175 vec->at( (
static_cast<proshade_unsign
> ( vec->size() ) / 4 ) * 3 ) ) / 2.0;
179 Q1 = vec->at(
static_cast<proshade_unsign
> ( vec->size() ) / 4 );
180 Q3 = vec->at( (
static_cast<proshade_unsign
> ( vec->size() ) / 4 ) * 3 );
203 std::sort ( vec, vec + vecSize );
206 if ( vecSize % 2 == 0)
208 ret[0] = ( vec[ ( vecSize / 2 ) - 1 ] + vec[ vecSize / 2 ] ) / 2.0;
212 ret[0] = vec[ vecSize / 2 ];
216 proshade_double Q1, Q3;
217 if ( vecSize % 2 == 0)
219 Q1 = ( vec[ ( vecSize / 4 ) - 1 ] + vec[ vecSize / 4 ] ) / 2.0;
220 Q3 = ( vec[ ( ( vecSize / 4 ) * 3 ) - 1 ] + vec[ ( vecSize / 4 ) * 3 ] ) / 2.0;
224 Q1 = vec[ vecSize / 4 ];
225 Q3 = vec[ ( vecSize / 4 ) * 3 ];
249 proshade_double xMean = 0.0;
250 proshade_double yMean = 0.0;
251 proshade_double zeroCount = 0.0;
252 for ( proshade_unsign iter = 0; iter < length; iter++ )
254 xMean += valSet1[iter];
255 yMean += valSet2[iter];
257 xMean /=
static_cast<proshade_double
> ( length ) - zeroCount;
258 yMean /=
static_cast<proshade_double
> ( length ) - zeroCount;
261 proshade_double xmmymm = 0.0;
262 proshade_double xmmsq = 0.0;
263 proshade_double ymmsq = 0.0;
264 for ( proshade_unsign iter = 0; iter < length; iter++ )
266 xmmymm += ( valSet1[iter] - xMean ) * ( valSet2[iter] - yMean );
267 xmmsq += pow( valSet1[iter] - xMean, 2.0 );
268 ymmsq += pow( valSet2[iter] - yMean, 2.0 );
271 proshade_double ret = xmmymm / ( sqrt(xmmsq) * sqrt(ymmsq) );
274 if ( std::isnan ( ret ) ) {
return ( 0.0 ); }
294 throw ProSHADE_exception (
"The integration order is too low.",
"EI00019", __FILE__, __LINE__, __func__,
"The Gauss-Legendre integration order is less than 2. This\n : seems very low; if you have a very small structure or very\n : low resolution, please manually increase the integration\n : order. Otherwise, please report this as a bug." );
298 proshade_double polyValue = 0.0;
299 proshade_double deriValue = 0.0;
300 proshade_double weightSum = 0.0;
308 if ( order % 2 == 1 )
310 abscissas[((order-1)/2)] = polyValue;
311 weights[((order-1)/2)] = deriValue;
316 getGLFirstEvenRoot ( polyValue, order, &abscissas[(order/2)], &weights[(order/2)], taylorSeriesCap );
323 for ( proshade_unsign iter = 0; iter < order; iter++ )
325 weights[iter] = 2.0 / ( 1.0 - abscissas[iter] ) / ( 1.0 + abscissas[iter] ) / weights[iter] / weights[iter];
326 weightSum = weightSum + weights[iter];
330 for ( proshade_unsign iter = 0; iter < order; iter++ )
332 weights[iter] = 2.0 * weights[iter] / weightSum;
352 proshade_double hlpVal = 0.0;
353 proshade_double prevPoly = 1.0;
354 proshade_double prevPrevPoly = 0.0;
355 proshade_double prevDeri = 0.0;
356 proshade_double prevPrevDeri = 0.0;
358 for ( proshade_unsign ordIt = 0; ordIt < order; ordIt++ )
360 hlpVal =
static_cast<proshade_double
> ( ordIt );
361 *polyValue = -hlpVal * prevPrevPoly / ( hlpVal + 1.0 );
362 *deriValue = ( ( 2.0 * hlpVal + 1.0 ) * prevPoly - hlpVal * prevPrevDeri ) / ( hlpVal + 1.0 );
363 prevPrevPoly = prevPoly;
364 prevPoly = *polyValue;
365 prevPrevDeri = prevDeri;
366 prevDeri = *deriValue;
389 if ( taylorSeriesCap < 2 )
391 throw ProSHADE_exception (
"The Taylor series cap is too low.",
"EI00020", __FILE__, __LINE__, __func__,
"The Taylor series expansion limit is less than 2. This\n : seems very low; if you have a very small structure or very\n : low resolution, please manually increase the integration\n : order. Otherwise, please report this as a bug." );
396 proshade_double hlp = 0.0;
397 proshade_double hlpVal =
static_cast<proshade_double
> ( order );
398 proshade_double *abscSteps;
399 proshade_double *weightSteps;
402 abscSteps =
new proshade_double [taylorSeriesCap+2];
403 weightSteps =
new proshade_double [taylorSeriesCap+1];
407 abscSteps[1] = polyAtZero;
408 weightSteps[0] = 0.0;
411 for ( proshade_unsign iter = 0; iter <= taylorSeriesCap - 2; iter = iter + 2 )
413 hlp =
static_cast<proshade_double
> ( iter );
415 abscSteps[iter+2] = 0.0;
416 abscSteps[iter+3] = ( hlp * ( hlp + 1.0 ) - hlpVal * ( hlpVal + 1.0 ) ) * abscSteps[iter+1] / (hlp + 1.0) / (hlp + 2.0 );
418 weightSteps[iter+1] = 0.0;
419 weightSteps[iter+2] = ( hlp + 2.0 ) * abscSteps[iter+3];
423 for ( proshade_double iter = 0; iter < 5; iter++ )
425 *abscAtZero = *abscAtZero -
evaluateGLSeries ( abscSteps, *abscAtZero, taylorSeriesCap ) /
evaluateGLSeries ( weightSteps, *abscAtZero, taylorSeriesCap-1 );
427 *weighAtZero =
evaluateGLSeries ( weightSteps, *abscAtZero, taylorSeriesCap-1 );
452 proshade_double factorialValue = 1.0;
453 proshade_double value = 0.0;
456 for ( proshade_unsign iter = 1; iter <= terms; iter++ )
458 value = value + series[iter] * factorialValue;
459 factorialValue = factorialValue * target;
482 proshade_double hlpVal = 0.0;
483 proshade_double stepSize = 0.0;
484 proshade_double valChange = 0.0;
485 proshade_double valSecChange = 0.0;
486 proshade_double squareSteps = 0.0;
487 proshade_double curVal = 0.0;
490 stepSize = ( to - from ) /
static_cast<proshade_double
> ( taylorSeriesCap );
491 squareSteps = sqrt (
static_cast<proshade_double
> ( noSteps * ( noSteps + 1 ) ) );
495 for ( proshade_unsign iter = 0; iter < taylorSeriesCap; iter++ )
497 hlpVal = ( 1.0 - valAtFrom ) * ( 1.0 + valAtFrom );
498 valChange = - stepSize * hlpVal / ( squareSteps * sqrt ( hlpVal ) - 0.5 * valAtFrom * sin ( 2.0 * curVal ) );
499 valAtFrom = valAtFrom + valChange;
501 curVal = curVal + stepSize;
503 hlpVal = ( 1.0 - valAtFrom ) * ( 1.0 + valAtFrom );
504 valSecChange = - stepSize * hlpVal / ( squareSteps * sqrt ( hlpVal ) - 0.5 * valAtFrom * sin ( 2.0 * curVal ) );
505 valAtFrom = valAtFrom + 0.5 * ( valSecChange - valChange );
526 proshade_double hlpTaylorVal = 0.0;
527 proshade_double hlpOrderVal =
static_cast<proshade_double
> ( order );
528 proshade_double abscValueChange = 0.0;
529 proshade_double prevAbsc = 0.0;
530 proshade_double *hlpAbscSeries;
531 proshade_double *hlpWeightSeries;
532 proshade_unsign noSeriesElems = 0;
533 proshade_unsign oddEvenSwitch = 0;
536 if ( order % 2 == 1 )
538 noSeriesElems = ( order - 1 ) / 2 - 1;
543 noSeriesElems = order / 2 - 1;
548 hlpAbscSeries =
new proshade_double[taylorSeriesCap+2];
549 hlpWeightSeries =
new proshade_double[taylorSeriesCap+1];
552 for ( proshade_unsign serIt = noSeriesElems + 1; serIt < order - 1; serIt++ )
555 prevAbsc = abscissas[serIt];
556 abscValueChange =
advanceGLPolyValue ( M_PI/2.0, -M_PI/2.0, prevAbsc, order, taylorSeriesCap ) - prevAbsc;
559 hlpAbscSeries[0] = 0.0;
560 hlpAbscSeries[1] = 0.0;
561 hlpAbscSeries[2] = weights[serIt];
564 hlpWeightSeries[0] = 0.0;
565 hlpWeightSeries[1] = hlpAbscSeries[2];
568 for ( proshade_unsign tayIt = 0; tayIt <= taylorSeriesCap - 2; tayIt++ )
570 hlpTaylorVal =
static_cast<proshade_double
> ( tayIt );
572 hlpAbscSeries[tayIt+3] = ( 2.0 * prevAbsc * ( hlpTaylorVal + 1.0 ) * hlpAbscSeries[tayIt+2] + ( hlpTaylorVal * ( hlpTaylorVal + 1.0 ) - hlpOrderVal *
573 ( hlpOrderVal + 1.0 ) ) * hlpAbscSeries[tayIt+1] / ( hlpTaylorVal + 1.0 ) ) / ( 1.0 - prevAbsc ) / ( 1.0 + prevAbsc ) /
574 ( hlpTaylorVal + 2.0 );
576 hlpWeightSeries[tayIt+2] = ( hlpTaylorVal + 2.0 ) * hlpAbscSeries[tayIt+3];
580 for ( proshade_unsign iter = 0; iter < 5; iter++ )
582 abscValueChange = abscValueChange -
evaluateGLSeries ( hlpAbscSeries, abscValueChange, taylorSeriesCap ) /
587 abscissas[serIt+1] = prevAbsc + abscValueChange;
588 weights[serIt+1] =
evaluateGLSeries ( hlpWeightSeries, abscValueChange, taylorSeriesCap - 1 );
591 for ( proshade_unsign serIt = 0; serIt <= noSeriesElems + oddEvenSwitch; serIt++ )
593 abscissas[serIt] = -abscissas[order-serIt-1];
594 weights[serIt] = weights[order-serIt-1];
598 delete hlpAbscSeries;
599 delete hlpWeightSeries;
624 proshade_double ret = 0.0;
625 proshade_complex* intData =
new proshade_complex[order];
627 proshade_complex posVals;
628 proshade_unsign lesserPos = 0;
629 proshade_unsign upperPos = 0;
630 proshade_double lesserWeight = 0.0;
631 proshade_double upperWeight = 0.0;
634 for ( proshade_unsign absIter = 0; absIter < order; absIter++ )
641 posVals[0] = ( ( abscissas[absIter] + 1.0 ) / 2.0 ) * integralOverRange;
645 for ( proshade_unsign valIt = 0; valIt < valsSize; valIt++ )
647 if ( ( (
static_cast< proshade_double
> ( valIt ) * maxSphereDists ) <= posVals[0] ) && ( ( (
static_cast< proshade_double
> ( valIt ) + 1.0 ) * maxSphereDists ) > posVals[0] ) )
649 lesserPos =
static_cast<proshade_unsign
> ( valIt );
650 upperPos =
static_cast<proshade_unsign
> ( valIt + 1 );
658 if ( lesserPos != 0 )
661 lesserWeight =
static_cast< proshade_double
> ( upperPos ) - ( posVals[0] / maxSphereDists );
662 upperWeight = 1.0 - lesserWeight;
664 posVals[1] = ( lesserWeight * vals[lesserPos-1] ) + ( upperWeight * vals[upperPos-1] );
669 upperWeight = 1.0 - (
static_cast< proshade_double
> ( upperPos ) - ( posVals[0] / maxSphereDists ) );
671 posVals[1] = ( upperWeight * vals[upperPos-1] );
674 intData[absIter][0] = posVals[0];
675 intData[absIter][1] = posVals[1];
679 for ( proshade_unsign absPoint = 0; absPoint < order; absPoint++ )
681 ret += ( weights[absPoint] * intData[absPoint][1] );
685 ret *= ( integralOverRange / 2.0 );
711 void ProSHADE_internal_maths::gaussLegendreIntegration ( proshade_complex* vals, proshade_unsign valsSize, proshade_unsign order, proshade_double* abscissas, proshade_double* weights, proshade_double integralOverRange, proshade_double maxSphereDists, proshade_double* retReal, proshade_double* retImag )
714 proshade_triplet* intData =
new proshade_triplet [order];
716 proshade_triplet posVals;
717 proshade_unsign lesserPos = 0;
718 proshade_unsign upperPos = 0;
719 proshade_double lesserWeight = 0.0;
720 proshade_double upperWeight = 0.0;
723 for ( proshade_unsign absIter = 0; absIter < order; absIter++ )
731 posVals[0] = ( ( abscissas[absIter] + 1.0 ) / 2.0 ) * integralOverRange;
735 for ( proshade_unsign valIt = 0; valIt < valsSize; valIt++ )
737 if ( ( (
static_cast< proshade_double
> ( valIt ) * maxSphereDists ) <= posVals[0] ) && ( ( (
static_cast< proshade_double
> ( valIt ) + 1.0 ) * maxSphereDists ) > posVals[0] ) )
739 lesserPos =
static_cast<proshade_unsign
> ( valIt );
740 upperPos =
static_cast<proshade_unsign
> ( valIt + 1 );
748 if ( lesserPos != 0 )
751 lesserWeight =
static_cast< proshade_double
> ( upperPos ) - ( posVals[0] / maxSphereDists );
752 upperWeight = 1.0 - lesserWeight;
754 posVals[1] = ( lesserWeight * vals[lesserPos-1][0] ) + ( upperWeight * vals[upperPos-1][0] );
755 posVals[2] = ( lesserWeight * vals[lesserPos-1][1] ) + ( upperWeight * vals[upperPos-1][1] );
760 upperWeight = 1.0 - (
static_cast< proshade_double
> ( upperPos ) - ( posVals[0] / maxSphereDists ) );
762 posVals[1] = ( upperWeight * vals[upperPos-1][0] );
763 posVals[2] = ( upperWeight * vals[upperPos-1][1] );
766 intData[absIter][0] = posVals[0];
767 intData[absIter][1] = posVals[1];
768 intData[absIter][2] = posVals[2];
774 for ( proshade_unsign absPoint = 0; absPoint < order; absPoint++ )
776 *retReal += ( weights[absPoint] * intData[absPoint][1] );
777 *retImag += ( weights[absPoint] * intData[absPoint][2] );
781 *retReal *= ( integralOverRange / 2.0 );
782 *retImag *= ( integralOverRange / 2.0 );
808 std::complex<double> *rotMatU =
new std::complex<double> [dim*dim];
809 std::complex<double> *rotMatV =
new std::complex<double> [dim*dim];
810 std::complex<double> *work =
new std::complex<double> [( 4 * dim)];
811 int workDim = ( 4 * dim);
812 double* rwork =
new double[(7 * dim)];
813 int* iwork =
new int[(8 * dim)];
824 std::complex<double> *matrixToDecompose =
new std::complex<double>[dim*dim];
826 for (
int rowIt = 0; rowIt < dim; rowIt++ )
828 for (
int colIt = 0; colIt < dim; colIt++ )
830 matrixToDecompose[(colIt*dim)+rowIt] = std::complex<double> ( mat[rowIt][colIt][0], mat[rowIt][colIt][1] );
835 zgesdd_ ( &job, &dim, &dim, matrixToDecompose, &dim, singularValues, rotMatU, &dim, rotMatV, &dim,
836 work, &workDim, rwork, iwork, &returnValue );
844 delete[] matrixToDecompose;
847 if ( returnValue != 0 )
849 throw ProSHADE_exception (
"The LAPACK complex SVD algorithm did not converge!",
"EL00021", __FILE__, __LINE__, __func__,
"LAPACK algorithm for computing the singular value\n : decomposition of complex matrices did not converge and\n : therefore it was not possible to combine SH coefficients\n : from multiple shells. Changing the resolution may help,\n : contact me if this error persists." );
875 double* singularValues =
new double[dim];
876 std::complex<double> *rotMatU =
new std::complex< double > [dim*dim];
877 std::complex<double> *rotMatV =
new std::complex< double > [dim*dim];
878 std::complex<double> *work =
new std::complex< double > [
static_cast< proshade_unsign
>( ( 3 * dim) + pow( dim, 2 ) * dim)];
879 int workDim =
static_cast< int > ( ( 3 * dim ) + pow( dim, 2 ) );
880 double* rwork =
new double[
static_cast<proshade_unsign
>((5 * dim) + 5 * pow(dim,2))];
881 int* iwork =
new int[(8 * dim)];
891 std::complex<double> *matrixToDecompose =
new std::complex<double>[dim*dim];
893 for (
int rowIt = 0; rowIt < dim; rowIt++ )
895 for (
int colIt = 0; colIt < dim; colIt++ )
897 matrixToDecompose[(colIt*dim)+rowIt] = std::complex<double> ( mat[(rowIt*dim)+colIt], 0.0 );
902 zgesdd_ ( &job, &dim, &dim, matrixToDecompose, &dim, singularValues, rotMatU, &dim, rotMatV, &dim,
903 work, &workDim, rwork, iwork, &returnValue );
909 delete[] matrixToDecompose;
910 delete[] singularValues;
913 if ( ( returnValue != 0 ) && ( fail ) )
915 throw ProSHADE_exception (
"The LAPACK complex SVD algorithm did not converge!",
"EL00022", __FILE__, __LINE__, __func__,
"LAPACK algorithm for computing the singular value\n : decomposition of complex matrices did not converge and\n : therefore it was not possible to optimise the peak\n : positions in the (self-)rotation function. Changing the\n : resolution may help, contact me if this error persists." );
917 if ( ( returnValue != 0 ) && ( !fail ) )
924 for ( proshade_signed rowIt = 0; rowIt < dim; rowIt++ )
926 for ( proshade_signed colIt = 0; colIt < dim; colIt++ )
928 uAndV[(rowIt*3)+colIt] = rotMatU[( rowIt * 3 ) + colIt].real();
933 for ( proshade_signed rowIt = 0; rowIt < dim; rowIt++ )
935 for ( proshade_signed colIt = 0; colIt < dim; colIt++ )
937 uAndV[(rowIt*3)+colIt+9] = rotMatV[( rowIt * 3 ) + colIt].real();
966 *eulerAlpha = M_PI *
static_cast<proshade_double
> ( y ) / (
static_cast<proshade_double
> ( band ) ) ;
967 *eulerBeta = M_PI * ( 2.0 *
static_cast<proshade_double
> ( x ) ) / ( 4.0 *
static_cast<proshade_double
> ( band ) ) ;
968 *eulerGamma = M_PI *
static_cast<proshade_double
> ( z ) / (
static_cast<proshade_double
> ( band ) ) ;
995 *x = ( eulerBeta *
static_cast<proshade_double
> ( band ) * 2.0 ) / M_PI;
996 *y = ( eulerGamma *
static_cast<proshade_double
> ( band ) ) / M_PI;
997 *z = ( eulerAlpha *
static_cast<proshade_double
> ( band ) ) / M_PI;
1014 if ( std::abs ( std::cos ( eulerBeta ) ) <= 0.98 )
1017 matrix[0] = cos ( eulerAlpha ) * cos ( eulerBeta ) * cos ( eulerGamma ) - sin ( eulerAlpha ) * sin ( eulerGamma );
1018 matrix[1] = sin ( eulerAlpha ) * cos ( eulerBeta ) * cos ( eulerGamma ) + cos ( eulerAlpha ) * sin ( eulerGamma );
1019 matrix[2] = -sin ( eulerBeta ) * cos ( eulerGamma );
1022 matrix[3] = -cos ( eulerAlpha ) * cos ( eulerBeta ) * sin ( eulerGamma ) - sin ( eulerAlpha ) * cos ( eulerGamma );
1023 matrix[4] = -sin ( eulerAlpha ) * cos ( eulerBeta ) * sin ( eulerGamma ) + cos ( eulerAlpha ) * cos ( eulerGamma );
1024 matrix[5] = sin ( eulerBeta ) * sin ( eulerGamma );
1027 matrix[6] = cos ( eulerAlpha ) * sin ( eulerBeta );
1028 matrix[7] = sin ( eulerAlpha ) * sin ( eulerBeta );
1029 matrix[8] = cos ( eulerBeta );
1034 proshade_double qi = std::cos ( ( eulerAlpha - eulerGamma ) / 2.0 ) * std::sin ( eulerBeta / 2.0 );
1035 proshade_double qj = std::sin ( ( eulerAlpha - eulerGamma ) / 2.0 ) * std::sin ( eulerBeta / 2.0 );
1036 proshade_double qk = std::sin ( ( eulerAlpha + eulerGamma ) / 2.0 ) * std::cos ( eulerBeta / 2.0 );
1037 proshade_double qr = std::cos ( ( eulerAlpha + eulerGamma ) / 2.0 ) * std::cos ( eulerBeta / 2.0 );
1040 matrix[0] = -1.0 + 2.0 * std::pow ( qi, 2.0 ) + 2.0 * std::pow ( qr, 2.0 );
1041 matrix[1] = 2.0 * ( qi * qj - qk * qr );
1042 matrix[2] = 2.0 * ( qi * qk + qj * qr );
1045 matrix[3] = 2.0 * ( qi * qj + qk * qr );
1046 matrix[4] = -1.0 + 2.0 * std::pow ( qj, 2.0 ) + 2.0 * std::pow ( qr, 2.0 );
1047 matrix[5] = 2.0 * ( qj * qk - qi * qr );
1050 matrix[6] = 2.0 * ( qi * qk - qj * qr );
1051 matrix[7] = 2.0 * ( qj * qk + qi * qr );
1052 matrix[8] = -1.0 + 2.0 * std::pow ( qk, 2.0 ) + 2.0 * std::pow ( qr, 2.0 );
1070 if ( std::abs ( std::cos ( eulerBeta ) ) <= 0.9999999f )
1073 matrix[0] = cos ( eulerAlpha ) * cos ( eulerBeta ) * cos ( eulerGamma ) - sin ( eulerAlpha ) * sin ( eulerGamma );
1074 matrix[1] = sin ( eulerAlpha ) * cos ( eulerBeta ) * cos ( eulerGamma ) + cos ( eulerAlpha ) * sin ( eulerGamma );
1075 matrix[2] = -sin ( eulerBeta ) * cos ( eulerGamma );
1078 matrix[3] = -cos ( eulerAlpha ) * cos ( eulerBeta ) * sin ( eulerGamma ) - sin ( eulerAlpha ) * cos ( eulerGamma );
1079 matrix[4] = -sin ( eulerAlpha ) * cos ( eulerBeta ) * sin ( eulerGamma ) + cos ( eulerAlpha ) * cos ( eulerGamma );
1080 matrix[5] = sin ( eulerBeta ) * sin ( eulerGamma );
1083 matrix[6] = cos ( eulerAlpha ) * sin ( eulerBeta );
1084 matrix[7] = sin ( eulerAlpha ) * sin ( eulerBeta );
1085 matrix[8] = cos ( eulerBeta );
1090 proshade_single qi = std::cos ( ( eulerAlpha - eulerGamma ) / 2.0f ) * std::sin ( eulerBeta / 2.0f );
1091 proshade_single qj = std::sin ( ( eulerAlpha - eulerGamma ) / 2.0f ) * std::sin ( eulerBeta / 2.0f );
1092 proshade_single qk = std::sin ( ( eulerAlpha + eulerGamma ) / 2.0f ) * std::cos ( eulerBeta / 2.0f );
1093 proshade_single qr = std::cos ( ( eulerAlpha + eulerGamma ) / 2.0f ) * std::cos ( eulerBeta / 2.0f );
1096 matrix[0] = -1.0f + 2.0f * std::pow ( qi, 2.0f ) + 2.0f * std::pow ( qr, 2.0f );
1097 matrix[1] = 2.0f * ( qi * qj - qk * qr );
1098 matrix[2] = 2.0f * ( qi * qk + qj * qr );
1101 matrix[3] = 2.0f * ( qi * qj + qk * qr );
1102 matrix[4] = -1.0f + 2.0f * std::pow ( qj, 2.0f ) + 2.0f * std::pow ( qr, 2.0f );
1103 matrix[5] = 2.0f * ( qj * qk - qi * qr );
1106 matrix[6] = 2.0f * ( qi * qk - qj * qr );
1107 matrix[7] = 2.0f * ( qj * qk + qi * qr );
1108 matrix[8] = -1.0f + 2.0f * std::pow ( qk, 2.0f ) + 2.0f * std::pow ( qr, 2.0f );
1131 proshade_double singAtPiCheck = 0.01;
1132 proshade_double singAtIdentity = 0.05;
1135 if ( ( std::abs ( rotMat[1] - rotMat[3] ) < singAtPiCheck ) &&
1136 ( std::abs ( rotMat[2] - rotMat[6] ) < singAtPiCheck ) &&
1137 ( std::abs ( rotMat[5] - rotMat[7] ) < singAtPiCheck ) )
1140 if ( ( std::abs ( rotMat[1] + rotMat[3] ) < singAtIdentity ) &&
1141 ( std::abs ( rotMat[2] + rotMat[6] ) < singAtIdentity ) &&
1142 ( std::abs ( rotMat[5] + rotMat[7] ) < singAtIdentity ) &&
1143 ( std::abs ( rotMat[0] + rotMat[4] + rotMat[8] - 3.0 ) < singAtIdentity ) )
1158 proshade_double xx = ( rotMat[0] + 1.0 ) / 2.0;
1159 proshade_double yy = ( rotMat[4] + 1.0 ) / 2.0;
1160 proshade_double zz = ( rotMat[8] + 1.0 ) / 2.0;
1161 proshade_double xy = ( rotMat[1] + rotMat[3] ) / 4.0;
1162 proshade_double xz = ( rotMat[2] + rotMat[6] ) / 4.0;
1163 proshade_double yz = ( rotMat[5] + rotMat[7] ) / 4.0;
1165 if ( ( xx > yy ) && ( xx > zz ) )
1167 if ( xx < singAtPiCheck )
1176 *y = xy / sqrt ( xx );
1177 *z = xz / sqrt ( xx );
1183 if ( yy < singAtPiCheck )
1192 *x = xy / sqrt ( yy );
1193 *z = yz / sqrt ( yy );
1199 if ( zz < singAtPiCheck )
1208 *x = xz / sqrt ( zz );
1209 *y = yz / sqrt ( zz );
1214 const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( *x ), std::max ( std::abs ( *y ), std::abs ( *z ) ) ) );
1215 const FloatingPoint< proshade_double > rhs1 ( std::abs ( *x ) );
1216 const FloatingPoint< proshade_double > rhs2 ( std::abs ( *y ) );
1217 const FloatingPoint< proshade_double > rhs3 ( std::abs ( *z ) );
1218 if ( ( ( lhs1.AlmostEquals ( rhs1 ) ) && ( *x < 0.0 ) ) ||
1219 ( ( lhs1.AlmostEquals ( rhs2 ) ) && ( *y < 0.0 ) ) ||
1220 ( ( lhs1.AlmostEquals ( rhs3 ) ) && ( *z < 0.0 ) ) )
1227 if ( *ang < 0.0 ) { *ang = ( 2.0 * M_PI ) + *ang; }
1234 *ang = std::acos ( ( std::max ( -1.0, std::min ( 3.0, rotMat[0] + rotMat[4] + rotMat[8] ) ) - 1.0 ) / 2.0 );
1242 if ( std::abs ( *ang ) < singAtPiCheck )
1249 *x = rotMat[7] - rotMat[5];
1250 *y = rotMat[2] - rotMat[6];
1251 *z = rotMat[3] - rotMat[1];
1253 proshade_double normFactor = std::sqrt ( pow ( *x, 2.0 ) + pow ( *y, 2.0 ) + pow ( *z, 2.0 ) );
1259 const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( *x ), std::max ( std::abs ( *y ), std::abs ( *z ) ) ) );
1260 const FloatingPoint< proshade_double > rhs1 ( std::abs ( *x ) );
1261 const FloatingPoint< proshade_double > rhs2 ( std::abs ( *y ) );
1262 const FloatingPoint< proshade_double > rhs3 ( std::abs ( *z ) );
1263 if ( ( ( lhs1.AlmostEquals ( rhs1 ) ) && ( *x < 0.0 ) ) ||
1264 ( ( lhs1.AlmostEquals ( rhs2 ) ) && ( *y < 0.0 ) ) ||
1265 ( ( lhs1.AlmostEquals ( rhs3 ) ) && ( *z < 0.0 ) ) )
1272 if ( *ang < 0.0 ) { *ang = ( 2.0 * M_PI ) + *ang; }
1294 proshade_double singAtPiCheck = 0.01;
1295 proshade_double singAtIdentity = 0.05;
1298 if ( ( std::abs ( rotMat->at(1) - rotMat->at(3) ) < singAtPiCheck ) &&
1299 ( std::abs ( rotMat->at(2) - rotMat->at(6) ) < singAtPiCheck ) &&
1300 ( std::abs ( rotMat->at(5) - rotMat->at(7) ) < singAtPiCheck ) )
1303 if ( ( std::abs ( rotMat->at(1) + rotMat->at(3) ) < singAtIdentity ) &&
1304 ( std::abs ( rotMat->at(2) + rotMat->at(6) ) < singAtIdentity ) &&
1305 ( std::abs ( rotMat->at(5) + rotMat->at(7) ) < singAtIdentity ) &&
1306 ( std::abs ( rotMat->at(0) + rotMat->at(4) + rotMat->at(8) - 3.0 ) < singAtIdentity ) )
1321 proshade_double xx = ( rotMat->at(0) + 1.0 ) / 2.0;
1322 proshade_double yy = ( rotMat->at(4) + 1.0 ) / 2.0;
1323 proshade_double zz = ( rotMat->at(8) + 1.0 ) / 2.0;
1324 proshade_double xy = ( rotMat->at(1) + rotMat->at(3) ) / 4.0;
1325 proshade_double xz = ( rotMat->at(2) + rotMat->at(6) ) / 4.0;
1326 proshade_double yz = ( rotMat->at(5) + rotMat->at(7) ) / 4.0;
1328 if ( ( xx > yy ) && ( xx > zz ) )
1330 if ( xx < singAtPiCheck )
1339 *y = xy / sqrt ( xx );
1340 *z = xz / sqrt ( xx );
1346 if ( yy < singAtPiCheck )
1355 *x = xy / sqrt ( yy );
1356 *z = yz / sqrt ( yy );
1362 if ( zz < singAtPiCheck )
1371 *x = xz / sqrt ( zz );
1372 *y = yz / sqrt ( zz );
1377 const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( *x ), std::max ( std::abs ( *y ), std::abs ( *z ) ) ) );
1378 const FloatingPoint< proshade_double > rhs1 ( std::abs ( *x ) );
1379 const FloatingPoint< proshade_double > rhs2 ( std::abs ( *y ) );
1380 const FloatingPoint< proshade_double > rhs3 ( std::abs ( *z ) );
1381 if ( ( ( lhs1.AlmostEquals ( rhs1 ) ) && ( *x < 0.0 ) ) ||
1382 ( ( lhs1.AlmostEquals ( rhs2 ) ) && ( *y < 0.0 ) ) ||
1383 ( ( lhs1.AlmostEquals ( rhs3 ) ) && ( *z < 0.0 ) ) )
1396 *ang = std::acos ( ( std::max ( -1.0, std::min ( 3.0, rotMat->at(0) + rotMat->at(4) + rotMat->at(8) ) ) - 1.0 ) / 2.0 );
1404 if ( std::abs ( *ang ) < singAtPiCheck )
1411 *x = rotMat->at(7) - rotMat->at(5);
1412 *y = rotMat->at(2) - rotMat->at(6);
1413 *z = rotMat->at(3) - rotMat->at(1);
1415 proshade_double normFactor = std::sqrt ( pow ( *x, 2.0 ) + pow ( *y, 2.0 ) + pow ( *z, 2.0 ) );
1421 const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( *x ), std::max ( std::abs ( *y ), std::abs ( *z ) ) ) );
1422 const FloatingPoint< proshade_double > rhs1 ( std::abs ( *x ) );
1423 const FloatingPoint< proshade_double > rhs2 ( std::abs ( *y ) );
1424 const FloatingPoint< proshade_double > rhs3 ( std::abs ( *z ) );
1425 if ( ( ( lhs1.AlmostEquals ( rhs1 ) ) && ( *x < 0.0 ) ) ||
1426 ( ( lhs1.AlmostEquals ( rhs2 ) ) && ( *y < 0.0 ) ) ||
1427 ( ( lhs1.AlmostEquals ( rhs3 ) ) && ( *z < 0.0 ) ) )
1451 if ( ( ang == 0.0 ) || ( std::isinf ( ang ) ) )
1454 for ( proshade_unsign i = 0; i < 9; i++ ) { rotMat[i] = 0.0; }
1464 proshade_double cAng = cos ( ang );
1465 proshade_double sAng = sin ( ang );
1466 proshade_double tAng = 1.0 - cAng;
1468 rotMat[0] = cAng + x * x * tAng;
1469 rotMat[4] = cAng + y * y * tAng;
1470 rotMat[8] = cAng + z * z * tAng;
1472 proshade_double tmp1 = x * y * tAng;
1473 proshade_double tmp2 = z * sAng;
1474 rotMat[3] = tmp1 + tmp2;
1475 rotMat[1] = tmp1 - tmp2;
1477 tmp1 = x * z * tAng;
1479 rotMat[6] = tmp1 - tmp2;
1480 rotMat[2] = tmp1 + tmp2;
1482 tmp1 = y * z * tAng;
1484 rotMat[7] = tmp1 + tmp2;
1485 rotMat[5] = tmp1 - tmp2;
1503 if ( ( ang == 0.0 ) || ( std::isinf ( ang ) ) )
1506 for (
size_t i = 0; i < 9; i++ ) { rotMat[i] = 0.0f; }
1516 proshade_single cAng = cos (
static_cast< proshade_single
> ( ang ) );
1517 proshade_single sAng = sin (
static_cast< proshade_single
> ( ang ) );
1518 proshade_single tAng = 1.0f - cAng;
1520 rotMat[0] = cAng +
static_cast< proshade_single
> ( x ) *
static_cast< proshade_single
> ( x ) * tAng;
1521 rotMat[4] = cAng +
static_cast< proshade_single
> ( y ) *
static_cast< proshade_single
> ( y ) * tAng;
1522 rotMat[8] = cAng +
static_cast< proshade_single
> ( z ) *
static_cast< proshade_single
> ( z ) * tAng;
1524 proshade_single tmp1 =
static_cast< proshade_single
> ( x ) *
static_cast< proshade_single
> ( y ) * tAng;
1525 proshade_single tmp2 =
static_cast< proshade_single
> ( z ) * sAng;
1526 rotMat[3] = tmp1 + tmp2;
1527 rotMat[1] = tmp1 - tmp2;
1529 tmp1 =
static_cast< proshade_single
> ( x ) *
static_cast< proshade_single
> ( z ) * tAng;
1530 tmp2 =
static_cast< proshade_single
> ( y ) * sAng;
1531 rotMat[6] = tmp1 - tmp2;
1532 rotMat[2] = tmp1 + tmp2;
1534 tmp1 =
static_cast< proshade_single
> ( y ) *
static_cast< proshade_single
> ( z ) * tAng;
1535 tmp2 =
static_cast< proshade_single
> ( x ) * sAng;
1536 rotMat[7] = tmp1 + tmp2;
1537 rotMat[5] = tmp1 - tmp2;
1554 if ( std::abs( rotMat[8] ) <= 0.99999 )
1557 *eA = std::atan2 ( rotMat[7], rotMat[6] );
1558 *eB = std::acos ( rotMat[8] );
1559 *eG = std::atan2 ( rotMat[5], -rotMat[2] );
1564 if ( rotMat[8] >= 0.99999 )
1567 *eA = std::atan2 ( rotMat[3], rotMat[0] );
1571 if ( rotMat[8] <= -0.99999 )
1574 *eA = std::atan2 ( rotMat[3], rotMat[0] );
1581 if ( *eA < 0.0 ) { *eA = 2.0 * M_PI + *eA; }
1582 if ( *eB < 0.0 ) { *eB = M_PI + *eB; }
1583 if ( *eG < 0.0 ) { *eG = 2.0 * M_PI + *eG; }
1605 if ( ( axAng == 0.0 ) || ( std::isinf ( axAng ) ) )
1617 proshade_double cAng = std::cos ( axAng );
1618 proshade_double sAng = std::sin ( axAng );
1619 proshade_double tAng = 1.0 - cAng;
1621 proshade_double element22 = cAng + axZ * axZ * tAng;
1623 proshade_double tmp1 = axX * axZ * tAng;
1624 proshade_double tmp2 = axY * sAng;
1625 proshade_double element20 = tmp1 - tmp2;
1626 proshade_double element02 = tmp1 + tmp2;
1628 tmp1 = axY * axZ * tAng;
1630 proshade_double element21 = tmp1 + tmp2;
1631 proshade_double element12 = tmp1 - tmp2;
1634 if ( std::abs( element22 ) <= 0.99999 )
1637 *eA = std::atan2 ( element21, element20 );
1638 *eB = std::acos ( element22 );
1639 *eG = std::atan2 ( element12, -element02 );
1644 tmp1 = axX * axY * tAng;
1646 proshade_double element10 = tmp1 + tmp2;
1647 proshade_double element00 = cAng + axX * axX * tAng;
1650 if ( element22 >= 0.99999 )
1653 *eA = std::atan2 ( element10, element00 );
1657 if ( element22 <= -0.99999 )
1660 *eA = std::atan2 ( element10, element00 );
1667 if ( *eA < 0.0 ) { *eA = 2.0 * M_PI + *eA; }
1668 if ( *eB < 0.0 ) { *eB = M_PI + *eB; }
1669 if ( *eG < 0.0 ) { *eG = 2.0 * M_PI + *eG; }
1688 for ( proshade_unsign iter = 0; iter < 9; iter++ ) { res[iter] = 0.0; }
1691 for ( proshade_unsign row = 0; row < dim; row++ )
1693 for ( proshade_unsign col = 0; col < dim; col++ )
1695 for ( proshade_unsign inner = 0; inner < dim; inner++ )
1697 res[(row*dim)+col] += A[(inner*dim)+row] * B[(col*dim)+inner];
1714 std::vector < proshade_signed > ret;
1717 bool changeSign =
false;
1718 if ( number < 0 ) { changeSign =
true; number = -number; }
1725 while ( number % 2 == 0 )
1728 number = number / 2;
1732 for ( proshade_double posDiv = 3; posDiv <= sqrt ( static_cast< proshade_double > ( number ) ); posDiv += 2.0 )
1735 while ( number %
static_cast< proshade_signed
> ( posDiv ) == 0 )
1738 number = number /
static_cast< proshade_signed
> ( posDiv );
1746 if ( changeSign ) { ret.at(0) = -ret.at(0); }
1763 return ( ( 1.0 / sqrt ( 2.0 * M_PI * pow(standardDev,2.0) ) ) * std::exp ( - pow( value - mean, 2.0 ) / 2.0 * pow(standardDev,2.0) ) );
1780 return ( (*x1 * *x2) + (*y1 * *y2) + (*z1 * *z2) );
1796 return ( (x1 * x2) + (y1 * y2) + (z1 * z2) );
1812 proshade_double* crossProd =
new proshade_double[3];
1816 crossProd[0] = ( (*y1) * (*z2) ) - ( (*z1) * (*y2) );
1817 crossProd[1] = ( (*z1) * (*x2) ) - ( (*x1) * (*z2) );
1818 crossProd[2] = ( (*x1) * (*y2) ) - ( (*y1) * (*x2) );
1821 return ( crossProd );
1834 proshade_double* ret =
new proshade_double[9];
1838 ret[0] = ( mat1[0] * mat2[0] ) + ( mat1[1] * mat2[3] ) + ( mat1[2] * mat2[6] );
1839 ret[1] = ( mat1[0] * mat2[1] ) + ( mat1[1] * mat2[4] ) + ( mat1[2] * mat2[7] );
1840 ret[2] = ( mat1[0] * mat2[2] ) + ( mat1[1] * mat2[5] ) + ( mat1[2] * mat2[8] );
1841 ret[3] = ( mat1[3] * mat2[0] ) + ( mat1[4] * mat2[3] ) + ( mat1[5] * mat2[6] );
1842 ret[4] = ( mat1[3] * mat2[1] ) + ( mat1[4] * mat2[4] ) + ( mat1[5] * mat2[7] );
1843 ret[5] = ( mat1[3] * mat2[2] ) + ( mat1[4] * mat2[5] ) + ( mat1[5] * mat2[8] );
1844 ret[6] = ( mat1[6] * mat2[0] ) + ( mat1[7] * mat2[3] ) + ( mat1[8] * mat2[6] );
1845 ret[7] = ( mat1[6] * mat2[1] ) + ( mat1[7] * mat2[4] ) + ( mat1[8] * mat2[7] );
1846 ret[8] = ( mat1[6] * mat2[2] ) + ( mat1[7] * mat2[5] ) + ( mat1[8] * mat2[8] );
1864 proshade_double* ret =
new proshade_double[3];
1868 ret[0] = ( x * mat[0] ) + ( y * mat[1] ) + ( z * mat[2] );
1869 ret[1] = ( x * mat[3] ) + ( y * mat[4] ) + ( z * mat[5] );
1870 ret[2] = ( x * mat[6] ) + ( y * mat[7] ) + ( z * mat[8] );
1888 proshade_single* ret =
new proshade_single[3];
1892 ret[0] = ( x * mat[0] ) + ( y * mat[1] ) + ( z * mat[2] );
1893 ret[1] = ( x * mat[3] ) + ( y * mat[4] ) + ( z * mat[5] );
1894 ret[2] = ( x * mat[6] ) + ( y * mat[7] ) + ( z * mat[8] );
1909 proshade_double* inverse =
new proshade_double[9];
1913 proshade_double matDet = ( mat[0] * mat[4] * mat[8] ) +
1914 ( mat[1] * mat[5] * mat[6] ) +
1915 ( mat[2] * mat[3] * mat[7] ) -
1916 ( mat[0] * mat[5] * mat[7] ) -
1917 ( mat[1] * mat[3] * mat[8] ) -
1918 ( mat[2] * mat[4] * mat[6] );
1921 inverse[0] = ( mat[4] * mat[8] - mat[5] * mat[7] ) / matDet;
1922 inverse[1] = ( mat[2] * mat[7] - mat[1] * mat[8] ) / matDet;
1923 inverse[2] = ( mat[1] * mat[5] - mat[2] * mat[4] ) / matDet;
1924 inverse[3] = ( mat[5] * mat[6] - mat[3] * mat[8] ) / matDet;
1925 inverse[4] = ( mat[0] * mat[8] - mat[2] * mat[6] ) / matDet;
1926 inverse[5] = ( mat[2] * mat[3] - mat[0] * mat[5] ) / matDet;
1927 inverse[6] = ( mat[3] * mat[7] - mat[4] * mat[6] ) / matDet;
1928 inverse[7] = ( mat[1] * mat[6] - mat[0] * mat[7] ) / matDet;
1929 inverse[8] = ( mat[0] * mat[4] - mat[1] * mat[3] ) / matDet;
1942 proshade_double tmp;
1982 proshade_double* inPlaneRotation =
new proshade_double[9];
1983 proshade_double* basisChangeMat =
new proshade_double[9];
1988 proshade_double normF = std::sqrt( std::pow( x1, 2.0 ) + std::pow ( y1, 2.0 ) + std::pow ( z1, 2.0 ) );
1989 x1 /= normF; y1 /= normF; z1 /= normF;
1991 normF = std::sqrt( std::pow( x2, 2.0 ) + std::pow ( y2, 2.0 ) + std::pow ( z2, 2.0 ) );
1992 x2 /= normF; y2 /= normF; z2 /= normF;
1996 proshade_double crossProdMag = std::sqrt( std::pow( crossProd[0], 2.0 ) + std::pow ( crossProd[1], 2.0 ) + std::pow ( crossProd[2], 2.0 ) );
2003 inPlaneRotation[0] = dotProd; inPlaneRotation[1] = -crossProdMag; inPlaneRotation[2] = 0.0;
2004 inPlaneRotation[3] = crossProdMag; inPlaneRotation[4] = dotProd; inPlaneRotation[5] = 0.0;
2005 inPlaneRotation[6] = 0.0; inPlaneRotation[7] = 0.0; inPlaneRotation[8] = 1.0;
2009 normF = std::sqrt ( std::pow ( x2 - ( dotProd * x1 ), 2.0 ) + std::pow ( y2 - ( dotProd * y1 ), 2.0 ) + std::pow ( z2 - ( dotProd * z1 ), 2.0 ) );
2011 basisChangeMat[0] = x1; basisChangeMat[1] = ( x2 - ( dotProd * x1 ) ) / normF; basisChangeMat[2] = crossProd[0];
2012 basisChangeMat[3] = y1; basisChangeMat[4] = ( y2 - ( dotProd * y1 ) ) / normF; basisChangeMat[5] = crossProd[1];
2013 basisChangeMat[6] = z1; basisChangeMat[7] = ( z2 - ( dotProd * z1 ) ) / normF; basisChangeMat[8] = crossProd[2];
2024 delete[] inPlaneRotation;
2025 delete[] basisChangeMat;
2026 delete[] basisChangeMatInverse;
2058 std::vector < proshade_double > ret;
2061 proshade_double solX = ( -sqrt ( pow ( 2.0 * x1 * y1 * dot2 * y2 + 2.0 * x1 * z1 * dot2 * z2 - 2.0 * x1 * dot1 * pow ( y2, 2.0 ) - 2.0 * x1 * dot1 * pow ( z2, 2.0 ) - 2.0 * pow ( y1, 2.0 ) * dot2 * x2 + 2.0 * y1 * dot1 * x2 * y2 - 2.0 * pow ( z1, 2.0 ) * dot2 * x2 + 2.0 * z1 * dot1 * x2 * z2, 2.0 ) -
2062 4.0 * ( pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * x1 * y1 * x2 * y2 - 2.0 * x1 * z1 * x2 * z2 + pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) ) *
2063 ( pow ( y1, 2.0 ) * pow ( dot2, 2.0 ) - pow ( y1, 2.0 ) * pow ( z2, 2.0 ) + 2.0 * y1 * z1 * y2 * z2 - 2.0 * y1 * dot1 * dot2 * y2 + pow ( z1, 2.0 ) * pow ( dot2, 2.0 ) - pow ( z1, 2.0 ) * pow ( y2, 2.0 ) - 2.0 * z1 * dot1 * dot2 * z2 + pow ( dot1, 2.0 ) * pow ( y2, 2.0 ) + pow ( dot1, 2.0 ) * pow ( z2, 2.0 ) ) ) -
2064 2.0 * x1 * y1 * dot2 * y2 - 2.0 * x1 * z1 * dot2 * z2 + 2.0 * x1 * dot1 * pow ( y2, 2.0 ) + 2.0 * x1 * dot1 * pow ( z2, 2.0 ) + 2.0 * pow ( y1, 2.0 ) * dot2 * x2 - 2.0 * y1 * dot1 * x2 * y2 + 2.0 * pow ( z1, 2.0 ) * dot2 * x2 - 2.0 * z1 * dot1 * x2 * z2 ) /
2065 ( 2.0 * ( pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * x1 * y1 * x2 * y2 - 2.0 * x1 * z1 * x2 * z2 + pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) ) );
2066 proshade_double solY = ( ( dot2 * pow ( x2, 2.0 ) * pow ( z1, 3.0 ) ) /
2067 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) -
2068 ( dot1 * pow ( x2, 2.0 ) * z2 * pow ( z1, 2.0 ) ) /
2069 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) -
2070 ( 2.0 * x1 * dot2 * x2 * z2 * pow ( z1, 2.0 ) ) /
2071 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) - dot2 * z1 -
2072 ( x2 * sqrt ( pow ( - 2.0 * dot2 * x2 * pow ( y1, 2.0 ) + 2.0 * x1 * dot2 * y2 * y1 + 2.0 * dot1 * x2 * y2 * y1 - 2.0 * x1 * dot1 * pow ( y2, 2.0 ) - 2.0 * x1 * dot1 * pow ( z2, 2.0 ) - 2.0 * pow ( z1, 2.0 ) * dot2 * x2 + 2.0 * x1 * z1 * dot2 * z2 + 2.0 * z1 * dot1 * x2 * z2, 2.0 ) -
2073 4.0 * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) *
2074 ( pow ( y1, 2.0 ) * pow ( dot2, 2.0 ) + pow ( z1, 2.0 ) * pow ( dot2, 2.0 ) - 2.0 * y1 * dot1 * y2 * dot2 - 2.0 * z1 * dot1 * z2 * dot2 - pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( dot1, 2.0 ) * pow ( y2, 2.0 ) - pow ( y1, 2.0 ) * pow ( z2, 2.0 ) + pow ( dot1, 2.0 ) * pow ( z2, 2.0 ) + 2.0 * y1 * z1 * y2 * z2 ) ) * z1 ) /
2075 ( 2.0 * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) +
2076 ( pow ( y1, 2.0 ) * dot2 * pow ( x2, 2.0 ) * z1 ) /
2077 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) +
2078 ( x1 * dot1 * x2 * pow ( y2, 2.0 ) * z1 ) /
2079 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) +
2080 ( pow ( x1, 2.0 ) * dot2 * pow ( z2, 2.0 ) * z1 ) /
2081 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) +
2082 ( 2.0 * x1 * dot1 * x2 * pow ( z2, 2.0 ) * z1 ) /
2083 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) -
2084 ( y1 * dot1 * pow ( x2, 2.0 ) * y2 * z1 ) /
2085 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) -
2086 ( x1 * y1 * dot2 * x2 * y2 * z1 ) /
2087 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) + dot1 * z2 +
2088 ( x1 * z2 * sqrt ( pow ( -2.0 * dot2 * x2 * pow ( y1, 2.0 ) + 2.0 * x1 * dot2 * y2 * y1 + 2.0 * dot1 * x2 * y2 * y1 - 2.0 * x1 * dot1 * pow ( y2, 2.0 ) - 2.0 * x1 * dot1 * pow ( z2, 2.0 ) - 2.0 * pow ( z1, 2.0 ) * dot2 * x2 + 2.0 * x1 * z1 * dot2 * z2 + 2.0 * z1 * dot1 * x2 * z2, 2.0 ) -
2089 4.0 * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) *
2090 ( pow ( y1, 2.0 ) * pow ( dot2, 2.0 ) + pow ( z1, 2.0 ) * pow ( dot2, 2.0 ) - 2.0 * y1 * dot1 * y2 * dot2 - 2.0 * z1 * dot1 * z2 * dot2 - pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( dot1, 2.0 ) * pow ( y2, 2.0 ) - pow ( y1, 2.0 ) * pow ( z2, 2.0 ) + pow ( dot1, 2.0 ) * pow ( z2, 2.0 ) + 2.0 * y1 * z1 * y2 * z2 ) ) ) /
2091 ( 2.0 * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) -
2092 ( pow ( x1, 2.0 ) * dot1 * pow ( z2, 3.0 ) ) /
2093 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) -
2094 ( pow ( x1, 2.0 ) * dot1 * pow ( y2, 2.0 ) * z2 ) /
2095 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) -
2096 ( x1 * pow ( y1, 2.0 ) * dot2 * x2 * z2 ) /
2097 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) +
2098 ( pow ( x1, 2.0 ) * y1 * dot2 * y2 * z2 ) /
2099 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) +
2100 ( x1 * y1 * dot1 * x2 * y2 * z2 ) /
2101 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) / ( y1 * z2 - z1 * y2 );
2102 proshade_double solZ = ( - ( dot2 * pow ( x2, 2.0 ) * y2 * pow ( z1, 3.0 ) ) /
2103 ( ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) -
2104 ( dot2 * pow ( x2, 2.0 ) * pow ( z1, 2.0 ) ) /
2105 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) +
2106 ( dot1 * pow ( x2, 2.0 ) * y2 * z2 * pow ( z1, 2.0 ) ) /
2107 ( ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) +
2108 ( 2.0 * x1 * dot2 * x2 * y2 * z2 * pow ( z1, 2.0 ) ) /
2109 ( ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) +
2110 ( x2 * y2 * sqrt ( pow ( -2.0 * dot2 * x2 * pow ( y1, 2.0 ) + 2.0 * x1 * dot2 * y2 * y1 + 2.0 * dot1 * x2 * y2 * y1 - 2.0 * x1 * dot1 * pow ( y2, 2.0 ) - 2.0 * x1 * dot1 * pow ( z2, 2.0 ) - 2.0 * pow ( z1, 2.0 ) * dot2 * x2 + 2.0 * x1 * z1 * dot2 * z2 + 2.0 * z1 * dot1 * x2 * z2, 2.0 ) -
2111 4.0 * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) *
2112 ( pow ( y1, 2.0 ) * pow ( dot2, 2.0 ) + pow ( z1, 2.0 ) * pow ( dot2, 2.0 ) - 2.0 * y1 * dot1 * y2 * dot2 - 2.0 * z1 * dot1 * z2 * dot2 - pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( dot1, 2.0 ) * pow ( y2, 2.0 ) - pow ( y1, 2.0 ) * pow ( z2, 2.0 ) + pow ( dot1, 2.0 ) * pow ( z2, 2.0 ) + 2.0 * y1 * z1 * y2 * z2 ) ) * z1 ) /
2113 ( 2.0 * ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) +
2114 ( dot2 * y2 * z1 ) / ( y1 * z2 - z1 * y2 ) +
2115 ( dot1 * pow ( x2, 2.0 ) * z2 * z1 ) /
2116 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) +
2117 ( x1 * dot2 * x2 * z2 * z1 ) /
2118 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) -
2119 ( x1 * dot1 * x2 * pow ( y2, 3.0 ) * z1 ) /
2120 ( ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) +
2121 ( y1 * dot1 * pow ( x2, 2.0 ) * pow ( y2, 2.0 ) * z1 ) /
2122 ( ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) +
2123 ( x1 * y1 * dot2 * x2 * pow ( y2, 2.0 ) * z1 ) /
2124 ( ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) -
2125 ( pow ( x1, 2.0 ) * dot2 * y2 * pow ( z2, 2.0 ) * z1 ) /
2126 ( ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) -
2127 ( 2.0 * x1 * dot1 * x2 * y2 * pow ( z2, 2.0 ) * z1 ) /
2128 ( ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) -
2129 ( pow ( y1, 2.0 ) * dot2 * pow ( x2, 2.0 ) * y2 * z1 ) /
2130 ( ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) + dot2 +
2131 ( x2 * sqrt ( pow ( - 2.0 * dot2 * x2 * pow ( y1, 2.0 ) + 2.0 * x1 * dot2 * y2 * y1 + 2.0 * dot1 * x2 * y2 * y1 - 2.0 * x1 * dot1 * pow ( y2, 2.0 ) - 2.0 * x1 * dot1 * pow ( z2, 2.0 ) - 2.0 * pow ( z1, 2.0 ) * dot2 * x2 + 2.0 * x1 * z1 * dot2 * z2 + 2.0 * z1 * dot1 * x2 * z2, 2.0 ) -
2132 4.0 * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) *
2133 ( pow ( y1, 2.0 ) * pow ( dot2, 2.0 ) + pow ( z1, 2.0 ) * pow ( dot2, 2.0 ) - 2.0 * y1 * dot1 * y2 * dot2 - 2.0 * z1 * dot1 * z2 * dot2 - pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( dot1, 2.0 ) * pow ( y2, 2.0 ) - pow ( y1, 2.0 ) * pow ( z2, 2.0 ) + pow ( dot1, 2.0 ) * pow ( z2, 2.0 ) + 2.0 * y1 * z1 * y2 * z2 ) ) ) /
2134 ( 2.0 * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) -
2135 ( x1 * y2 * z2 * sqrt ( pow ( - 2.0 * dot2 * x2 * pow ( y1, 2.0 ) + 2.0 * x1 * dot2 * y2 * y1 + 2.0 * dot1 * x2 * y2 * y1 - 2.0 * x1 * dot1 * pow ( y2, 2.0 ) - 2.0 * x1 * dot1 * pow ( z2, 2.0 ) - 2.0 * pow ( z1, 2.0 ) * dot2 * x2 + 2.0 * x1 * z1 * dot2 * z2 + 2.0 * z1 * dot1 * x2 * z2, 2.0 ) -
2136 4.0 * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) *
2137 ( pow ( y1, 2.0 ) * pow ( dot2, 2.0 ) + pow ( z1, 2.0 ) * pow ( dot2, 2.0 ) - 2.0 * y1 * dot1 * y2 * dot2 - 2.0 * z1 * dot1 * z2 * dot2 - pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( dot1, 2.0 ) * pow ( y2, 2.0 ) - pow ( y1, 2.0 ) * pow ( z2, 2.0 ) + pow ( dot1, 2.0 ) * pow ( z2, 2.0 ) + 2.0 * y1 * z1 * y2 * z2 ) ) ) /
2138 ( 2.0 * ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) -
2139 ( dot1 * y2 * z2 ) / ( y1 * z2 - z1 * y2 ) -
2140 ( pow ( y1, 2.0 ) * dot2 * pow ( x2, 2.0 ) ) /
2141 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) -
2142 ( x1 * dot1 * x2 * pow ( y2, 2.0 ) ) /
2143 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) -
2144 ( x1 * dot1 * x2 * pow ( z2, 2.0 ) ) /
2145 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) +
2146 ( y1 * dot1 * pow ( x2, 2.0 ) * y2 ) /
2147 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) +
2148 ( x1 * y1 * dot2 * x2 * y2 ) /
2149 ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) +
2150 ( pow ( x1, 2.0 ) * dot1 * y2 * pow ( z2, 3.0 ) ) /
2151 ( ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) +
2152 ( pow ( x1, 2.0 ) * dot1 * pow ( y2, 3.0 ) * z2 ) /
2153 ( ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) -
2154 ( pow ( x1, 2.0 ) * y1 * dot2 * pow ( y2, 2.0 ) * z2 ) /
2155 ( ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) -
2156 ( x1 * y1 * dot1 * x2 * pow ( y2, 2.0 ) * z2 ) /
2157 ( ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) +
2158 ( x1 * pow ( y1, 2.0 ) * dot2 * x2 * y2 * z2 ) /
2159 ( ( y1 * z2 - z1 * y2 ) * ( pow ( y1, 2.0 ) * pow ( x2, 2.0 ) + pow ( z1, 2.0 ) * pow ( x2, 2.0 ) - 2.0 * x1 * y1 * y2 * x2 - 2.0 * x1 * z1 * z2 * x2 + pow ( x1, 2.0 ) * pow ( y2, 2.0 ) + pow ( z1, 2.0 ) * pow ( y2, 2.0 ) + pow ( x1, 2.0 ) * pow ( z2, 2.0 ) + pow ( y1, 2.0 ) * pow ( z2, 2.0 ) - 2.0 * y1 * z1 * y2 * z2 ) ) ) / z2;
2162 const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( solX ), std::max( std::abs ( solY ), std::abs ( solZ ) ) ) );
2163 const FloatingPoint< proshade_double > rhs1 ( std::abs ( solX ) );
2164 const FloatingPoint< proshade_double > rhs2 ( std::abs ( solY ) );
2165 const FloatingPoint< proshade_double > rhs3 ( std::abs ( solZ ) );
2166 if ( ( ( lhs1.AlmostEquals ( rhs1 ) ) && ( solX < 0.0 ) ) ||
2167 ( ( lhs1.AlmostEquals ( rhs2 ) ) && ( solY < 0.0 ) ) ||
2168 ( ( lhs1.AlmostEquals ( rhs3 ) ) && ( solZ < 0.0 ) ) ) { solX *= -1.0; solY *= -1.0; solZ *= -1.0; }
2201 std::vector < proshade_double >
ProSHADE_internal_maths::findVectorFromThreeVAndThreeD ( proshade_double x1, proshade_double y1, proshade_double z1, proshade_double x2, proshade_double y2, proshade_double z2, proshade_double x3, proshade_double y3, proshade_double z3, proshade_double dot1, proshade_double dot2, proshade_double dot3 )
2204 std::vector < proshade_double > ret;
2207 proshade_double solX = - ( y1 * dot2 * z3 - y1 * dot3 * z2 - z1 * dot2 * y3 + z1 * dot3 * y2 + dot1 * y3 * z2 - dot1 * z3 * y2 ) /
2208 ( -x1 * y3 * z2 + x1 * z3 * y2 + y1 * x3 * z2 - y1 * z3 * x2 - z1 * x3 * y2 + z1 * y3 * x2 );
2209 proshade_double solY = - ( x1 * dot2 * z3 - x1 * dot3 * z2 - z1 * dot2 * x3 + z1 * dot3 * x2 + dot1 * x3 * z2 - dot1 * z3 * x2 ) /
2210 ( x1 * y3 * z2 - x1 * z3 * y2 - y1 * x3 * z2 + y1 * z3 * x2 + z1 * x3 * y2 - z1 * y3 * x2 );
2211 proshade_double solZ = - ( x1 * dot2 * y3 - x1 * dot3 * y2 - y1 * dot2 * x3 + y1 * dot3 * x2 + dot1 * x3 * y2 - dot1 * y3 * x2 ) /
2212 ( -x1 * y3 * z2 + x1 * z3 * y2 + y1 * x3 * z2 - y1 * z3 * x2 - z1 * x3 * y2 + z1 * y3 * x2 );
2215 proshade_double normFactor = sqrt ( pow ( solX, 2.0 ) + pow ( solY, 2.0 ) + pow ( solZ, 2.0 ) );
2221 const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( solX ), std::max( std::abs ( solY ), std::abs ( solZ ) ) ) );
2222 const FloatingPoint< proshade_double > rhs1 ( std::abs ( solX ) );
2223 const FloatingPoint< proshade_double > rhs2 ( std::abs ( solY ) );
2224 const FloatingPoint< proshade_double > rhs3 ( std::abs ( solZ ) );
2225 if ( ( ( lhs1.AlmostEquals ( rhs1 ) ) && ( solX < 0.0 ) ) ||
2226 ( ( lhs1.AlmostEquals ( rhs2 ) ) && ( solY < 0.0 ) ) ||
2227 ( ( lhs1.AlmostEquals ( rhs3 ) ) && ( solZ < 0.0 ) ) ) { solX *= -1.0; solY *= -1.0; solZ *= -1.0; }
2248 std::vector< proshade_double > ret;
2252 ( el1->at(1) * el2->at(3) ) +
2253 ( el1->at(2) * el2->at(6) ) );
2255 ( el1->at(1) * el2->at(4) ) +
2256 ( el1->at(2) * el2->at(7) ) );
2258 ( el1->at(1) * el2->at(5) ) +
2259 ( el1->at(2) * el2->at(8) ) );
2262 ( el1->at(4) * el2->at(3) ) +
2263 ( el1->at(5) * el2->at(6) ) );
2265 ( el1->at(4) * el2->at(4) ) +
2266 ( el1->at(5) * el2->at(7) ) );
2268 ( el1->at(4) * el2->at(5) ) +
2269 ( el1->at(5) * el2->at(8) ) );
2272 ( el1->at(7) * el2->at(3) ) +
2273 ( el1->at(8) * el2->at(6) ) );
2275 ( el1->at(7) * el2->at(4) ) +
2276 ( el1->at(8) * el2->at(7) ) );
2278 ( el1->at(7) * el2->at(5) ) +
2279 ( el1->at(8) * el2->at(8) ) );
2305 proshade_double trace = ( mat1->at(0) * mat2->at(0) ) + ( mat1->at(1) * mat2->at(1) ) + ( mat1->at(2) * mat2->at(2) );
2306 trace += ( mat1->at(3) * mat2->at(3) ) + ( mat1->at(4) * mat2->at(4) ) + ( mat1->at(5) * mat2->at(5) );
2307 trace += ( mat1->at(6) * mat2->at(6) ) + ( mat1->at(7) * mat2->at(7) ) + ( mat1->at(8) * mat2->at(8) );
2313 if ( tolerance > std::abs ( trace ) ) { ret =
true; }
2342 proshade_double cosDist = ( ( a1 * b1 ) + ( a2 * b2 ) + ( a3 * b3 ) ) /
2343 ( sqrt( pow( a1, 2.0 ) + pow( a2, 2.0 ) + pow( a3, 2.0 ) ) *
2344 sqrt( pow( b1, 2.0 ) + pow( b2, 2.0 ) + pow( b3, 2.0 ) ) );
2347 if ( std::abs( cosDist ) > ( 1.0 - tolerance ) ) { ret =
true; }
2376 proshade_double cosDist = ( ( a1 * b1 ) + ( a2 * b2 ) + ( a3 * b3 ) ) /
2377 ( sqrt( pow( a1, 2.0 ) + pow( a2, 2.0 ) + pow( a3, 2.0 ) ) *
2378 sqrt( pow( b1, 2.0 ) + pow( b2, 2.0 ) + pow( b3, 2.0 ) ) );
2381 if ( cosDist > ( 1.0 - tolerance ) ) { ret =
true; }
2400 void ProSHADE_internal_maths::optimiseAxisBiCubicInterpolation ( proshade_double* bestLattitude, proshade_double* bestLongitude, proshade_double* bestSum, std::vector<proshade_unsign>* sphereList, std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*>* sphereMappedRotFun, proshade_double step )
2403 proshade_double lonM, lonP, latM, latP, movSum;
2404 std::vector<proshade_double> latVals ( 3 );
2405 std::vector<proshade_double> lonVals ( 3 );
2406 proshade_double learningRate = 0.1;
2407 proshade_double prevVal = *bestSum;
2408 proshade_double valChange = 999.9;
2409 proshade_double origBestLat = std::round ( *bestLattitude );
2410 proshade_double origBestLon = std::round ( *bestLongitude );
2411 proshade_double tmpVal;
2414 std::vector<ProSHADE_internal_maths::BicubicInterpolator*> interpolsMinusMinus;
2415 std::vector<ProSHADE_internal_maths::BicubicInterpolator*> interpolsMinusPlus;
2416 std::vector<ProSHADE_internal_maths::BicubicInterpolator*> interpolsPlusMinus;
2417 std::vector<ProSHADE_internal_maths::BicubicInterpolator*> interpolsPlusPlus;
2424 while ( valChange > 0.0001 )
2427 lonM = *bestLongitude - step;
2428 lonP = *bestLongitude + step;
2429 latM = *bestLattitude - step;
2430 latP = *bestLattitude + step;
2433 const FloatingPoint< proshade_double > lhs1 ( *bestLattitude ), rhs1 ( origBestLat - 1.0 );
2434 const FloatingPoint< proshade_double > lhs2 ( *bestLattitude ), rhs2 ( origBestLat + 1.0 );
2435 const FloatingPoint< proshade_double > lhs3 ( *bestLongitude ), rhs3 ( origBestLon - 1.0 );
2436 const FloatingPoint< proshade_double > lhs4 ( *bestLongitude ), rhs4 ( origBestLon + 1.0 );
2437 if ( latM < ( origBestLat - 1.0 ) ) { tmpVal = *bestLattitude; *bestLattitude = origBestLat - 1.0;
optimiseAxisBiCubicInterpolation ( bestLattitude, bestLongitude, bestSum, sphereList, sphereMappedRotFun, step );
if ( lhs1.AlmostEquals ( rhs1 ) ) { *bestLattitude = tmpVal; }
break; }
2438 if ( latP > ( origBestLat + 1.0 ) ) { tmpVal = *bestLattitude; *bestLattitude = origBestLat + 1.0;
optimiseAxisBiCubicInterpolation ( bestLattitude, bestLongitude, bestSum, sphereList, sphereMappedRotFun, step );
if ( lhs2.AlmostEquals ( rhs2 ) ) { *bestLattitude = tmpVal; }
break; }
2439 if ( lonM < ( origBestLon - 1.0 ) ) { tmpVal = *bestLongitude; *bestLongitude = origBestLon - 1.0;
optimiseAxisBiCubicInterpolation ( bestLattitude, bestLongitude, bestSum, sphereList, sphereMappedRotFun, step );
if ( lhs3.AlmostEquals ( rhs3 ) ) { *bestLongitude = tmpVal; }
break; }
2440 if ( lonP > ( origBestLon + 1.0 ) ) { tmpVal = *bestLongitude; *bestLongitude = origBestLon + 1.0;
optimiseAxisBiCubicInterpolation ( bestLattitude, bestLongitude, bestSum, sphereList, sphereMappedRotFun, step );
if ( lhs4.AlmostEquals ( rhs4 ) ) { *bestLongitude = tmpVal; }
break; }
2443 latVals.at(0) = latM; latVals.at(1) = *bestLattitude; latVals.at(2) = latP;
2444 lonVals.at(0) = lonM; lonVals.at(1) = *bestLongitude; lonVals.at(2) = lonP;
2447 for ( proshade_unsign laIt = 0; laIt < static_cast<proshade_unsign> ( latVals.size() ); laIt++ )
2449 for ( proshade_unsign loIt = 0; loIt < static_cast<proshade_unsign> ( lonVals.size() ); loIt++ )
2453 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( sphereList->size() ); iter++ )
2456 if ( ( latVals.at(laIt) <= origBestLat ) && ( lonVals.at(loIt) <= origBestLon ) ) { movSum += interpolsMinusMinus.at(iter)->getValue ( latVals.at(laIt), lonVals.at(loIt) ); }
2457 if ( ( latVals.at(laIt) <= origBestLat ) && ( lonVals.at(loIt) > origBestLon ) ) { movSum += interpolsMinusPlus.at(iter)->getValue ( latVals.at(laIt), lonVals.at(loIt) ); }
2458 if ( ( latVals.at(laIt) > origBestLat ) && ( lonVals.at(loIt) <= origBestLon ) ) { movSum += interpolsPlusMinus.at(iter)->getValue ( latVals.at(laIt), lonVals.at(loIt) ); }
2459 if ( ( latVals.at(laIt) > origBestLat ) && ( lonVals.at(loIt) > origBestLon ) ) { movSum += interpolsPlusPlus.at(iter)->getValue ( latVals.at(laIt), lonVals.at(loIt) ); }
2463 if ( *bestSum < movSum )
2466 *bestLongitude = lonVals.at(loIt);
2467 *bestLattitude = latVals.at(laIt);
2473 valChange = std::floor ( 100000.0 * ( *bestSum - prevVal ) ) / 100000.0;
2474 prevVal = std::floor ( 100000.0 * ( *bestSum ) ) / 100000.0;
2475 step = std::max ( ( valChange / step ) * learningRate, 0.01 );
2476 if ( learningRate >= 0.02 ) { learningRate -= 0.01; }
2481 for ( proshade_unsign intIt = 0; intIt < static_cast<proshade_unsign> ( interpolsMinusMinus.size() ); intIt++ ) {
delete interpolsMinusMinus.at(intIt); }
2482 for ( proshade_unsign intIt = 0; intIt < static_cast<proshade_unsign> ( interpolsMinusPlus.size() ); intIt++ ) {
delete interpolsMinusPlus.at(intIt); }
2483 for ( proshade_unsign intIt = 0; intIt < static_cast<proshade_unsign> ( interpolsPlusMinus.size() ); intIt++ ) {
delete interpolsPlusMinus.at(intIt); }
2484 for ( proshade_unsign intIt = 0; intIt < static_cast<proshade_unsign> ( interpolsPlusPlus.size() ); intIt++ ) {
delete interpolsPlusPlus.at(intIt); }
2501 void ProSHADE_internal_maths::prepareBiCubicInterpolatorsMinusMinus ( proshade_double bestLattitude, proshade_double bestLongitude, std::vector<proshade_unsign>* sphereList, std::vector<ProSHADE_internal_maths::BicubicInterpolator*>* interpols, std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*>* sphereMappedRotFun )
2504 proshade_signed latHlp, lonHlp;
2505 proshade_signed angDim =
static_cast< proshade_signed
> ( sphereMappedRotFun->at(0)->getAngularDim() );
2508 for ( proshade_unsign sphereIt = 0; sphereIt < static_cast<proshade_unsign> ( sphereList->size() ); sphereIt++ )
2511 proshade_double** interpGrid =
new proshade_double*[4];
2515 for ( proshade_unsign iter = 0; iter < 4; iter++ )
2517 interpGrid[iter] =
new proshade_double[4];
2522 for ( proshade_signed latIt = 0; latIt < 4; latIt++ )
2524 for ( proshade_signed lonIt = 0; lonIt < 4; lonIt++ )
2526 latHlp =
static_cast< proshade_signed
> ( bestLattitude - 2.0 +
static_cast< proshade_double
> ( latIt ) );
if ( latHlp < 0 ) { latHlp += angDim; }
if ( latHlp >= angDim ) { latHlp -= angDim; }
2527 lonHlp =
static_cast< proshade_signed
> ( bestLongitude - 2.0 +
static_cast< proshade_double
> ( lonIt ) );
if ( lonHlp < 0 ) { lonHlp += angDim; }
if ( lonHlp >= angDim ) { lonHlp -= angDim; }
2528 interpGrid[latIt][lonIt] = sphereMappedRotFun->at(sphereList->at(sphereIt))->getSphereLatLonPosition (
static_cast< proshade_unsign
> ( latHlp ),
static_cast< proshade_unsign
> ( lonHlp ) );
2534 interpols->emplace_back ( biCubInterp );
2537 for ( proshade_unsign iter = 0; iter < 4; iter++ ) {
delete[] interpGrid[iter]; }
2538 delete[] interpGrid;
2556 void ProSHADE_internal_maths::prepareBiCubicInterpolatorsMinusPlus ( proshade_double bestLattitude, proshade_double bestLongitude, std::vector<proshade_unsign>* sphereList, std::vector<ProSHADE_internal_maths::BicubicInterpolator*>* interpols, std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*>* sphereMappedRotFun )
2559 proshade_signed latHlp, lonHlp;
2560 proshade_signed angDim =
static_cast< proshade_signed
> ( sphereMappedRotFun->at(0)->getAngularDim() );
2563 for ( proshade_unsign sphereIt = 0; sphereIt < static_cast<proshade_unsign> ( sphereList->size() ); sphereIt++ )
2566 proshade_double** interpGrid =
new proshade_double*[4];
2570 for ( proshade_unsign iter = 0; iter < 4; iter++ )
2572 interpGrid[iter] =
new proshade_double[4];
2577 for ( proshade_unsign latIt = 0; latIt < 4; latIt++ )
2579 for ( proshade_unsign lonIt = 0; lonIt < 4; lonIt++ )
2581 latHlp =
static_cast< proshade_signed
> ( bestLattitude - 2 +
static_cast< proshade_double
> ( latIt ) );
if ( latHlp < 0 ) { latHlp += angDim; }
if ( latHlp >= angDim ) { latHlp -= angDim; }
2582 lonHlp =
static_cast< proshade_signed
> ( bestLongitude - 1 +
static_cast< proshade_double
> ( lonIt ) );
if ( lonHlp < 0 ) { lonHlp += angDim; }
if ( lonHlp >= angDim ) { lonHlp -= angDim; }
2583 interpGrid[latIt][lonIt] = sphereMappedRotFun->at(sphereList->at(sphereIt))->getSphereLatLonPosition (
static_cast< proshade_unsign
> ( latHlp ) ,
static_cast< proshade_unsign
> ( lonHlp ) );
2589 interpols->emplace_back ( biCubInterp );
2592 for ( proshade_unsign iter = 0; iter < 4; iter++ ) {
delete[] interpGrid[iter]; }
2593 delete[] interpGrid;
2611 void ProSHADE_internal_maths::prepareBiCubicInterpolatorsPlusMinus ( proshade_double bestLattitude, proshade_double bestLongitude, std::vector<proshade_unsign>* sphereList, std::vector<ProSHADE_internal_maths::BicubicInterpolator*>* interpols, std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*>* sphereMappedRotFun )
2614 proshade_signed latHlp, lonHlp;
2615 proshade_signed angDim =
static_cast< proshade_signed
> ( sphereMappedRotFun->at(0)->getAngularDim() );
2618 for ( proshade_unsign sphereIt = 0; sphereIt < static_cast<proshade_unsign> ( sphereList->size() ); sphereIt++ )
2621 proshade_double** interpGrid =
new proshade_double*[4];
2625 for ( proshade_unsign iter = 0; iter < 4; iter++ )
2627 interpGrid[iter] =
new proshade_double[4];
2632 for ( proshade_unsign latIt = 0; latIt < 4; latIt++ )
2634 for ( proshade_unsign lonIt = 0; lonIt < 4; lonIt++ )
2636 latHlp =
static_cast< proshade_signed
> ( bestLattitude - 1 +
static_cast< proshade_double
> ( latIt ) );
if ( latHlp < 0 ) { latHlp += angDim; }
if ( latHlp >= angDim ) { latHlp -= angDim; }
2637 lonHlp =
static_cast< proshade_signed
> ( bestLongitude - 2 +
static_cast< proshade_double
> ( lonIt ) );
if ( lonHlp < 0 ) { lonHlp += angDim; }
if ( lonHlp >= angDim ) { lonHlp -= angDim; }
2638 interpGrid[latIt][lonIt] = sphereMappedRotFun->at(sphereList->at(sphereIt))->getSphereLatLonPosition (
static_cast< proshade_unsign
> ( latHlp ),
static_cast< proshade_unsign
> ( lonHlp ) );
2644 interpols->emplace_back ( biCubInterp );
2647 for ( proshade_unsign iter = 0; iter < 4; iter++ ) {
delete[] interpGrid[iter]; }
2648 delete[] interpGrid;
2666 void ProSHADE_internal_maths::prepareBiCubicInterpolatorsPlusPlus ( proshade_double bestLattitude, proshade_double bestLongitude, std::vector<proshade_unsign>* sphereList, std::vector<ProSHADE_internal_maths::BicubicInterpolator*>* interpols, std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*>* sphereMappedRotFun )
2669 proshade_signed latHlp, lonHlp;
2670 proshade_signed angDim =
static_cast< proshade_signed
> ( sphereMappedRotFun->at(0)->getAngularDim() );
2673 for ( proshade_unsign sphereIt = 0; sphereIt < static_cast<proshade_unsign> ( sphereList->size() ); sphereIt++ )
2676 proshade_double** interpGrid =
new proshade_double*[4];
2680 for ( proshade_unsign iter = 0; iter < 4; iter++ )
2682 interpGrid[iter] =
new proshade_double[4];
2687 for ( proshade_unsign latIt = 0; latIt < 4; latIt++ )
2689 for ( proshade_unsign lonIt = 0; lonIt < 4; lonIt++ )
2691 latHlp =
static_cast< proshade_signed
> ( bestLattitude - 1 +
static_cast< proshade_double
> ( latIt ) );
if ( latHlp < 0 ) { latHlp += angDim; }
if ( latHlp >= angDim ) { latHlp -= angDim; }
2692 lonHlp =
static_cast< proshade_signed
> ( bestLongitude - 1 +
static_cast< proshade_double
> ( lonIt ) );
if ( lonHlp < 0 ) { lonHlp += angDim; }
if ( lonHlp >= angDim ) { lonHlp -= angDim; }
2693 interpGrid[latIt][lonIt] = sphereMappedRotFun->at(sphereList->at(sphereIt))->getSphereLatLonPosition (
static_cast< proshade_unsign
> ( latHlp ),
static_cast< proshade_unsign
> ( lonHlp ) );
2699 interpols->emplace_back ( biCubInterp );
2702 for ( proshade_unsign iter = 0; iter < 4; iter++ ) {
delete[] interpGrid[iter]; }
2703 delete[] interpGrid;
2725 proshade_unsign whichImprove = 0;
2728 for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( CSymList->size() ); grIt++ )
2731 const FloatingPoint< proshade_double > lhs ( CSymList->at(grIt)[0] ), rhs ( axis[0] );
2732 if ( lhs.AlmostEquals ( rhs ) )
2737 whichImprove = grIt;
2744 if ( improve && !ret )
2746 CSymList->at(whichImprove)[1] = axis[1];
2747 CSymList->at(whichImprove)[2] = axis[2];
2748 CSymList->at(whichImprove)[3] = axis[3];
2749 CSymList->at(whichImprove)[4] = axis[4];
2750 CSymList->at(whichImprove)[5] = axis[5];
2776 for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( CSymList->size() ); grIt++ )
2778 const FloatingPoint< proshade_double > lhs ( fold ), rhs ( CSymList->at(grIt)[0] );
2779 if ( lhs.AlmostEquals ( rhs ) )
2805 std::vector< proshade_unsign > ret;
2806 std::vector< std::pair< proshade_unsign, bool > > sieveOfEratosthenesArray;
2809 if ( upTo < 2 ) {
return ( ret ); }
2812 for ( proshade_unsign iter = 2; iter <= upTo; iter++ ) { sieveOfEratosthenesArray.emplace_back ( std::pair< proshade_unsign, bool > ( iter,
true ) ); }
2815 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( sieveOfEratosthenesArray.size() ); iter++ )
2818 if ( sieveOfEratosthenesArray.at(iter).second )
2821 for ( proshade_unsign it = iter + sieveOfEratosthenesArray.at(iter).first; it < static_cast<proshade_unsign> ( sieveOfEratosthenesArray.size() ); it += sieveOfEratosthenesArray.at(iter).first )
2823 sieveOfEratosthenesArray.at(it).second =
false;
2829 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( sieveOfEratosthenesArray.size() ); iter++ )
2850 proshade_double zScore = ( val / sigma );
2851 proshade_double cumulativeProbability = 0.5 * std::erfc ( zScore * M_SQRT1_2 );
2854 if ( cumulativeProbability > 0.5 ) { cumulativeProbability = 1.0 - cumulativeProbability; }
2857 return ( cumulativeProbability );
2876 proshade_signed windowHalf = ( windowSize - 1 ) / 2;
2877 proshade_signed totSize =
static_cast< proshade_signed
> ( ( 1.0 / step ) + 1 );
2878 std::vector< proshade_double > smoothened (
static_cast< size_t > ( totSize - ( windowSize - 1 ) ), 0.0 );
2879 std::vector< proshade_double > winWeights (
static_cast< size_t > ( windowSize ), 0.0 );
2882 for ( proshade_double winIt = 0.0; winIt < static_cast< proshade_double > ( windowSize ); winIt += 1.0 ) { winWeights.at(
static_cast< proshade_unsign
> ( winIt ) ) =
ProSHADE_internal_maths::computeGaussian ( ( winIt -
static_cast< proshade_double
> ( windowHalf ) ) * step, sigma ); }
2885 for ( proshade_unsign it = 0; it < static_cast< proshade_unsign > ( smoothened.size() ); it++ )
2888 for ( proshade_signed winIt = 0; winIt < windowSize; winIt++ )
2890 smoothened.at(it) += winWeights.at(
static_cast< size_t > ( winIt ) ) * data.at(
static_cast< size_t > (
static_cast< proshade_signed
> ( it ) + winIt ) );
2895 return ( smoothened );
2912 proshade_single vol = ( xDim * yDim * zDim );
2913 proshade_single sa = ( yDim * zDim ) / vol;
2914 proshade_single sb = ( xDim * zDim ) / vol;
2915 proshade_single sc = ( xDim * yDim ) / vol;
2918 proshade_single s2 = ( std::pow ( h * sa, 2.0f ) +
2919 std::pow ( k * sb, 2.0f ) +
2920 std::pow ( l * sc, 2.0f ) ) / 4.0f;
2923 if ( s2 == 0.0f ) { s2 = 0.0000000001f; }
2926 return ( 1.0f / ( 2.0f * std::sqrt ( s2 ) ) );
2946 binIndexing =
new proshade_signed [xInds * yInds * zInds];
2948 for (
size_t iter = 0; iter < static_cast< size_t > ( xInds * yInds * zInds ); iter++ ) { binIndexing[iter] = -100; }
2949 proshade_single xIndsF =
static_cast< proshade_single
> ( xInds ), yIndsF =
static_cast< proshade_single
> ( yInds ), zIndsF =
static_cast< proshade_single
> ( zInds );
2952 proshade_single *mins =
new proshade_single[3];
2953 proshade_single *maxs =
new proshade_single[3];
2954 proshade_single *resMins =
new proshade_single[3];
2955 proshade_signed *resMinLoc =
new proshade_signed[3];
2956 proshade_single *steps =
new proshade_single[3];
2966 proshade_single resol = 0.0f;
2967 proshade_signed reciX, reciY, reciZ, arrPos = 0, minLoc = -1;
2971 mins[0] = std::floor ( xIndsF / -2.0f );
2972 mins[1] = std::floor ( yIndsF / -2.0f );
2973 mins[2] = std::floor ( zIndsF / -2.0f );
2979 if ( xInds % 2 == 0 ) { mins[0] += 1.0f; }
2980 if ( yInds % 2 == 0 ) { mins[1] += 1.0f; }
2981 if ( zInds % 2 == 0 ) { mins[2] += 1.0f; }
2989 resMinLoc[0] = 0; resMinLoc[1] = 0; resMinLoc[2] = 0;
2990 const FloatingPoint< proshade_single > lhs1 ( resMins[0] ), lhs2 ( resMins[1] ), lhs3 ( resMins[2] ), rhs1 ( std::min( resMins[0], std::min( resMins[1], resMins[2] ) ) );
2991 if ( lhs1.AlmostEquals ( rhs1 ) ) { resMinLoc[0] = 1; minLoc = 0; }
2992 if ( lhs2.AlmostEquals ( rhs1 ) ) { resMinLoc[1] = 1; minLoc = 1; }
2993 if ( lhs3.AlmostEquals ( rhs1 ) ) { resMinLoc[2] = 1; minLoc = 2; }
2996 std::vector< proshade_single > resArray (
static_cast< size_t > ( maxs[minLoc] - 1 ), 0.0f );
2997 std::vector< proshade_single > binArray (
static_cast< size_t > ( maxs[minLoc] - 1 ), 0.0f );
2998 for ( proshade_signed dimIt = 0; dimIt < static_cast< proshade_signed > ( maxs[minLoc] - 1 ); dimIt++ )
3001 steps[0] = (
static_cast< proshade_single
> ( dimIt ) + 2.5f ) *
static_cast< proshade_single
> ( resMinLoc[0] );
3002 steps[1] = (
static_cast< proshade_single
> ( dimIt ) + 2.5f ) *
static_cast< proshade_single
> ( resMinLoc[1] );
3003 steps[2] = (
static_cast< proshade_single
> ( dimIt ) + 2.5f ) *
static_cast< proshade_single
> ( resMinLoc[2] );
3009 resArray.at(
static_cast< size_t > ( dimIt ) ) = resol;
3010 binArray.at(
static_cast< size_t > ( dimIt ) ) =
static_cast< proshade_single
> ( dimIt ) + 2.5f;
3015 for ( proshade_signed xIt = 0; xIt < static_cast< proshade_signed > ( xInds ); xIt++ )
3017 for ( proshade_signed yIt = 0; yIt < static_cast< proshade_signed > ( yInds ); yIt++ )
3019 for ( proshade_signed zIt = 0; zIt < static_cast< proshade_signed > ( zInds / 2 ) + 1; zIt++ )
3022 reciX = xIt;
if ( reciX >
static_cast< proshade_signed
> ( maxs[0] ) ) { reciX -=
static_cast< proshade_signed
> ( xInds ); }
3023 reciY = yIt;
if ( reciY >
static_cast< proshade_signed
> ( maxs[1] ) ) { reciY -=
static_cast< proshade_signed
> ( yInds ); }
3024 reciZ = zIt;
if ( reciZ >
static_cast< proshade_signed
> ( maxs[2] ) ) { reciZ -=
static_cast< proshade_signed
> ( zInds ); }
3027 for ( proshade_signed binIt = 0; binIt < (*noBin); binIt++ )
3030 if ( std::sqrt ( std::pow (
static_cast< proshade_single
> ( reciX ), 2.0f ) +
3031 std::pow (
static_cast< proshade_single
> ( reciY ), 2.0f ) +
3032 std::pow (
static_cast< proshade_single
> ( reciZ ), 2.0f ) ) <= binArray.at(
static_cast< size_t > ( binIt ) ) )
3035 arrPos = zIt +
static_cast< proshade_signed
> ( zInds ) * ( yIt +
static_cast< proshade_signed
> ( yInds ) * xIt );
3036 binIndexing[
static_cast< size_t > ( arrPos ) ] = binIt;
3039 if ( reciX ==
static_cast< proshade_signed
> ( mins[0] ) || -reciX ==
static_cast< proshade_signed
> ( mins[0] ) ) {
break; }
3040 if ( reciY ==
static_cast< proshade_signed
> ( mins[1] ) || -reciY ==
static_cast< proshade_signed
> ( mins[1] ) ) {
break; }
3041 if ( reciZ ==
static_cast< proshade_signed
> ( mins[2] ) || -reciZ ==
static_cast< proshade_signed
> ( mins[2] ) ) {
break; }
3044 reciX *= -1;
if ( reciX < 0 ) { reciX +=
static_cast< proshade_signed
> ( xInds ); }
3045 reciY *= -1;
if ( reciY < 0 ) { reciY +=
static_cast< proshade_signed
> ( yInds ); }
3046 reciZ *= -1;
if ( reciZ < 0 ) { reciZ +=
static_cast< proshade_signed
> ( zInds ); }
3049 arrPos = reciZ +
static_cast< proshade_signed
> ( zInds ) * ( reciY +
static_cast< proshade_signed
> ( yInds ) * reciX );
3050 binIndexing[
static_cast< size_t > ( arrPos ) ] = binIt;
3090 proshade_double
ProSHADE_internal_maths::computeFSC ( fftw_complex *fCoeffs1, fftw_complex *fCoeffs2, proshade_unsign xInds, proshade_unsign yInds, proshade_unsign zInds, proshade_signed noBins, proshade_signed* binIndexing, proshade_double**& binData, proshade_signed*& binCounts )
3093 proshade_double realOrig, realRot, imagOrig, imagRot, fsc = 0.0;;
3094 proshade_signed indx, arrPos;
3095 std::vector< proshade_double > covarByBin (
static_cast< size_t > ( noBins ), 0.0 );
3096 std::vector< proshade_double > fscByBin (
static_cast< size_t > ( noBins ), 0.0 );
3099 for ( proshade_signed xIt = 0; xIt < static_cast< proshade_signed > ( xInds ); xIt++ )
3101 for ( proshade_signed yIt = 0; yIt < static_cast< proshade_signed > ( yInds ); yIt++ )
3103 for ( proshade_signed zIt = 0; zIt < static_cast< proshade_signed > ( zInds ); zIt++ )
3106 arrPos = zIt +
static_cast< proshade_signed
> ( zInds ) * ( yIt +
static_cast< proshade_signed
> ( yInds ) * xIt );
3109 indx = binIndexing[
static_cast< size_t > ( arrPos ) ];
3110 if ( ( indx < 0 ) || ( indx > noBins ) ) {
continue; }
3113 realOrig = fCoeffs1[arrPos][0];
3114 imagOrig = fCoeffs1[arrPos][1];
3115 realRot = fCoeffs2[arrPos][0];
3116 imagRot = fCoeffs2[arrPos][1];
3118 binData[indx][0] += realOrig;
3119 binData[indx][1] += imagOrig;
3120 binData[indx][2] += realRot;
3121 binData[indx][3] += imagRot;
3122 binData[indx][4] += realOrig * realRot;
3123 binData[indx][5] += imagOrig * imagRot;
3124 binData[indx][6] += std::pow ( realOrig, 2.0 );
3125 binData[indx][7] += std::pow ( imagOrig, 2.0 );
3126 binData[indx][8] += std::pow ( realRot, 2.0 );
3127 binData[indx][9] += std::pow ( imagRot, 2.0 );
3130 binCounts[indx] += 1;
3136 for (
size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ )
3138 covarByBin.at(binIt) = ( ( binData[binIt][4] + binData[binIt][5] ) /
static_cast< proshade_double
> ( binCounts[binIt] ) -
3139 ( ( binData[binIt][0] /
static_cast< proshade_double
> ( binCounts[binIt] ) *
3140 binData[binIt][2] /
static_cast< proshade_double
> ( binCounts[binIt] ) ) +
3141 ( binData[binIt][1] /
static_cast< proshade_double
> ( binCounts[binIt] ) *
3142 binData[binIt][3] /
static_cast< proshade_double
> ( binCounts[binIt] ) ) ) );
3146 for (
size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ )
3148 binData[binIt][10] = ( binData[binIt][6] + binData[binIt][7] ) /
static_cast< proshade_double
> ( binCounts[binIt] ) -
3149 ( std::pow ( binData[binIt][0] /
static_cast< proshade_double
> ( binCounts[binIt] ), 2.0 ) +
3150 std::pow ( binData[binIt][1] /
static_cast< proshade_double
> ( binCounts[binIt] ), 2.0 ) );
3151 binData[binIt][11] = ( binData[binIt][8] + binData[binIt][9] ) /
static_cast< proshade_double
> ( binCounts[binIt] ) -
3152 ( std::pow ( binData[binIt][2] /
static_cast< proshade_double
> ( binCounts[binIt] ), 2.0 ) +
3153 std::pow ( binData[binIt][3] /
static_cast< proshade_double
> ( binCounts[binIt] ), 2.0 ) );
3154 fscByBin.at(binIt) = covarByBin.at(binIt) / ( std::sqrt ( binData[binIt][10] ) * std::sqrt ( binData[binIt][11] ) );
3158 proshade_double binSizeSum = 0.0;
3159 for (
size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ )
3161 fsc += fscByBin.at(binIt) *
static_cast< proshade_double
> ( binCounts[binIt] );
3162 binSizeSum +=
static_cast< proshade_double
> ( binCounts[binIt] );
3164 fsc /=
static_cast< proshade_double
> ( binSizeSum );