Merge changes I47c90687,I7cd19653,I4bd76f56,Ic2fb06ef

* changes:
  [liba] Add a constant representing the minimum float
  [apps] Sort out private and protected methods
  [apps] clean
  [apps/probability] Handle all edge cases
This commit is contained in:
Émilie Feral
2017-01-24 09:24:38 +01:00
committed by Gerrit
14 changed files with 114 additions and 51 deletions

View File

@@ -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

View File

@@ -8,7 +8,7 @@ public:
float x();
float y();
void moveTo(float x, float y);
protected:
private:
float m_x;
float m_y;
};

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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 {

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 {

View File

@@ -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));
}

View File

@@ -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;
};
}

View File

@@ -2,5 +2,6 @@
#define LIBA_FLOAT_H
#define FLT_MAX 1E+37f
#define FLT_MIN 1E-37f
#endif