mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[poincare] Move IsApproximatelyEqual to a better helper
Change-Id: I056a96b3721005e01c6ef3f166a80a08195ff338
This commit is contained in:
committed by
Émilie Feral
parent
9f4aafd6b6
commit
3db1cad18b
@@ -6,6 +6,7 @@
|
||||
#include "../regression_context.h"
|
||||
#include "../store.h"
|
||||
#include <poincare/helpers.h>
|
||||
#include <poincare/test/helper.h>
|
||||
|
||||
using namespace Poincare;
|
||||
using namespace Regression;
|
||||
@@ -39,13 +40,13 @@ void assert_regression_is(double * xi, double * yi, int numberOfPoints, Model::T
|
||||
double * coefficients = store.coefficientsForSeries(series, &context);
|
||||
int numberOfCoefs = store.modelForSeries(series)->numberOfCoefficients();
|
||||
for (int i = 0; i < numberOfCoefs; i++) {
|
||||
quiz_assert(Helpers::IsApproximatelyEqual(coefficients[i], trueCoefficients[i], precision, reference));
|
||||
quiz_assert(IsApproximatelyEqual(coefficients[i], trueCoefficients[i], precision, reference));
|
||||
}
|
||||
|
||||
// Compute and check r2 value and sign
|
||||
double r2 = store.determinationCoefficientForSeries(series, &globalContext);
|
||||
quiz_assert(r2 >= 0.0);
|
||||
quiz_assert(Helpers::IsApproximatelyEqual(r2, trueR2, precision, reference));
|
||||
quiz_assert(IsApproximatelyEqual(r2, trueR2, precision, reference));
|
||||
}
|
||||
|
||||
QUIZ_CASE(linear_regression) {
|
||||
@@ -190,15 +191,15 @@ void assert_column_calculations_is(double * xi, int numberOfPoints, double trueM
|
||||
// The least likely value to be null is trueSquaredSum
|
||||
double reference = trueSquaredSum;
|
||||
|
||||
quiz_assert(Helpers::IsApproximatelyEqual(variance, trueVariance, precision, reference));
|
||||
quiz_assert(Helpers::IsApproximatelyEqual(squaredSum, trueSquaredSum, precision, reference));
|
||||
quiz_assert(IsApproximatelyEqual(variance, trueVariance, precision, reference));
|
||||
quiz_assert(IsApproximatelyEqual(squaredSum, trueSquaredSum, precision, reference));
|
||||
|
||||
// adapt the reference
|
||||
reference = std::sqrt(trueSquaredSum);
|
||||
|
||||
quiz_assert(Helpers::IsApproximatelyEqual(mean, trueMean, precision, reference));
|
||||
quiz_assert(Helpers::IsApproximatelyEqual(sum, trueSum, precision, reference));
|
||||
quiz_assert(Helpers::IsApproximatelyEqual(standardDeviation, trueStandardDeviation, precision, reference));
|
||||
quiz_assert(IsApproximatelyEqual(mean, trueMean, precision, reference));
|
||||
quiz_assert(IsApproximatelyEqual(sum, trueSum, precision, reference));
|
||||
quiz_assert(IsApproximatelyEqual(standardDeviation, trueStandardDeviation, precision, reference));
|
||||
}
|
||||
|
||||
QUIZ_CASE(column_calculation) {
|
||||
@@ -236,8 +237,8 @@ void assert_regression_calculations_is(double * xi, double * yi, int numberOfPoi
|
||||
|
||||
// trueProductSum and trueCovariance are using each other as reference
|
||||
// By construction, they often have a close value with a numberOfPoints factor
|
||||
quiz_assert(Helpers::IsApproximatelyEqual(covariance, trueCovariance, precision, trueProductSum / numberOfPoints));
|
||||
quiz_assert(Helpers::IsApproximatelyEqual(productSum, trueProductSum, precision, trueCovariance * numberOfPoints));
|
||||
quiz_assert(IsApproximatelyEqual(covariance, trueCovariance, precision, trueProductSum / numberOfPoints));
|
||||
quiz_assert(IsApproximatelyEqual(productSum, trueProductSum, precision, trueCovariance * numberOfPoints));
|
||||
|
||||
// When trueR = 0, a DBL_EPSILON reference ensures that the only accepted errors are due to double approximations
|
||||
// sqrt is used because the R is computed from sqrt(V1*V0)
|
||||
@@ -245,7 +246,7 @@ void assert_regression_calculations_is(double * xi, double * yi, int numberOfPoi
|
||||
|
||||
double r = store.correlationCoefficient(series);
|
||||
quiz_assert(r >= 0.0);
|
||||
quiz_assert(Helpers::IsApproximatelyEqual(r, trueR, precision, reference));
|
||||
quiz_assert(IsApproximatelyEqual(r, trueR, precision, reference));
|
||||
}
|
||||
|
||||
QUIZ_CASE(regression_calculation) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <cmath>
|
||||
#include "../store.h"
|
||||
#include <poincare/helpers.h>
|
||||
#include <poincare/test/helper.h>
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
@@ -12,7 +13,7 @@ namespace Statistics {
|
||||
void assert_value_approximately_equal_to(double d1, double d2, double precision, double reference) {
|
||||
quiz_assert((std::isnan(d1) && std::isnan(d2))
|
||||
|| (std::isinf(d1) && std::isinf(d2) && d1 * d2 > 0.0 /*same sign*/)
|
||||
|| Helpers::IsApproximatelyEqual(d1, d2, precision, reference));
|
||||
|| IsApproximatelyEqual(d1, d2, precision, reference));
|
||||
}
|
||||
|
||||
void assert_data_statictics_equal_to(double v[], double n[], int numberOfData, double trueSumOfOccurrences, double trueMaxValue, double trueMinValue, double trueRange, double trueMean, double trueVariance, double trueStandardDeviation, double trueSampleStandardDeviation, double trueFirstQuartile, double trueThirdQuartile, double trueQuartileRange, double trueMedian, double trueSum, double trueSquaredValueSum) {
|
||||
|
||||
@@ -11,7 +11,6 @@ namespace Helpers {
|
||||
size_t AlignedSize(size_t realSize, size_t alignment);
|
||||
size_t Gcd(size_t a, size_t b);
|
||||
bool Rotate(uint32_t * dst, uint32_t * src, size_t len);
|
||||
bool IsApproximatelyEqual(double observedValue, double expectedValue, double precision, double reference);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -98,21 +98,5 @@ bool Rotate(uint32_t * dst, uint32_t * src, size_t len) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsApproximatelyEqual(double observedValue, double expectedValue, double precision, double reference) {
|
||||
/* Return true if observedValue and expectedValue are approximately equal, according to precision and reference parameters */
|
||||
if (expectedValue != 0.0) {
|
||||
double relativeError = std::fabs((observedValue - expectedValue) / expectedValue);
|
||||
// The relative error must be smaller than the precision
|
||||
return relativeError <= precision;
|
||||
}
|
||||
if (reference != 0.0) {
|
||||
double referenceRatio = std::fabs(observedValue / reference);
|
||||
// The observedValue must be negligible against the reference
|
||||
return referenceRatio <= precision;
|
||||
}
|
||||
// The observedValue must exactly match the expectedValue
|
||||
return observedValue == expectedValue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +103,21 @@ void assert_parsed_expression_simplify_to(const char * expression, const char *
|
||||
});
|
||||
}
|
||||
|
||||
bool IsApproximatelyEqual(double observedValue, double expectedValue, double precision, double reference) {
|
||||
if (expectedValue != 0.0) {
|
||||
double relativeError = std::fabs((observedValue - expectedValue) / expectedValue);
|
||||
// The relative error must be smaller than the precision
|
||||
return relativeError <= precision;
|
||||
}
|
||||
if (reference != 0.0) {
|
||||
double referenceRatio = std::fabs(observedValue / reference);
|
||||
// The observedValue must be negligible against the reference
|
||||
return referenceRatio <= precision;
|
||||
}
|
||||
// The observedValue must exactly match the expectedValue
|
||||
return observedValue == expectedValue;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void assert_expression_approximates_to(const char * expression, const char * approximation, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, int numberOfSignificantDigits) {
|
||||
int numberOfDigits = sizeof(T) == sizeof(double) ? PrintFloat::k_numberOfStoredSignificantDigits : PrintFloat::k_numberOfPrintedSignificantDigits;
|
||||
|
||||
@@ -47,6 +47,9 @@ void assert_parsed_expression_simplify_to(const char * expression, const char *
|
||||
|
||||
// Approximation
|
||||
|
||||
/* Return true if observedValue and expectedValue are approximately equal,
|
||||
* according to precision and reference parameters */
|
||||
bool IsApproximatelyEqual(double observedValue, double expectedValue, double precision, double reference);
|
||||
template<typename T>
|
||||
void assert_expression_approximates_to(const char * expression, const char * approximation, Poincare::Preferences::AngleUnit angleUnit = Degree, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, int numberOfSignificantDigits = -1);
|
||||
void assert_expression_simplifies_and_approximates_to(const char * expression, const char * approximation, Poincare::Preferences::AngleUnit angleUnit = Degree, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, int numberOfSignificantDigits = -1);
|
||||
|
||||
Reference in New Issue
Block a user