mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
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:
@@ -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
|
||||
|
||||
@@ -8,7 +8,7 @@ public:
|
||||
float x();
|
||||
float y();
|
||||
void moveTo(float x, float y);
|
||||
protected:
|
||||
private:
|
||||
float m_x;
|
||||
float m_y;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
#define LIBA_FLOAT_H
|
||||
|
||||
#define FLT_MAX 1E+37f
|
||||
#define FLT_MIN 1E-37f
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user