diff --git a/apps/Makefile b/apps/Makefile index 85bc4610f..6a98142e9 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -17,7 +17,6 @@ app_src += $(addprefix apps/,\ backlight_dimming_timer.cpp \ battery_timer.cpp \ battery_view.cpp \ - constant.cpp \ empty_battery_window.cpp \ exam_pop_up_controller.cpp \ global_preferences.cpp \ diff --git a/apps/constant.cpp b/apps/constant.cpp deleted file mode 100644 index 6a1259964..000000000 --- a/apps/constant.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "constant.h" - -constexpr int Constant::LargeNumberOfSignificantDigits; -constexpr int Constant::MediumNumberOfSignificantDigits; -constexpr int Constant::ShortNumberOfSignificantDigits; diff --git a/apps/constant.h b/apps/constant.h index 4d4c86520..0190f0eb2 100644 --- a/apps/constant.h +++ b/apps/constant.h @@ -5,9 +5,6 @@ class Constant { public: - constexpr static int LargeNumberOfSignificantDigits = 7; - constexpr static int MediumNumberOfSignificantDigits = 5; - constexpr static int ShortNumberOfSignificantDigits = 4; constexpr static int MaxSerializedExpressionSize = 2*::TextField::maxBufferSize(); }; diff --git a/apps/graph/graph/graph_controller_helper.cpp b/apps/graph/graph/graph_controller_helper.cpp index 5fb387d31..2ef5fd11b 100644 --- a/apps/graph/graph/graph_controller_helper.cpp +++ b/apps/graph/graph/graph_controller_helper.cpp @@ -1,8 +1,8 @@ #include "graph_controller_helper.h" #include "../../shared/function_banner_delegate.h" #include "../app.h" -#include "../../constant.h" #include "../../shared/poincare_helpers.h" +#include using namespace Shared; using namespace Poincare; @@ -20,7 +20,7 @@ bool GraphControllerHelper::privateMoveCursorHorizontally(Shared::CurveViewCurso void GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(Shared::CurveViewCursor * cursor, Ion::Storage::Record record) { ExpiringPointer function = App::app()->functionStore()->modelForRecord(record); - constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits); + constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits); char buffer[bufferSize]; const char * space = " "; int numberOfChar = function->derivativeNameWithArgument(buffer, bufferSize, CartesianFunction::Symbol()); @@ -28,7 +28,7 @@ void GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(Shar assert(numberOfChar <= bufferSize); numberOfChar += strlcpy(buffer+numberOfChar, legend, bufferSize-numberOfChar); double y = function->approximateDerivative(cursor->x(), App::app()->localContext()); - numberOfChar += PoincareHelpers::ConvertFloatToText(y, buffer + numberOfChar, bufferSize-numberOfChar, Constant::ShortNumberOfSignificantDigits); + numberOfChar += PoincareHelpers::ConvertFloatToText(y, buffer + numberOfChar, bufferSize-numberOfChar, Preferences::ShortNumberOfSignificantDigits); assert(numberOfChar <= bufferSize); strlcpy(buffer+numberOfChar, space, bufferSize-numberOfChar); bannerView()->derivativeView()->setText(buffer); diff --git a/apps/graph/graph/intersection_graph_controller.cpp b/apps/graph/graph/intersection_graph_controller.cpp index d95c5fe9b..169f1fcdb 100644 --- a/apps/graph/graph/intersection_graph_controller.cpp +++ b/apps/graph/graph/intersection_graph_controller.cpp @@ -1,6 +1,7 @@ #include "intersection_graph_controller.h" #include "../app.h" #include "../../shared/poincare_helpers.h" +#include using namespace Shared; @@ -18,7 +19,7 @@ const char * IntersectionGraphController::title() { void IntersectionGraphController::reloadBannerView() { CalculationGraphController::reloadBannerView(); - constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits); + constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(Poincare::Preferences::LargeNumberOfSignificantDigits); char buffer[bufferSize]; const char * space = " "; const char * legend = "="; @@ -32,7 +33,7 @@ void IntersectionGraphController::reloadBannerView() { numberOfChar += g->nameWithArgument(buffer+numberOfChar, bufferSize-numberOfChar-1, CartesianFunction::Symbol()); assert(numberOfChar <= bufferSize); numberOfChar += strlcpy(buffer+numberOfChar, legend, bufferSize-numberOfChar); - numberOfChar += PoincareHelpers::ConvertFloatToText(m_cursor->y(), buffer+numberOfChar, bufferSize-numberOfChar, Constant::MediumNumberOfSignificantDigits); + numberOfChar += PoincareHelpers::ConvertFloatToText(m_cursor->y(), buffer+numberOfChar, bufferSize-numberOfChar, Poincare::Preferences::MediumNumberOfSignificantDigits); assert(numberOfChar <= bufferSize); strlcpy(buffer+numberOfChar, space, bufferSize-numberOfChar); bannerView()->ordinateView()->setText(buffer); diff --git a/apps/graph/graph/tangent_graph_controller.cpp b/apps/graph/graph/tangent_graph_controller.cpp index 82e9ad4cb..57b0c6cab 100644 --- a/apps/graph/graph/tangent_graph_controller.cpp +++ b/apps/graph/graph/tangent_graph_controller.cpp @@ -1,6 +1,7 @@ #include "tangent_graph_controller.h" #include "../../shared/poincare_helpers.h" #include "../app.h" +#include using namespace Shared; using namespace Poincare; @@ -64,21 +65,22 @@ void TangentGraphController::reloadBannerView() { } FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(m_cursor, m_record, Shared::FunctionApp::app()->functionStore(), CartesianFunction::Symbol()); GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, m_record); - constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits); + constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters + PrintFloat::bufferSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits); char buffer[bufferSize]; Poincare::Context * context = textFieldDelegateApp()->localContext(); + constexpr int precision = Preferences::MediumNumberOfSignificantDigits; const char * legend = "a="; int legendLength = strlcpy(buffer, legend, bufferSize); ExpiringPointer function = App::app()->functionStore()->modelForRecord(m_record); double y = function->approximateDerivative(m_cursor->x(), context); - PoincareHelpers::ConvertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); + PoincareHelpers::ConvertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(precision), precision); m_bannerView->aView()->setText(buffer); legend = "b="; legendLength = strlcpy(buffer, legend, bufferSize); y = -y*m_cursor->x()+function->evaluateAtAbscissa(m_cursor->x(), context); - PoincareHelpers::ConvertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); + PoincareHelpers::ConvertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(precision), precision); m_bannerView->bView()->setText(buffer); m_bannerView->reload(); } diff --git a/apps/hardware_test/battery_test_controller.cpp b/apps/hardware_test/battery_test_controller.cpp index ab81dcd99..70d406784 100644 --- a/apps/hardware_test/battery_test_controller.cpp +++ b/apps/hardware_test/battery_test_controller.cpp @@ -1,6 +1,5 @@ #include "battery_test_controller.h" #include -#include "../constant.h" #include "app.h" extern "C" { #include @@ -43,14 +42,16 @@ void BatteryTestController::viewWillAppear() { } void BatteryTestController::updateBatteryState(float batteryLevel, bool batteryCharging) { - constexpr size_t bufferLevelSize = ContentView::k_maxNumberOfCharacters + PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits); + constexpr int precision = Preferences::LargeNumberOfSignificantDigits; + constexpr int sizeForPrecision = PrintFloat::bufferSizeForFloatsWithPrecision(precision); + constexpr size_t bufferLevelSize = ContentView::k_maxNumberOfCharacters + sizeForPrecision; char bufferLevel[bufferLevelSize]; const char * legend = "Battery level: "; int legendLength = strlcpy(bufferLevel, legend, bufferLevelSize); - PrintFloat::ConvertFloatToText(batteryLevel, bufferLevel+legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal); + PrintFloat::ConvertFloatToText(batteryLevel, bufferLevel+legendLength, sizeForPrecision, precision, Preferences::PrintFloatMode::Decimal); m_view.batteryLevelTextView()->setText(bufferLevel); - constexpr size_t bufferChargingSize = ContentView::k_maxNumberOfCharacters + PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits); + constexpr size_t bufferChargingSize = ContentView::k_maxNumberOfCharacters + sizeForPrecision; char bufferCharging[bufferChargingSize]; int numberOfChars = 0; legend = "Battery charging: "; diff --git a/apps/probability/Makefile b/apps/probability/Makefile index ed3e3fd39..860892894 100644 --- a/apps/probability/Makefile +++ b/apps/probability/Makefile @@ -3,7 +3,6 @@ app_headers += apps/probability/app.h app_probability_test_src = $(addprefix apps/probability/,\ distribution/chi_squared_distribution.cpp \ - distribution/erf_inv.cpp \ distribution/geometric_distribution.cpp \ distribution/helper.cpp \ distribution/incomplete_beta_function.cpp \ @@ -53,7 +52,6 @@ tests_src += $(addprefix apps/probability/distribution/,\ hypergeometric_function.cpp\ ) tests_src += $(addprefix apps/probability/test/,\ - erf_inv.cpp\ hypergeometric_function.cpp\ distributions.cpp\ regularized_gamma.cpp \ diff --git a/apps/probability/calculation/left_integral_calculation.cpp b/apps/probability/calculation/left_integral_calculation.cpp index eec5e2b4e..a08d402c6 100644 --- a/apps/probability/calculation/left_integral_calculation.cpp +++ b/apps/probability/calculation/left_integral_calculation.cpp @@ -1,7 +1,7 @@ #include "left_integral_calculation.h" -#include -#include +#include #include +#include namespace Probability { @@ -48,7 +48,7 @@ void LeftIntegralCalculation::compute(int indexKnownElement) { m_result = m_distribution->cumulativeDistributiveFunctionAtAbscissa(m_upperBound); } else { double currentResult = m_distribution->cumulativeDistributiveFunctionAtAbscissa(m_upperBound); - if (std::fabs(currentResult - m_result) < std::pow(10.0, - Constant::LargeNumberOfSignificantDigits)) { + if (std::fabs(currentResult - m_result) < std::pow(10.0, - Poincare::Preferences::LargeNumberOfSignificantDigits)) { return; } m_upperBound = m_distribution->cumulativeDistributiveInverseForProbability(&m_result); diff --git a/apps/probability/calculation/right_integral_calculation.cpp b/apps/probability/calculation/right_integral_calculation.cpp index a1d760392..9fc8bdea4 100644 --- a/apps/probability/calculation/right_integral_calculation.cpp +++ b/apps/probability/calculation/right_integral_calculation.cpp @@ -1,7 +1,7 @@ #include "right_integral_calculation.h" -#include -#include +#include #include +#include namespace Probability { @@ -48,7 +48,7 @@ void RightIntegralCalculation::compute(int indexKnownElement) { m_result = m_distribution->rightIntegralFromAbscissa(m_lowerBound); } else { double currentResult = m_distribution->rightIntegralFromAbscissa(m_lowerBound); - if (std::fabs(currentResult - m_result) < std::pow(10.0, - Constant::LargeNumberOfSignificantDigits)) { + if (std::fabs(currentResult - m_result) < std::pow(10.0, - Poincare::Preferences::LargeNumberOfSignificantDigits)) { return; } m_lowerBound = m_distribution->rightIntegralInverseForProbability(&m_result); diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index c91f91409..a4e732775 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -1,5 +1,4 @@ #include "calculation_controller.h" -#include "../constant.h" #include "../shared/poincare_helpers.h" #include "app.h" #include "calculation/discrete_calculation.h" @@ -14,6 +13,7 @@ #include "images/focused_calcul2_icon.h" #include "images/focused_calcul3_icon.h" #include "images/focused_calcul4_icon.h" +#include #include #include @@ -179,7 +179,7 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int if (field->isEditing()) { return; } - constexpr int precision = Constant::LargeNumberOfSignificantDigits; + constexpr int precision = Preferences::LargeNumberOfSignificantDigits; constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision); char buffer[bufferSize]; PrintFloat::ConvertFloatToText(m_calculation->parameterAtIndex(i-1), buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal); @@ -282,7 +282,7 @@ void CalculationController::updateTitle() { if (currentChar >= k_titleBufferSize) { break; } - constexpr int precision = Constant::ShortNumberOfSignificantDigits; + constexpr int precision = Preferences::ShortNumberOfSignificantDigits; constexpr size_t bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision); char buffer[bufferSize]; PrintFloat::ConvertFloatToText(m_distribution->parameterValueAtIndex(index), buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal); diff --git a/apps/probability/distribution/distribution.h b/apps/probability/distribution/distribution.h index fb19a1b9c..ab5927d22 100644 --- a/apps/probability/distribution/distribution.h +++ b/apps/probability/distribution/distribution.h @@ -1,10 +1,9 @@ #ifndef PROBABILITE_DISTRIBUTION_H #define PROBABILITE_DISTRIBUTION_H -#include -#include "../../constant.h" #include "../../shared/curve_view_range.h" #include +#include namespace Probability { @@ -40,7 +39,7 @@ public: virtual double evaluateAtDiscreteAbscissa(int k) const; constexpr static int k_maxNumberOfOperations = 1000000; protected: - static_assert(Constant::LargeNumberOfSignificantDigits == 7, "k_maxProbability is ill-defined compared to LargeNumberOfSignificantDigits"); + static_assert(Poincare::Preferences::LargeNumberOfSignificantDigits == 7, "k_maxProbability is ill-defined compared to LargeNumberOfSignificantDigits"); constexpr static double k_maxProbability = 0.9999995; constexpr static float k_displayTopMarginRatio = 0.05f; constexpr static float k_displayLeftMarginRatio = 0.05f; diff --git a/apps/probability/distribution/erf_inv.h b/apps/probability/distribution/erf_inv.h deleted file mode 100644 index 36712a693..000000000 --- a/apps/probability/distribution/erf_inv.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef PROBABILITE_ERFINV_H -#define PROBABILITE_ERFINV_H - -double erfInv(double y); - -#endif - diff --git a/apps/probability/distribution/normal_distribution.cpp b/apps/probability/distribution/normal_distribution.cpp index c3e7c8d3a..691b7d0bd 100644 --- a/apps/probability/distribution/normal_distribution.cpp +++ b/apps/probability/distribution/normal_distribution.cpp @@ -1,5 +1,5 @@ #include "normal_distribution.h" -#include "erf_inv.h" +#include #include #include #include @@ -33,10 +33,7 @@ I18n::Message NormalDistribution::parameterDefinitionAtIndex(int index) { } float NormalDistribution::evaluateAtAbscissa(float x) const { - if (m_parameter2 == 0.0f) { - return NAN; - } - return (1.0f/(std::fabs(m_parameter2) * std::sqrt(2.0f * M_PI))) * std::exp(-0.5f * std::pow((x - m_parameter1)/m_parameter2, 2)); + return Poincare::NormalDistribution::EvaluateAtAbscissa(x, m_parameter1, m_parameter2); } bool NormalDistribution::authorizedValueAtIndex(float x, int index) const { @@ -57,43 +54,11 @@ void NormalDistribution::setParameterAtIndex(float f, int index) { } double NormalDistribution::cumulativeDistributiveFunctionAtAbscissa(double x) const { - if (m_parameter2 == 0.0f) { - return NAN; - } - return standardNormalCumulativeDistributiveFunctionAtAbscissa((x-m_parameter1)/std::fabs(m_parameter2)); + return Poincare::NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(x, m_parameter1, m_parameter2); } double NormalDistribution::cumulativeDistributiveInverseForProbability(double * probability) { - if (m_parameter2 == 0.0f) { - return NAN; - } - return standardNormalCumulativeDistributiveInverseForProbability(*probability) * std::fabs(m_parameter2) + m_parameter1; -} - -double NormalDistribution::standardNormalCumulativeDistributiveFunctionAtAbscissa(double abscissa) const { - if (abscissa == 0.0) { - return 0.5; - } - if (abscissa < 0.0) { - return 1.0 - standardNormalCumulativeDistributiveFunctionAtAbscissa(-abscissa); - } - if (abscissa > k_boundStandardNormalDistribution) { - return 1.0; - } - return 0.5 + 0.5 * std::erf(abscissa/std::sqrt(2.0)); -} - -double NormalDistribution::standardNormalCumulativeDistributiveInverseForProbability(double probability) { - if (probability >= 1.0) { - return INFINITY; - } - if (probability <= 0.0) { - return -INFINITY; - } - if (probability < 0.5) { - return -standardNormalCumulativeDistributiveInverseForProbability(1-probability); - } - return std::sqrt(2.0) * erfInv(2.0 * probability - 1.0); + return Poincare::NormalDistribution::CumulativeDistributiveInverseForProbability(*probability, m_parameter1, m_parameter2); } float NormalDistribution::xExtremum(bool min) const { diff --git a/apps/probability/distribution/normal_distribution.h b/apps/probability/distribution/normal_distribution.h index 3751493d1..ae64e1107 100644 --- a/apps/probability/distribution/normal_distribution.h +++ b/apps/probability/distribution/normal_distribution.h @@ -23,13 +23,6 @@ public: double cumulativeDistributiveInverseForProbability(double * probability) override; private: constexpr static double k_maxRatioMuSigma = 1000000.0f; - /* For the standard normal distribution, P(X < y) > 0.9999995 with y >= 4.892 so the - * value displayed is 1. But this is dependent on the fact that we display - * only 7 decimal values! */ - static_assert(Constant::LargeNumberOfSignificantDigits == 7, "k_maxProbability is ill-defined compared to LargeNumberOfSignificantDigits"); - constexpr static double k_boundStandardNormalDistribution = 4.892; - double standardNormalCumulativeDistributiveFunctionAtAbscissa(double abscissa) const; - double standardNormalCumulativeDistributiveInverseForProbability(double probability); float xExtremum(bool min) const; }; diff --git a/apps/regression/calculation_controller.cpp b/apps/regression/calculation_controller.cpp index be96868a0..8ba925910 100644 --- a/apps/regression/calculation_controller.cpp +++ b/apps/regression/calculation_controller.cpp @@ -3,6 +3,7 @@ #include "../shared/poincare_helpers.h" #include #include +#include #include @@ -169,15 +170,17 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int } // Calculation cell + const int numberSignificantDigits = Preferences::LargeNumberOfSignificantDigits; if (i > 0 && j > 0 && j <= k_totalNumberOfDoubleBufferRows) { ArgCalculPointer calculationMethods[k_totalNumberOfDoubleBufferRows] = {&Store::meanOfColumn, &Store::sumOfColumn, &Store::squaredValueSumOfColumn, &Store::standardDeviationOfColumn, &Store::varianceOfColumn}; double calculation1 = (m_store->*calculationMethods[j-1])(seriesNumber, 0); double calculation2 = (m_store->*calculationMethods[j-1])(seriesNumber, 1); EvenOddDoubleBufferTextCellWithSeparator * myCell = (EvenOddDoubleBufferTextCellWithSeparator *)cell; - char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; - PoincareHelpers::ConvertFloatToText(calculation1, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits); + constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(numberSignificantDigits); + char buffer[bufferSize]; + PoincareHelpers::ConvertFloatToText(calculation1, buffer, bufferSize, numberSignificantDigits); myCell->setFirstText(buffer); - PoincareHelpers::ConvertFloatToText(calculation2, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits); + PoincareHelpers::ConvertFloatToText(calculation2, buffer, bufferSize, numberSignificantDigits); myCell->setSecondText(buffer); return; } @@ -192,8 +195,9 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int assert(j != k_regressionCellIndex); CalculPointer calculationMethods[] = {&Store::doubleCastedNumberOfPairsOfSeries, &Store::covariance, &Store::columnProductSum}; double calculation = (m_store->*calculationMethods[j-k_totalNumberOfDoubleBufferRows-1])(seriesNumber); - char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; - PoincareHelpers::ConvertFloatToText(calculation, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits); + constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(numberSignificantDigits); + char buffer[bufferSize]; + PoincareHelpers::ConvertFloatToText(calculation, buffer, bufferSize, numberSignificantDigits); bufferCell->setText(buffer); return; } @@ -223,8 +227,9 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int if (modelType == Model::Type::Linear) { CalculPointer calculationMethods[2] = {&Store::correlationCoefficient, &Store::squaredCorrelationCoefficient}; double calculation = (m_store->*calculationMethods[j - k_regressionCellIndex - maxNumberCoefficients - 1])(seriesNumber); - char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; - PoincareHelpers::ConvertFloatToText(calculation, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits); + constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(numberSignificantDigits); + char buffer[bufferSize]; + PoincareHelpers::ConvertFloatToText(calculation, buffer, bufferSize, numberSignificantDigits); bufferCell->setText(buffer); return; } else { @@ -238,8 +243,9 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int bufferCell->setText(I18n::translate(I18n::Message::Dash)); return; } else { - char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; - PoincareHelpers::ConvertFloatToText(coefficients[j - k_regressionCellIndex - 1], buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits); + constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(numberSignificantDigits); + char buffer[bufferSize]; + PoincareHelpers::ConvertFloatToText(coefficients[j - k_regressionCellIndex - 1], buffer, bufferSize, numberSignificantDigits); bufferCell->setText(buffer); return; } diff --git a/apps/regression/calculation_controller.h b/apps/regression/calculation_controller.h index 00237fa73..35881290d 100644 --- a/apps/regression/calculation_controller.h +++ b/apps/regression/calculation_controller.h @@ -2,6 +2,7 @@ #define REGRESSION_CALCULATION_CONTROLLER_H #include +#include #include "store.h" #include "column_title_cell.h" #include "even_odd_double_buffer_text_cell_with_separator.h" @@ -10,7 +11,6 @@ #include "../shared/tab_table_controller.h" #include "../shared/separator_even_odd_buffer_text_cell.h" #include "../shared/store_cell.h" -#include "../constant.h" namespace Regression { @@ -64,7 +64,7 @@ private: static constexpr KDCoordinate k_cellHeight = 25; static constexpr KDCoordinate k_titleCalculationCellWidth = Ion::Display::Width/2 - Metric::CommonRightMargin/2 - Metric::CommonLeftMargin/2; // TODO: change 7 for KDFont::SmallFont->glyphSize().width() - static constexpr KDCoordinate k_minCalculationCellWidth = 7*2*(Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)); //Calculation width should at least be able to hold to numbers with LargeNumberOfSignificantDigits. + static constexpr KDCoordinate k_minCalculationCellWidth = 7*2*(Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(Poincare::Preferences::LargeNumberOfSignificantDigits)); //Calculation width should at least be able to hold to numbers with LargeNumberOfSignificantDigits. static constexpr KDCoordinate k_cubicCalculationCellWidth = maxCoordinate(150, k_minCalculationCellWidth); // Should hold aX^3+bX^2+cX+d static constexpr KDCoordinate k_quarticCalculationCellWidth = maxCoordinate(195, k_minCalculationCellWidth ); // Should hold ? aX^4+bX^3+c*X^2+dX+e static constexpr KDCoordinate k_margin = 8; diff --git a/apps/regression/graph_controller.cpp b/apps/regression/graph_controller.cpp index 6f3322980..bc26a5d8c 100644 --- a/apps/regression/graph_controller.cpp +++ b/apps/regression/graph_controller.cpp @@ -2,6 +2,7 @@ #include "../shared/poincare_helpers.h" #include "../shared/text_helpers.h" #include "../apps_container.h" +#include #include using namespace Poincare; @@ -104,7 +105,7 @@ Poincare::Context * GraphController::globalContext() { void GraphController::reloadBannerView() { // Set point equals: "P(...) =" - constexpr size_t bufferSize = k_maxNumberOfCharacters + PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits); + constexpr size_t bufferSize = k_maxNumberOfCharacters + PrintFloat::bufferSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits); char buffer[bufferSize]; int numberOfChar = 0; const char * legend = " P("; @@ -118,7 +119,7 @@ void GraphController::reloadBannerView() { assert(numberOfChar <= bufferSize); numberOfChar += strlcpy(buffer + numberOfChar, legend, bufferSize - numberOfChar); } else { - numberOfChar += PrintFloat::ConvertFloatToText(std::round((float)*m_selectedDotIndex+1.0f), buffer + numberOfChar, bufferSize - numberOfChar, Constant::ShortNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal); + numberOfChar += PrintFloat::ConvertFloatToText(std::round((float)*m_selectedDotIndex+1.0f), buffer + numberOfChar, bufferSize - numberOfChar, Preferences::ShortNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal); } legend = ") "; assert(numberOfChar <= bufferSize); @@ -136,7 +137,7 @@ void GraphController::reloadBannerView() { } m_bannerView.abscissaSymbol()->setText(legend); - numberOfChar = PoincareHelpers::ConvertFloatToText(x, buffer, bufferSize, Constant::MediumNumberOfSignificantDigits); + numberOfChar = PoincareHelpers::ConvertFloatToText(x, buffer, bufferSize, Preferences::MediumNumberOfSignificantDigits); // Padding Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, k_maxLegendLength); m_bannerView.abscissaValue()->setText(buffer); @@ -151,7 +152,7 @@ void GraphController::reloadBannerView() { y = m_store->meanOfColumn(*m_selectedSeriesIndex, 1); } numberOfChar += strlcpy(buffer, legend, bufferSize); - numberOfChar += PoincareHelpers::ConvertFloatToText(y, buffer + numberOfChar, bufferSize - numberOfChar, Constant::MediumNumberOfSignificantDigits); + numberOfChar += PoincareHelpers::ConvertFloatToText(y, buffer + numberOfChar, bufferSize - numberOfChar, Preferences::MediumNumberOfSignificantDigits); // Padding Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, k_maxLegendLength); m_bannerView.ordinateView()->setText(buffer); @@ -192,7 +193,7 @@ void GraphController::reloadBannerView() { char leg[] = {' ', coefficientName, '=', 0}; legend = leg; numberOfChar += strlcpy(buffer, legend, bufferSize); - numberOfChar += PoincareHelpers::ConvertFloatToText(coefficients[i], buffer + numberOfChar, bufferSize - numberOfChar, Constant::LargeNumberOfSignificantDigits); + numberOfChar += PoincareHelpers::ConvertFloatToText(coefficients[i], buffer + numberOfChar, bufferSize - numberOfChar, Preferences::LargeNumberOfSignificantDigits); m_bannerView.subTextAtIndex(i)->setText(buffer); coefficientName++; } @@ -203,7 +204,7 @@ void GraphController::reloadBannerView() { legend = " r="; double r = m_store->correlationCoefficient(*m_selectedSeriesIndex); numberOfChar += strlcpy(buffer, legend, bufferSize); - numberOfChar += PoincareHelpers::ConvertFloatToText(r, buffer + numberOfChar, bufferSize - numberOfChar, Constant::LargeNumberOfSignificantDigits); + numberOfChar += PoincareHelpers::ConvertFloatToText(r, buffer + numberOfChar, bufferSize - numberOfChar, Preferences::LargeNumberOfSignificantDigits); m_bannerView.subTextAtIndex(2)->setText(buffer); // Set "r2=..." @@ -211,7 +212,7 @@ void GraphController::reloadBannerView() { legend = " r2="; double r2 = m_store->squaredCorrelationCoefficient(*m_selectedSeriesIndex); numberOfChar += strlcpy(buffer, legend, bufferSize); - numberOfChar += PoincareHelpers::ConvertFloatToText(r2, buffer + numberOfChar, bufferSize - numberOfChar, Constant::LargeNumberOfSignificantDigits); + numberOfChar += PoincareHelpers::ConvertFloatToText(r2, buffer + numberOfChar, bufferSize - numberOfChar, Preferences::LargeNumberOfSignificantDigits); m_bannerView.subTextAtIndex(3)->setText(buffer); // Clean the last subview diff --git a/apps/shared/curve_view.h b/apps/shared/curve_view.h index a3742db1d..b739a3bd1 100644 --- a/apps/shared/curve_view.h +++ b/apps/shared/curve_view.h @@ -1,12 +1,11 @@ #ifndef SHARED_CURVE_VIEW_H #define SHARED_CURVE_VIEW_H -#include -#include +#include "banner_view.h" #include "curve_view_range.h" #include "curve_view_cursor.h" -#include "banner_view.h" -#include +#include +#include namespace Shared { @@ -47,7 +46,7 @@ protected: constexpr static KDCoordinate k_okHorizontalMargin = 10; constexpr static KDCoordinate k_labelGraduationLength = 6; constexpr static int k_numberSignificantDigits = 6; - constexpr static int k_bigNumberSignificantDigits = Constant::LargeNumberOfSignificantDigits; + constexpr static int k_bigNumberSignificantDigits = Poincare::Preferences::LargeNumberOfSignificantDigits; constexpr static int k_labelBufferMaxSize = 1 + k_bigNumberSignificantDigits + 3 + 3 + 1; // '-' + significant digits + '.' + "E-" + 3 digits + null-terminating char constexpr static int k_maxNumberOfXLabels = CurveViewRange::k_maxNumberOfXGridUnits; constexpr static int k_maxNumberOfYLabels = CurveViewRange::k_maxNumberOfYGridUnits; diff --git a/apps/shared/editable_cell_table_view_controller.cpp b/apps/shared/editable_cell_table_view_controller.cpp index 0be4edde2..db0e0921a 100644 --- a/apps/shared/editable_cell_table_view_controller.cpp +++ b/apps/shared/editable_cell_table_view_controller.cpp @@ -64,7 +64,7 @@ void EditableCellTableViewController::willDisplayCellAtLocationWithDisplayMode(H // The cell is editable if (cellAtLocationIsEditable(i, j)) { EvenOddEditableTextCell * myEditableValueCell = (EvenOddEditableTextCell *)cell; - char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; + char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits)]; // Special case 1: last row if (j == numberOfRows() - 1) { /* Display an empty line only if there is enough space for a new element in @@ -78,7 +78,7 @@ void EditableCellTableViewController::willDisplayCellAtLocationWithDisplayMode(H } if (!myEditableValueCell->editableTextCell()->textField()->isEditing()) { myCell->setEven(j%2 == 0); - PrintFloat::ConvertFloatToText(dataAtLocation(i, j), buffer, cellBufferSize(i), Constant::LargeNumberOfSignificantDigits, floatDisplayMode); + PrintFloat::ConvertFloatToText(dataAtLocation(i, j), buffer, cellBufferSize(i), Preferences::LargeNumberOfSignificantDigits, floatDisplayMode); myEditableValueCell->editableTextCell()->textField()->setText(buffer); } return; diff --git a/apps/shared/float_parameter_controller.cpp b/apps/shared/float_parameter_controller.cpp index b4bf16c2a..d8b6729ae 100644 --- a/apps/shared/float_parameter_controller.cpp +++ b/apps/shared/float_parameter_controller.cpp @@ -1,6 +1,6 @@ #include "float_parameter_controller.h" -#include "../constant.h" #include "../shared/poincare_helpers.h" +#include #include #include @@ -108,8 +108,10 @@ void FloatParameterController::willDisplayCellForIndex(HighlightCell * cell, int if (myCell->isEditing()) { return; } - char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; - PrintFloat::ConvertFloatToText(parameterAtIndex(index), buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal); + constexpr int precision = Preferences::LargeNumberOfSignificantDigits; + constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision); + char buffer[bufferSize]; + PrintFloat::ConvertFloatToText(parameterAtIndex(index), buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal); myCell->setAccessoryText(buffer); } diff --git a/apps/shared/function_banner_delegate.cpp b/apps/shared/function_banner_delegate.cpp index c5bf45089..eeb5f129c 100644 --- a/apps/shared/function_banner_delegate.cpp +++ b/apps/shared/function_banner_delegate.cpp @@ -1,6 +1,6 @@ #include "function_banner_delegate.h" #include "poincare_helpers.h" -#include "../constant.h" +#include using namespace Poincare; @@ -8,7 +8,7 @@ namespace Shared { void FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(CurveViewCursor * cursor, Ion::Storage::Record record, FunctionStore * functionStore, char symbol) { ExpiringPointer function = functionStore->modelForRecord(record); - constexpr int bufferSize = k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits); + constexpr int bufferSize = k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits); char buffer[bufferSize]; const char * space = " "; int numberOfChar = 0; @@ -17,7 +17,9 @@ void FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(CurveViewCursor strlcpy(buffer + numberOfChar, "=", bufferSize - numberOfChar); bannerView()->abscissaSymbol()->setText(buffer); - numberOfChar = PoincareHelpers::ConvertFloatToText(cursor->x(), buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); + constexpr int precision = Preferences::MediumNumberOfSignificantDigits; + + numberOfChar = PoincareHelpers::ConvertFloatToText(cursor->x(), buffer, PrintFloat::bufferSizeForFloatsWithPrecision(precision), precision); assert(numberOfChar <= bufferSize); strlcpy(buffer+numberOfChar, space, bufferSize - numberOfChar); bannerView()->abscissaValue()->setText(buffer); @@ -25,7 +27,7 @@ void FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(CurveViewCursor numberOfChar = function->nameWithArgument(buffer, bufferSize, symbol); assert(numberOfChar <= bufferSize); numberOfChar += strlcpy(buffer+numberOfChar, "=", bufferSize-numberOfChar); - numberOfChar += PoincareHelpers::ConvertFloatToText(cursor->y(), buffer+numberOfChar, bufferSize-numberOfChar, Constant::MediumNumberOfSignificantDigits); + numberOfChar += PoincareHelpers::ConvertFloatToText(cursor->y(), buffer+numberOfChar, bufferSize-numberOfChar, precision); assert(numberOfChar <= bufferSize); strlcpy(buffer+numberOfChar, space, bufferSize-numberOfChar); bannerView()->ordinateView()->setText(buffer); diff --git a/apps/shared/sum_graph_controller.cpp b/apps/shared/sum_graph_controller.cpp index b2052130c..25b8c067f 100644 --- a/apps/shared/sum_graph_controller.cpp +++ b/apps/shared/sum_graph_controller.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "poincare_helpers.h" #include @@ -177,9 +178,11 @@ void SumGraphController::LegendView::setLegendMessage(I18n::Message message, Ste } void SumGraphController::LegendView::setEditableZone(double d) { - char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits)]; - PrintFloat::ConvertFloatToText(d, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal); - m_editableZone.setText(buffer); + constexpr int precision = Preferences::MediumNumberOfSignificantDigits; + constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision); + char buffer[bufferSize]; + PrintFloat::ConvertFloatToText(d, buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal); + m_editableZone.setText(buffer); } void SumGraphController::LegendView::setSumSymbol(Step step, double start, double end, double result, Layout functionLayout) { @@ -189,24 +192,29 @@ void SumGraphController::LegendView::setSumSymbol(Step step, double start, doubl if (step == Step::FirstParameter) { m_sumLayout = LayoutHelper::CodePointString(sigma, sigmaLength); } else if (step == Step::SecondParameter) { - char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits)]; - PrintFloat::ConvertFloatToText(start, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal); + constexpr int precision = Preferences::MediumNumberOfSignificantDigits; + constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision); + char buffer[bufferSize]; + PrintFloat::ConvertFloatToText(start, buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal); m_sumLayout = CondensedSumLayout::Builder( LayoutHelper::CodePointString(sigma, sigmaLength), LayoutHelper::String(buffer, strlen(buffer), k_font), EmptyLayout::Builder(EmptyLayoutNode::Color::Yellow, false, k_font, false)); } else { - char buffer[2+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; - PrintFloat::ConvertFloatToText(start, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal); + constexpr int precision = Preferences::LargeNumberOfSignificantDigits; + constexpr int sizeForPrecision = PrintFloat::bufferSizeForFloatsWithPrecision(precision); + constexpr int bufferSize = 2 + sizeForPrecision; + char buffer[bufferSize]; + PrintFloat::ConvertFloatToText(start, buffer, sizeForPrecision, precision, Preferences::PrintFloatMode::Decimal); Layout start = LayoutHelper::String(buffer, strlen(buffer), k_font); - PrintFloat::ConvertFloatToText(end, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal); + PrintFloat::ConvertFloatToText(end, buffer, sizeForPrecision, precision, Preferences::PrintFloatMode::Decimal); Layout end = LayoutHelper::String(buffer, strlen(buffer), k_font); m_sumLayout = CondensedSumLayout::Builder( LayoutHelper::CodePointString(sigma, sigmaLength), start, end); strlcpy(buffer, "= ", 3); - PoincareHelpers::ConvertFloatToText(result, buffer+2, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits); + PoincareHelpers::ConvertFloatToText(result, buffer+2, sizeForPrecision, precision); m_sumLayout = HorizontalLayout::Builder( m_sumLayout, functionLayout, diff --git a/apps/shared/values_controller.cpp b/apps/shared/values_controller.cpp index 14f79f06e..45fd31151 100644 --- a/apps/shared/values_controller.cpp +++ b/apps/shared/values_controller.cpp @@ -1,7 +1,7 @@ #include "values_controller.h" #include "function_app.h" -#include "../constant.h" #include "poincare_helpers.h" +#include #include using namespace Poincare; @@ -156,7 +156,8 @@ void ValuesController::willDisplayCellAtLocation(HighlightCell * cell, int i, in } // The cell is not a title cell and not editable if (j > 0 && i > 0) { - char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; + constexpr int precision = Preferences::LargeNumberOfSignificantDigits; + char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(precision)]; // Special case: last row if (j == numberOfRows() - 1) { int numberOfIntervalElements = m_interval->numberOfElements(); @@ -170,8 +171,8 @@ void ValuesController::willDisplayCellAtLocation(HighlightCell * cell, int i, in // The cell is a value cell EvenOddBufferTextCell * myValueCell = (EvenOddBufferTextCell *)cell; double x = m_interval->element(j-1); - PoincareHelpers::ConvertFloatToText(evaluationOfAbscissaAtColumn(x, i), buffer, cellBufferSize(i), Constant::LargeNumberOfSignificantDigits); - myValueCell->setText(buffer); + PoincareHelpers::ConvertFloatToText(evaluationOfAbscissaAtColumn(x, i), buffer, cellBufferSize(i), precision); + myValueCell->setText(buffer); } } diff --git a/apps/solver/equation_models_parameter_controller.cpp b/apps/solver/equation_models_parameter_controller.cpp index f8c9339a3..2a769c05c 100644 --- a/apps/solver/equation_models_parameter_controller.cpp +++ b/apps/solver/equation_models_parameter_controller.cpp @@ -1,9 +1,9 @@ #include "equation_models_parameter_controller.h" #include "list_controller.h" -#include "../constant.h" -#include #include +#include #include +#include using namespace Poincare; @@ -23,7 +23,7 @@ EquationModelsParameterController::EquationModelsParameterController(Responder * m_selectableTableView.setDecoratorType(ScrollView::Decorator::Type::None); for (int i = 0; i < k_numberOfExpressionCells; i++) { Poincare::Expression e = Expression::Parse(k_models[i+1]); - m_layouts[i] = e.createLayout(Poincare::Preferences::PrintFloatMode::Decimal, Constant::ShortNumberOfSignificantDigits); + m_layouts[i] = e.createLayout(Poincare::Preferences::PrintFloatMode::Decimal, Preferences::ShortNumberOfSignificantDigits); m_modelCells[i].setLayout(m_layouts[i]); } } diff --git a/apps/solver/solutions_controller.cpp b/apps/solver/solutions_controller.cpp index 64fa77f52..3d05a43b0 100644 --- a/apps/solver/solutions_controller.cpp +++ b/apps/solver/solutions_controller.cpp @@ -1,12 +1,12 @@ #include "solutions_controller.h" #include "app.h" -#include "../constant.h" #include "../shared/poincare_helpers.h" #include #include #include #include #include +#include #include #include @@ -188,8 +188,10 @@ void SolutionsController::willDisplayCellAtLocation(HighlightCell * cell, int i, // Value of the variable or discriminant if (m_equationStore->type() == EquationStore::Type::Monovariable) { EvenOddBufferTextCell * valueCell = static_cast(cell); - char bufferValue[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; - PoincareHelpers::ConvertFloatToText(m_equationStore->approximateSolutionAtIndex(j), bufferValue, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits); + constexpr int precision = Preferences::LargeNumberOfSignificantDigits; + constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision); + char bufferValue[bufferSize]; + PoincareHelpers::ConvertFloatToText(m_equationStore->approximateSolutionAtIndex(j), bufferValue, bufferSize, precision); valueCell->setText(bufferValue); } else { Shared::ScrollableExactApproximateExpressionsCell * valueCell = static_cast(cell); diff --git a/apps/statistics/box_controller.cpp b/apps/statistics/box_controller.cpp index 96000b7d9..85158b3b8 100644 --- a/apps/statistics/box_controller.cpp +++ b/apps/statistics/box_controller.cpp @@ -50,12 +50,13 @@ void BoxController::reloadBannerView() { // Set calculation result assert(UTF8Decoder::CharSizeOfCodePoint(' ') == 1); - constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits) + 1; + constexpr int precision = Preferences::LargeNumberOfSignificantDigits; + constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision) + 1; char buffer[bufferSize]; CalculPointer calculationMethods[5] = {&Store::minValue, &Store::firstQuartile, &Store::median, &Store::thirdQuartile, &Store::maxValue}; double calculation = (m_store->*calculationMethods[selectedQuantile])(selectedSeriesIndex()); - int numberOfChar = PoincareHelpers::ConvertFloatToText(calculation, buffer, bufferSize - 1, Constant::LargeNumberOfSignificantDigits); + int numberOfChar = PoincareHelpers::ConvertFloatToText(calculation, buffer, bufferSize - 1, precision); buffer[numberOfChar++] = ' '; assert(numberOfChar <= bufferSize - 1); buffer[numberOfChar] = 0; diff --git a/apps/statistics/calculation_controller.cpp b/apps/statistics/calculation_controller.cpp index 718d7f475..627716461 100644 --- a/apps/statistics/calculation_controller.cpp +++ b/apps/statistics/calculation_controller.cpp @@ -1,6 +1,7 @@ #include "calculation_controller.h" -#include #include "../shared/poincare_helpers.h" +#include +#include #include using namespace Shared; @@ -97,8 +98,10 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int int seriesIndex = m_store->indexOfKthNonEmptySeries(i-1); double calculation = (m_store->*calculationMethods[j-1])(seriesIndex); EvenOddBufferTextCell * calculationCell = static_cast(cell); - char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; - PoincareHelpers::ConvertFloatToText(calculation, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits); + constexpr int precision = Preferences::LargeNumberOfSignificantDigits; + constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision); + char buffer[bufferSize]; + PoincareHelpers::ConvertFloatToText(calculation, buffer, bufferSize, precision); calculationCell->setText(buffer); } diff --git a/apps/statistics/calculation_controller.h b/apps/statistics/calculation_controller.h index c5ef14621..653ac69d4 100644 --- a/apps/statistics/calculation_controller.h +++ b/apps/statistics/calculation_controller.h @@ -3,6 +3,7 @@ #include #include +#include #include "store.h" #include "calculation_selectable_table_view.h" #include "../shared/hideable_even_odd_cell.h" @@ -10,7 +11,6 @@ #include "../shared/separator_even_odd_buffer_text_cell.h" #include "../shared/store_title_cell.h" #include "../shared/tab_table_controller.h" -#include "../constant.h" namespace Statistics { @@ -56,7 +56,7 @@ private: static constexpr KDCoordinate k_cellHeight = 20; static constexpr KDCoordinate k_calculationTitleCellWidth = 175; // TODO: change 7 for KDFont::SmallFont->glyphSize().width() - static constexpr KDCoordinate k_calculationCellWidth = 7*(Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)); + static constexpr KDCoordinate k_calculationCellWidth = 7*(Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(Poincare::Preferences::LargeNumberOfSignificantDigits)); static constexpr KDCoordinate k_margin = 8; static constexpr KDCoordinate k_scrollBarMargin = Metric::CommonRightMargin; diff --git a/apps/statistics/histogram_controller.cpp b/apps/statistics/histogram_controller.cpp index 1e5b9320c..f682271fe 100644 --- a/apps/statistics/histogram_controller.cpp +++ b/apps/statistics/histogram_controller.cpp @@ -2,6 +2,7 @@ #include "../shared/poincare_helpers.h" #include "../shared/text_helpers.h" #include "app.h" +#include #include #include #include @@ -94,7 +95,8 @@ void HistogramController::reloadBannerView() { if (selectedSeriesIndex() < 0) { return; } - const size_t bufferSize = k_maxNumberOfCharacters + PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)*2; + constexpr int precision = Preferences::LargeNumberOfSignificantDigits; + constexpr size_t bufferSize = k_maxNumberOfCharacters + 2 * PrintFloat::bufferSizeForFloatsWithPrecision(precision); char buffer[bufferSize]; int numberOfChar = 0; @@ -107,7 +109,7 @@ void HistogramController::reloadBannerView() { // Add lower bound if (selectedSeriesIndex() >= 0) { double lowerBound = m_store->startOfBarAtIndex(selectedSeriesIndex(), *m_selectedBarIndex); - numberOfChar += PoincareHelpers::ConvertFloatToText(lowerBound, buffer+numberOfChar, bufferSize-numberOfChar, Constant::LargeNumberOfSignificantDigits); + numberOfChar += PoincareHelpers::ConvertFloatToText(lowerBound, buffer+numberOfChar, bufferSize-numberOfChar, precision); } numberOfChar+= UTF8Decoder::CodePointToChars(';', buffer + numberOfChar, bufferSize - numberOfChar); @@ -115,7 +117,7 @@ void HistogramController::reloadBannerView() { // Add upper bound if (selectedSeriesIndex() >= 0) { double upperBound = m_store->endOfBarAtIndex(selectedSeriesIndex(), *m_selectedBarIndex); - numberOfChar += PoincareHelpers::ConvertFloatToText(upperBound, buffer+numberOfChar, bufferSize-numberOfChar, Constant::LargeNumberOfSignificantDigits); + numberOfChar += PoincareHelpers::ConvertFloatToText(upperBound, buffer+numberOfChar, bufferSize-numberOfChar, precision); } numberOfChar+= UTF8Decoder::CodePointToChars('[', buffer + numberOfChar, bufferSize - numberOfChar); @@ -132,7 +134,7 @@ void HistogramController::reloadBannerView() { double size = 0; if (selectedSeriesIndex() >= 0) { size = m_store->heightOfBarAtIndex(selectedSeriesIndex(), *m_selectedBarIndex); - numberOfChar += PoincareHelpers::ConvertFloatToText(size, buffer+numberOfChar, bufferSize-numberOfChar, Constant::LargeNumberOfSignificantDigits); + numberOfChar += PoincareHelpers::ConvertFloatToText(size, buffer+numberOfChar, bufferSize-numberOfChar, precision); } // Padding Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, k_maxLegendLength); @@ -146,7 +148,7 @@ void HistogramController::reloadBannerView() { numberOfChar += legendLength; if (selectedSeriesIndex() >= 0) { double frequency = size/m_store->sumOfOccurrences(selectedSeriesIndex()); - numberOfChar += PoincareHelpers::ConvertFloatToText(frequency, buffer+numberOfChar, bufferSize - numberOfChar, Constant::LargeNumberOfSignificantDigits); + numberOfChar += PoincareHelpers::ConvertFloatToText(frequency, buffer+numberOfChar, bufferSize - numberOfChar, precision); } // Padding Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, k_maxLegendLength); diff --git a/apps/variable_box_controller.cpp b/apps/variable_box_controller.cpp index ff5ed82fb..eeb49a238 100644 --- a/apps/variable_box_controller.cpp +++ b/apps/variable_box_controller.cpp @@ -4,12 +4,12 @@ #include "shared/function.h" #include "shared/cartesian_function.h" #include "graph/cartesian_function_store.h" -#include "constant.h" #include -#include -#include -#include #include +#include +#include +#include +#include using namespace Poincare; using namespace Shared; @@ -236,7 +236,7 @@ Layout VariableBoxController::expressionLayoutForRecord(Storage::Record record, } assert(index >= m_firstMemoizedLayoutIndex && index < m_firstMemoizedLayoutIndex + k_maxNumberOfDisplayedRows); if (m_layouts[index-m_firstMemoizedLayoutIndex].isUninitialized()) { - m_layouts[index-m_firstMemoizedLayoutIndex] = GlobalContext::ExpressionFromRecord(record).createLayout(Poincare::Preferences::sharedPreferences()->displayMode(), Constant::ShortNumberOfSignificantDigits); + m_layouts[index-m_firstMemoizedLayoutIndex] = GlobalContext::ExpressionFromRecord(record).createLayout(Preferences::sharedPreferences()->displayMode(), Preferences::ShortNumberOfSignificantDigits); } return m_layouts[index-m_firstMemoizedLayoutIndex]; } diff --git a/poincare/Makefile b/poincare/Makefile index cfdb9cd63..345d01750 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -30,8 +30,10 @@ poincare_src += $(addprefix poincare/src/,\ poincare_src += $(addprefix poincare/src/,\ init.cpp \ + erf_inv.cpp \ exception_checkpoint.cpp \ helpers.cpp \ + normal_distribution.cpp \ ) poincare_src += $(addprefix poincare/src/,\ @@ -144,6 +146,7 @@ tests_src += $(addprefix poincare/test/,\ approximation.cpp\ arithmetic.cpp\ context.cpp\ + erf_inv.cpp \ expression.cpp\ expression_order.cpp\ expression_properties.cpp\ diff --git a/poincare/include/poincare/erf_inv.h b/poincare/include/poincare/erf_inv.h new file mode 100644 index 000000000..ae7e0fcc2 --- /dev/null +++ b/poincare/include/poincare/erf_inv.h @@ -0,0 +1,11 @@ +#ifndef POINCARE_ERFINV_H +#define POINCARE_ERFINV_H + +namespace Poincare { + +double erfInv(double y); + +} + +#endif + diff --git a/poincare/include/poincare/normal_distribution.h b/poincare/include/poincare/normal_distribution.h new file mode 100644 index 000000000..bf4517be1 --- /dev/null +++ b/poincare/include/poincare/normal_distribution.h @@ -0,0 +1,25 @@ +#ifndef POINCARE_NORMAL_DISTRIBUTION_H +#define POINCARE_NORMAL_DISTRIBUTION_H + +#include + +namespace Poincare { + +class NormalDistribution final { +public: + template static T EvaluateAtAbscissa(T x, T mu, T sigma); + template static T CumulativeDistributiveFunctionAtAbscissa(T x, T mu, T sigma); + static double CumulativeDistributiveInverseForProbability(double probability, float mu, float sigma); +private: + /* For the standard normal distribution, P(X < y) > 0.9999995 for y >= 4.892 so the + * value displayed is 1. But this is dependent on the fact that we display + * only 7 decimal values! */ + static_assert(Preferences::LargeNumberOfSignificantDigits == 7, "k_boundStandardNormalDistribution is ill-defined compared to LargeNumberOfSignificantDigits"); + constexpr static double k_boundStandardNormalDistribution = 4.892; + template static T StandardNormalCumulativeDistributiveFunctionAtAbscissa(T abscissa); + static double StandardNormalCumulativeDistributiveInverseForProbability(double probability); +}; + +} + +#endif diff --git a/poincare/include/poincare/preferences.h b/poincare/include/poincare/preferences.h index c4cb5991b..aa4f1cbb8 100644 --- a/poincare/include/poincare/preferences.h +++ b/poincare/include/poincare/preferences.h @@ -7,6 +7,10 @@ namespace Poincare { class Preferences final { public: + constexpr static int LargeNumberOfSignificantDigits = 7; + constexpr static int MediumNumberOfSignificantDigits = 5; + constexpr static int ShortNumberOfSignificantDigits = 4; + enum class EditionMode { Edition2D, Edition1D diff --git a/apps/probability/distribution/erf_inv.cpp b/poincare/src/erf_inv.cpp similarity index 98% rename from apps/probability/distribution/erf_inv.cpp rename to poincare/src/erf_inv.cpp index 67632fb63..63b0323ae 100644 --- a/apps/probability/distribution/erf_inv.cpp +++ b/poincare/src/erf_inv.cpp @@ -1,8 +1,9 @@ -#include "erf_inv.h" -#include "distribution.h" +#include #include #include +namespace Poincare { + /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -114,3 +115,5 @@ double erfInv(double x) { } return p * x; } + +} diff --git a/poincare/src/normal_distribution.cpp b/poincare/src/normal_distribution.cpp new file mode 100644 index 000000000..267ef8cd4 --- /dev/null +++ b/poincare/src/normal_distribution.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +namespace Poincare { + +template +T NormalDistribution::EvaluateAtAbscissa(T x, T mu, T sigma) { + assert(!std::isnan(x) && !std::isnan(mu) && !std::isnan(sigma)); + if (sigma == (T)0.0) { + return NAN; + } + const float xMinusMuOverSigma = (x - mu)/sigma; + return ((T)1.0)/(std::fabs(sigma) * std::sqrt(((T)2.0) * M_PI)) * std::exp(-((T)0.5) * xMinusMuOverSigma * xMinusMuOverSigma); +} + +template +T NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(T x, T mu, T sigma) { + if (sigma == (T)0.0) { + return NAN; + } + return StandardNormalCumulativeDistributiveFunctionAtAbscissa((x-mu)/std::fabs(sigma)); +} + +double NormalDistribution::CumulativeDistributiveInverseForProbability(double probability, float mu, float sigma) { + if (sigma == 0.0f) { + return NAN; + } + return StandardNormalCumulativeDistributiveInverseForProbability(probability) * std::fabs(sigma) + mu; +} + +template +T NormalDistribution::StandardNormalCumulativeDistributiveFunctionAtAbscissa(T abscissa) { + if (abscissa == (T)0.0) { + return (T)0.5; + } + if (abscissa < (T)0.0) { + return ((T)1.0) - StandardNormalCumulativeDistributiveFunctionAtAbscissa(-abscissa); + } + if (abscissa > k_boundStandardNormalDistribution) { + return (T)1.0; + } + return ((T)0.5) + ((T)0.5) * std::erf(abscissa/std::sqrt(((T)2.0))); +} + +double NormalDistribution::StandardNormalCumulativeDistributiveInverseForProbability(double probability) { + if (probability >= 1.0) { + return INFINITY; + } + if (probability <= 0.0) { + return -INFINITY; + } + if (probability < 0.5) { + return -StandardNormalCumulativeDistributiveInverseForProbability(1-probability); + } + return std::sqrt(2.0) * erfInv(2.0 * probability - 1.0); +} + +template float NormalDistribution::EvaluateAtAbscissa(float, float, float); +template double NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(double, double, double); +template float NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(float, float, float); + +} diff --git a/poincare/src/preferences.cpp b/poincare/src/preferences.cpp index 207dea71d..98b1e2982 100644 --- a/poincare/src/preferences.cpp +++ b/poincare/src/preferences.cpp @@ -3,14 +3,17 @@ namespace Poincare { +constexpr int Preferences::LargeNumberOfSignificantDigits; +constexpr int Preferences::MediumNumberOfSignificantDigits; +constexpr int Preferences::ShortNumberOfSignificantDigits; + Preferences::Preferences() : m_angleUnit(AngleUnit::Degree), m_displayMode(Preferences::PrintFloatMode::Decimal), m_editionMode(EditionMode::Edition2D), m_complexFormat(Preferences::ComplexFormat::Real), m_numberOfSignificantDigits(PrintFloat::k_numberOfPrintedSignificantDigits) -{ -} +{} Preferences * Preferences::sharedPreferences() { static Preferences preferences; diff --git a/apps/probability/test/erf_inv.cpp b/poincare/test/erf_inv.cpp similarity index 90% rename from apps/probability/test/erf_inv.cpp rename to poincare/test/erf_inv.cpp index 577f8fb61..8a70dce2e 100644 --- a/apps/probability/test/erf_inv.cpp +++ b/poincare/test/erf_inv.cpp @@ -1,9 +1,9 @@ #include -#include -#include +#include #include #include -#include "../distribution/erf_inv.h" + +using namespace Poincare; QUIZ_CASE(erf_inv) { quiz_assert(erfInv(0.0) == 0.0);