diff --git a/apps/curve_view.h b/apps/curve_view.h index c34cd7809..d859b9547 100644 --- a/apps/curve_view.h +++ b/apps/curve_view.h @@ -26,21 +26,13 @@ public: protected: void setCurveViewRange(CurveViewRange * curveViewRange); - // Drawing methods constexpr static KDColor k_axisColor = KDColor::RGB24(0x000000); constexpr static KDColor k_gridColor = KDColor::RGB24(0xEEEEEE); constexpr static KDCoordinate k_labelMargin = 4; - constexpr static int k_maxNumberOfXLabels = 18; - constexpr static int k_maxNumberOfYLabels = 13; + constexpr static int k_maxNumberOfXLabels = CurveViewRange::k_maxNumberOfXGridUnits; + constexpr static int k_maxNumberOfYLabels = CurveViewRange::k_maxNumberOfYGridUnits; constexpr static KDCoordinate k_cursorSize = 9; - /* The window bounds are deduced from the model bounds but also take into - account a margin (computed with k_marginFactor) */ - float min(Axis axis) const; - float max(Axis axis) const; - float gridUnit(Axis axis) const; - virtual char * label(Axis axis, int index) const = 0; - KDCoordinate pixelLength(Axis axis) const; float pixelToFloat(Axis axis, KDCoordinate p) const; float floatToPixel(Axis axis, float f) const; void drawLine(KDContext * ctx, KDRect rect, Axis axis, @@ -60,6 +52,13 @@ protected: private: constexpr static int k_externRectMargin = 1; + /* The window bounds are deduced from the model bounds but also take into + account a margin (computed with k_marginFactor) */ + float min(Axis axis) const; + float max(Axis axis) const; + float gridUnit(Axis axis) const; + KDCoordinate pixelLength(Axis axis) const; + virtual char * label(Axis axis, int index) const = 0; int numberOfLabels(Axis axis) const; virtual float evaluateModelWithParameter(Model * curve, float t) const; /* Recursively join two dots (dichotomy). The method stops when the diff --git a/apps/curve_view_cursor.h b/apps/curve_view_cursor.h index d66139d30..fc384a55c 100644 --- a/apps/curve_view_cursor.h +++ b/apps/curve_view_cursor.h @@ -8,7 +8,7 @@ public: float x(); float y(); void moveTo(float x, float y); -protected: +private: float m_x; float m_y; }; diff --git a/apps/curve_view_range.h b/apps/curve_view_range.h index f2b8804d4..514af2a63 100644 --- a/apps/curve_view_range.h +++ b/apps/curve_view_range.h @@ -14,11 +14,11 @@ public: virtual float xGridUnit() = 0; virtual float yGridUnit(); float computeGridUnit(Axis axis, float min, float max); -protected: - constexpr static float k_minNumberOfXGridUnits = 7.0f; constexpr static float k_maxNumberOfXGridUnits = 18.0f; - constexpr static float k_minNumberOfYGridUnits = 5.0f; constexpr static float k_maxNumberOfYGridUnits = 13.0f; +private: + constexpr static float k_minNumberOfXGridUnits = 7.0f; + constexpr static float k_minNumberOfYGridUnits = 5.0f; constexpr static float k_oneUnit = 1.0f; constexpr static float k_twoUnit = 2.0f; constexpr static float k_fiveUnit = 5.0f; diff --git a/apps/editable_cell_table_view_controller.h b/apps/editable_cell_table_view_controller.h index 1b8a2a2aa..a7e098f88 100644 --- a/apps/editable_cell_table_view_controller.h +++ b/apps/editable_cell_table_view_controller.h @@ -21,13 +21,14 @@ public: void didBecomeFirstResponder() override; protected: + SelectableTableView m_selectableTableView; +private: static constexpr KDCoordinate k_cellHeight = 30; virtual bool cellAtLocationIsEditable(int columnIndex, int rowIndex) = 0; virtual void setDataAtLocation(float floatBody, int columnIndex, int rowIndex) = 0; virtual float dataAtLocation(int columnIndex, int rowIndex) = 0; virtual int numberOfElements() = 0; virtual int maxNumberOfElements() const = 0; - SelectableTableView m_selectableTableView; }; #endif diff --git a/apps/interactive_curve_view_range.cpp b/apps/interactive_curve_view_range.cpp index 7d10bc34a..a11759eb4 100644 --- a/apps/interactive_curve_view_range.cpp +++ b/apps/interactive_curve_view_range.cpp @@ -186,8 +186,8 @@ void InteractiveCurveViewRange::centerAxisAround(Axis axis, float position) { bool InteractiveCurveViewRange::moveCursorTo(float x, float y) { if (m_cursor) { m_cursor->moveTo(x, y); - float xMargin = InteractiveCurveViewRange::k_cursorMarginFactorToBorder * (m_xMax - m_xMin); - float yMargin = InteractiveCurveViewRange::k_cursorMarginFactorToBorder * (m_yMax - m_yMin); + float xMargin = k_cursorMarginFactorToBorder * (m_xMax - m_xMin); + float yMargin = k_cursorMarginFactorToBorder * (m_yMax - m_yMin); bool windowHasMoved = panToMakePointVisible(x, y, xMargin, yMargin); return windowHasMoved; } diff --git a/apps/interactive_curve_view_range.h b/apps/interactive_curve_view_range.h index cb6981626..42072b3ad 100644 --- a/apps/interactive_curve_view_range.h +++ b/apps/interactive_curve_view_range.h @@ -41,7 +41,6 @@ public: constexpr static float k_numberOfCursorStepsInGradUnit = 5.0f; protected: constexpr static float k_cursorMarginFactorToBorder = 0.025f; - bool panToMakePointVisible(float x, float y, float xMargin, float yMargin); // Window bounds of the data float m_xMin; float m_xMax; @@ -50,6 +49,8 @@ protected: bool m_yAuto; float m_xGridUnit; float m_yGridUnit; +private: + bool panToMakePointVisible(float x, float y, float xMargin, float yMargin); CurveViewCursor * m_cursor; InteractiveCurveViewRangeDelegate * m_delegate; }; diff --git a/apps/probability/law/binomial_law.cpp b/apps/probability/law/binomial_law.cpp index e50b36feb..26388de0a 100644 --- a/apps/probability/law/binomial_law.cpp +++ b/apps/probability/law/binomial_law.cpp @@ -44,7 +44,11 @@ float BinomialLaw::xMin() { } float BinomialLaw::xMax() { - return ceilf(m_parameter1*m_parameter2+5.0f*sqrtf(m_parameter1*m_parameter2*(1-m_parameter2))); + float result = ceilf(m_parameter1*m_parameter2+5.0f*sqrtf(m_parameter1*m_parameter2*(1-m_parameter2))); + if (result <= xMin()) { + result = xMin() + 1.0f; + } + return result; } float BinomialLaw::yMin() { @@ -54,15 +58,21 @@ float BinomialLaw::yMin() { float BinomialLaw::yMax() { int maxAbscissa = m_parameter2 < 1.0f ? (m_parameter1+1)*m_parameter2 : m_parameter1; float result = evaluateAtAbscissa(maxAbscissa); - if (result <= 0.0f || result == yMin() || isnan(result)) { + if (result <= yMin() || isnan(result)) { result = yMin() + 1.0f; } return result; } float BinomialLaw::evaluateAtAbscissa(float x) const { - if (m_parameter1 == 0.0f && (m_parameter2 == 0.0f || m_parameter2 == 1.0f)) { - return NAN; + if (m_parameter1 == 0.0f) { + if (m_parameter2 == 0.0f || m_parameter2 == 1.0f) { + return NAN; + } + if ((int)x == 0) { + return 1.0f; + } + return 0.0f; } if (m_parameter2 == 1.0f) { if ((int)x == m_parameter1) { @@ -70,6 +80,12 @@ float BinomialLaw::evaluateAtAbscissa(float x) const { } return 0.0f; } + if (m_parameter2 == 0.0f) { + if ((int)x == 0) { + return 1.0f; + } + return 0.0f; + } if (x > m_parameter1) { return 0.0f; } @@ -92,6 +108,9 @@ bool BinomialLaw::authorizedValueAtIndex(float x, int index) const { } float BinomialLaw::cumulativeDistributiveInverseForProbability(float * probability) { + if (m_parameter1 == 0.0f && (m_parameter2 == 0.0f || m_parameter2 == 1.0f)) { + return NAN; + } if (*probability >= 1.0f) { return m_parameter1; } @@ -99,6 +118,9 @@ float BinomialLaw::cumulativeDistributiveInverseForProbability(float * probabili } float BinomialLaw::rightIntegralInverseForProbability(float * probability) { + if (m_parameter1 == 0.0f && (m_parameter2 == 0.0f || m_parameter2 == 1.0f)) { + return NAN; + } if (*probability <= 0.0f) { return m_parameter1; } diff --git a/apps/probability/law/exponential_law.cpp b/apps/probability/law/exponential_law.cpp index c34eba7bf..f9eb19096 100644 --- a/apps/probability/law/exponential_law.cpp +++ b/apps/probability/law/exponential_law.cpp @@ -38,7 +38,11 @@ float ExponentialLaw::xMin() { float ExponentialLaw::xMax() { assert(m_parameter1 != 0.0f); - return 5.0f/m_parameter1; + float result = 5.0f/m_parameter1; + if (result <= xMin()) { + result = xMin() + 1.0f; + } + return result; } float ExponentialLaw::yMin() { @@ -46,7 +50,11 @@ float ExponentialLaw::yMin() { } float ExponentialLaw::yMax() { - return m_parameter1; + float result = m_parameter1; + if (result <= yMin()) { + result = yMin() + 1.0f; + } + return result; } float ExponentialLaw::evaluateAtAbscissa(float x) const { diff --git a/apps/probability/law/law.cpp b/apps/probability/law/law.cpp index 2f503a49a..7a82f103d 100644 --- a/apps/probability/law/law.cpp +++ b/apps/probability/law/law.cpp @@ -10,7 +10,7 @@ float Law::xGridUnit() { float Law::cumulativeDistributiveFunctionAtAbscissa(float x) const { if (!isContinuous()) { - int end = x; + int end = floorf(x); float result = 0.0f; for (int k = 0; k <=end; k++) { result += evaluateAtAbscissa(k); @@ -21,19 +21,14 @@ float Law::cumulativeDistributiveFunctionAtAbscissa(float x) const { } float Law::rightIntegralFromAbscissa(float x) const { - if (isContinuous()) { - return 1.0f - cumulativeDistributiveFunctionAtAbscissa(x); - } - int start = ceilf(x); - return 1.0f - cumulativeDistributiveFunctionAtAbscissa(start - 1); + return 1.0f - cumulativeDistributiveFunctionAtAbscissa(x); } float Law::finiteIntegralBetweenAbscissas(float a, float b) const { if (b < a) { return 0.0f; } - if (isContinuous()) - { + if (isContinuous()) { return cumulativeDistributiveFunctionAtAbscissa(b) - cumulativeDistributiveFunctionAtAbscissa(a); } int start = ceilf(a); @@ -49,23 +44,26 @@ float Law::cumulativeDistributiveInverseForProbability(float * probability) { if (*probability >= 1.0f) { return INFINITY; } - if (!isContinuous()) { - if (*probability <= 0.0f) { - return 0.0f; - } - float p = 0.0f; - int k = 0; - while (p < *probability && k < k_maxNumberOfOperations) { - p += evaluateAtAbscissa(k++); - } - if (k == k_maxNumberOfOperations) { - p = 1.0f; - k = INFINITY; - } - *probability = p; - return k-1; + if (isContinuous()) { + return 0.0f; } - return 0.0f; + if (*probability <= 0.0f) { + return 0.0f; + } + float p = 0.0f; + int k = 0; + while (p < *probability && k < k_maxNumberOfOperations) { + p += evaluateAtAbscissa(k++); + } + if (k == k_maxNumberOfOperations) { + p = 1.0f; + k = INFINITY; + } + *probability = p; + if (isnan(*probability)) { + return NAN; + } + return k-1; } float Law::rightIntegralInverseForProbability(float * probability) { @@ -89,6 +87,9 @@ float Law::rightIntegralInverseForProbability(float * probability) { k = INFINITY; } *probability = 1.0f - (p - evaluateAtAbscissa(k-1)); + if (isnan(*probability)) { + return NAN; + } return k-1; } diff --git a/apps/probability/law/normal_law.cpp b/apps/probability/law/normal_law.cpp index 6103ba48d..554ab8cc5 100644 --- a/apps/probability/law/normal_law.cpp +++ b/apps/probability/law/normal_law.cpp @@ -61,7 +61,7 @@ float NormalLaw::yMin() { float NormalLaw::yMax() { float maxAbscissa = m_parameter1; float result = evaluateAtAbscissa(maxAbscissa); - if (result <= 0.0f || result == yMin()) { + if (isnan(result) || result == yMin()) { result = yMin() + 1.0f; } return result; @@ -79,10 +79,16 @@ bool NormalLaw::authorizedValueAtIndex(float x, int index) const { } float NormalLaw::cumulativeDistributiveFunctionAtAbscissa(float x) const { + if (m_parameter2 == 0.0f) { + return NAN; + } return standardNormalCumulativeDistributiveFunctionAtAbscissa((x-m_parameter1)/fabsf(m_parameter2)); } float NormalLaw::cumulativeDistributiveInverseForProbability(float * probability) { + if (m_parameter2 == 0.0f) { + return NAN; + } return standardNormalCumulativeDistributiveInverseForProbability(*probability)*fabsf(m_parameter2) + m_parameter1; } diff --git a/apps/probability/law/poisson_law.cpp b/apps/probability/law/poisson_law.cpp index 17483d2b9..fa611a1b9 100644 --- a/apps/probability/law/poisson_law.cpp +++ b/apps/probability/law/poisson_law.cpp @@ -46,7 +46,12 @@ float PoissonLaw::yMin() { float PoissonLaw::yMax() { int maxAbscissa = (int)m_parameter1; - return evaluateAtAbscissa(maxAbscissa); + assert(maxAbscissa >= 0.0f); + float result = evaluateAtAbscissa(maxAbscissa); + if (result <= yMin()) { + result = yMin() + 1.0f; + } + return result; } float PoissonLaw::evaluateAtAbscissa(float x) const { diff --git a/apps/probability/law/uniform_law.cpp b/apps/probability/law/uniform_law.cpp index a80df4c81..88b6a2e09 100644 --- a/apps/probability/law/uniform_law.cpp +++ b/apps/probability/law/uniform_law.cpp @@ -40,10 +40,16 @@ const char * UniformLaw::parameterDefinitionAtIndex(int index) { float UniformLaw::xMin() { assert(m_parameter2 >= m_parameter1); + if (m_parameter1 == m_parameter2) { + return m_parameter1 - 1.0f; + } return m_parameter1 - 0.6f*(m_parameter2 - m_parameter1); } float UniformLaw::xMax() { + if (m_parameter1 == m_parameter2) { + return m_parameter1 + 1.0f; + } return m_parameter2 + 0.6f*(m_parameter2 - m_parameter1); } @@ -52,10 +58,20 @@ float UniformLaw::yMin() { } float UniformLaw::yMax() { - return (1.0f/(m_parameter2-m_parameter1)); + float result = m_parameter1 == m_parameter2 ? k_diracMaximum : 1.0f/(m_parameter2-m_parameter1); + if (result <= yMin()) { + result = yMin() + 1.0f; + } + return result; } float UniformLaw::evaluateAtAbscissa(float t) const { + if (m_parameter1 == m_parameter2) { + if (m_parameter1 - k_diracWidth<= t && t <= m_parameter2 + k_diracWidth) { + return 2.0f*k_diracMaximum; + } + return 0.0f; + } if (m_parameter1 <= t && t <= m_parameter2) { return (1.0f/(m_parameter2-m_parameter1)); } diff --git a/apps/probability/law/uniform_law.h b/apps/probability/law/uniform_law.h index db760fe0b..e07148282 100644 --- a/apps/probability/law/uniform_law.h +++ b/apps/probability/law/uniform_law.h @@ -22,6 +22,9 @@ public: bool authorizedValueAtIndex(float x, int index) const override; float cumulativeDistributiveFunctionAtAbscissa(float x) const override; float cumulativeDistributiveInverseForProbability(float * probability) override; +private: + constexpr static float k_diracMaximum = 10.0f; + constexpr static float k_diracWidth = 0.001f; }; } diff --git a/liba/include/float.h b/liba/include/float.h index d0485dc26..40bb24c08 100644 --- a/liba/include/float.h +++ b/liba/include/float.h @@ -2,5 +2,6 @@ #define LIBA_FLOAT_H #define FLT_MAX 1E+37f +#define FLT_MIN 1E-37f #endif