diff --git a/src/Amalgam/GeneralizedDistance.h b/src/Amalgam/GeneralizedDistance.h index b29e37aa..ae2de42b 100644 --- a/src/Amalgam/GeneralizedDistance.h +++ b/src/Amalgam/GeneralizedDistance.h @@ -258,8 +258,11 @@ class GeneralizedDistanceEvaluator else //!high_accuracy { //multiplying by the reciprocal is lower accuracy due to rounding differences but faster + //cast to float before taking the exponent since it's faster than a double, and because if the + //difference divided by the deviation exceeds the single precision floating point range, + //it will just set the term to zero, which is appropriate double deviation_reciprocal = feature_attribs.deviationReciprocal; - diff += FastExp(-diff * deviation_reciprocal) * (3 * deviation + diff) * 0.5; + diff += std::exp(static_cast(-diff * deviation_reciprocal)) * (3 * deviation + diff) * 0.5; if(!surprisal_transform) return diff; else @@ -269,7 +272,8 @@ class GeneralizedDistanceEvaluator const double term = diff / (2.0 * deviation); //diff / (2*sigma) if(high_accuracy) { - diff += s_two_over_sqrt_pi * deviation * std::exp(-term * term) - diff * std::erfc(term); //2*sigma*(e^(-1*(diff^2)/((2*simga)^2)))/sqrt(pi) - diff*erfc(diff/(2*sigma)) + //2*sigma*(e^(-1*(diff^2)/((2*simga)^2)))/sqrt(pi) - diff*erfc(diff/(2*sigma)) + diff += s_two_over_sqrt_pi * deviation * std::exp(-term * term) - diff * std::erfc(term); if(!surprisal_transform) return diff; else @@ -277,7 +281,12 @@ class GeneralizedDistanceEvaluator } else //!high_accuracy { - diff += s_two_over_sqrt_pi * deviation * FastExp(-term * term) - diff * std::erfc(term); //2*sigma*(e^(-1*(diff^2)/((2*simga)^2)))/sqrt(pi) - diff*erfc(diff/(2*sigma)) + //multiplying by the reciprocal is lower accuracy due to rounding differences but faster + //cast to float before taking the exponent since it's faster than a double, and because if the + //difference divided by the deviation exceeds the single precision floating point range, + //it will just set the term to zero, which is appropriate + //2*sigma*(e^(-1*(diff^2)/((2*simga)^2)))/sqrt(pi) - diff*erfc(diff/(2*sigma)) + diff += s_two_over_sqrt_pi * deviation * std::exp(static_cast(-term * term)) - diff * std::erfc(term); if(!surprisal_transform) return diff; else diff --git a/src/Amalgam/evaluablenode/EvaluableNodeTreeManipulation.h b/src/Amalgam/evaluablenode/EvaluableNodeTreeManipulation.h index f2b21a11..bc35a9b0 100644 --- a/src/Amalgam/evaluablenode/EvaluableNodeTreeManipulation.h +++ b/src/Amalgam/evaluablenode/EvaluableNodeTreeManipulation.h @@ -54,8 +54,11 @@ typedef FastHashMap, MergeMetricResu inline double NumberCommonality(double difference, double a, double b) { double max_abs = std::max(std::fabs(a), std::fabs(b)); - //since this is called frequently in comparing and merging, and perfect accuracy isn't required, just use fast version - double difference_commonality = FastExp(-difference / max_abs); + //since this is called frequently in comparing and merging, and perfect accuracy isn't required, + //cast to float before taking the exponent since it's faster than a double, and because if the + //difference divided by the range exceeds the single precision floating point range, + //it will just set the term to zero, which is appropriate + double difference_commonality = std::exp(static_cast(-difference / max_abs)); return difference_commonality; }