mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-19 05:40:38 +01:00
[apps/probability] Make law model an abstract class with inheritance for
all specific laws (binomial...) Change-Id: Ida6d5bfb7a3fbfc288393cd2f7e9e9b934798073
This commit is contained in:
@@ -1,13 +1,21 @@
|
||||
app_objs += $(addprefix apps/probability/,\
|
||||
app.o\
|
||||
binomial_law.o\
|
||||
calculation.o\
|
||||
calculation_controller.o\
|
||||
cell.o\
|
||||
evaluate_context.o\
|
||||
exponential_law.o\
|
||||
image_table_view.o\
|
||||
law.o\
|
||||
law_controller.o\
|
||||
law_curve_view.o\
|
||||
normal_law.o\
|
||||
one_parameter_law.o\
|
||||
parameters_controller.o\
|
||||
poisson_law.o\
|
||||
two_parameter_law.o\
|
||||
uniform_law.o\
|
||||
)
|
||||
|
||||
app_images += $(addprefix apps/probability/images/,\
|
||||
|
||||
71
apps/probability/binomial_law.cpp
Normal file
71
apps/probability/binomial_law.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#include "binomial_law.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace Probability {
|
||||
|
||||
BinomialLaw::BinomialLaw(EvaluateContext * evaluateContext) :
|
||||
TwoParameterLaw(evaluateContext),
|
||||
m_expression(Expression::parse("p1-p2*t"))
|
||||
{
|
||||
//m_expression = Expression::parse("binomial(p1, p2)*p2^t*(1-p2)^(p1-t)");
|
||||
assert(m_expression != nullptr);
|
||||
}
|
||||
|
||||
BinomialLaw::~BinomialLaw() {
|
||||
delete m_expression;
|
||||
}
|
||||
|
||||
const char * BinomialLaw::title() {
|
||||
return "Loi binomiale";
|
||||
}
|
||||
|
||||
Expression * BinomialLaw::expression() const {
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
Law::Type BinomialLaw::type() const {
|
||||
return Type::Binomial;
|
||||
}
|
||||
|
||||
bool BinomialLaw::isContinuous() {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char * BinomialLaw::parameterNameAtIndex(int index) {
|
||||
assert(index >= 0 && index < 2);
|
||||
if (index == 0) {
|
||||
return "n";
|
||||
} else {
|
||||
return "p";
|
||||
}
|
||||
}
|
||||
|
||||
const char * BinomialLaw::parameterDefinitionAtIndex(int index) {
|
||||
assert(index >= 0 && index < 2);
|
||||
if (index == 0) {
|
||||
return "n : nombre de repetitions";
|
||||
} else {
|
||||
return "p : probabilites de succes";
|
||||
}
|
||||
}
|
||||
|
||||
float BinomialLaw::xMin() {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float BinomialLaw::xMax() {
|
||||
if (m_parameter1 == 0) {
|
||||
return 1.0f;
|
||||
}
|
||||
return m_parameter1;
|
||||
}
|
||||
|
||||
float BinomialLaw::yMin() {
|
||||
return -0.2f;
|
||||
}
|
||||
|
||||
float BinomialLaw::yMax() {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
29
apps/probability/binomial_law.h
Normal file
29
apps/probability/binomial_law.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef PROBABILITE_BINOMIAL_LAW_H
|
||||
#define PROBABILITE_BINOMIAL_LAW_H
|
||||
|
||||
#include "evaluate_context.h"
|
||||
#include "two_parameter_law.h"
|
||||
|
||||
namespace Probability {
|
||||
|
||||
class BinomialLaw : public TwoParameterLaw {
|
||||
public:
|
||||
BinomialLaw(EvaluateContext * evaluateContext);
|
||||
~BinomialLaw() override;
|
||||
const char * title() override;
|
||||
Expression * expression() const override;
|
||||
Type type() const override;
|
||||
bool isContinuous() override;
|
||||
float xMin() override;
|
||||
float yMin() override;
|
||||
float xMax() override;
|
||||
float yMax() override;
|
||||
const char * parameterNameAtIndex(int index) override;
|
||||
const char * parameterDefinitionAtIndex(int index) override;
|
||||
private:
|
||||
Expression * m_expression;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
97
apps/probability/calculation.cpp
Normal file
97
apps/probability/calculation.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "calculation.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
namespace Probability {
|
||||
|
||||
Calculation::Calculation():
|
||||
m_type(LeftIntegral),
|
||||
m_parameter1(0.0f),
|
||||
m_parameter2(0.0f),
|
||||
m_parameter3(0.0f),
|
||||
m_law(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void Calculation::setLaw(Law * law) {
|
||||
m_law = law;
|
||||
computeCalculation(0);
|
||||
}
|
||||
|
||||
void Calculation::setType(Type type) {
|
||||
m_type = type;
|
||||
initParameters();
|
||||
}
|
||||
|
||||
Calculation::Type Calculation::type() const {
|
||||
return m_type;
|
||||
}
|
||||
|
||||
float Calculation::parameterAtIndex(int index) {
|
||||
if (index == 0) {
|
||||
return m_parameter1;
|
||||
}
|
||||
if (index == 1) {
|
||||
return m_parameter2;
|
||||
}
|
||||
return m_parameter3;
|
||||
}
|
||||
|
||||
void Calculation::setParameterAtIndex(float f, int index) {
|
||||
if (index == 0) {
|
||||
m_parameter1 = f;
|
||||
}
|
||||
if (index == 1) {
|
||||
m_parameter2 = f;
|
||||
}
|
||||
if (index == 2) {
|
||||
m_parameter3 = f;
|
||||
}
|
||||
computeCalculation(index);
|
||||
}
|
||||
|
||||
void Calculation::computeCalculation(int indexKnownElement) {
|
||||
if (m_law == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (m_type == LeftIntegral) {
|
||||
if (indexKnownElement == 0) {
|
||||
// TODO: compute integral from -Inf to m_parameter1
|
||||
m_parameter2 = m_law->evaluateAtAbscissa(m_parameter1);
|
||||
} else {
|
||||
// TODO: find m_parameter1
|
||||
m_parameter1 = m_law->evaluateAtAbscissa(m_parameter2);
|
||||
}
|
||||
}
|
||||
if (m_type == FiniteIntegral) {
|
||||
// TODO: compute integral from m_parameter1 to m_parameter2
|
||||
m_parameter3 = m_law->evaluateAtAbscissa(m_parameter1 + m_parameter2);
|
||||
}
|
||||
if (m_type == RightIntegral) {
|
||||
if (indexKnownElement == 0) {
|
||||
// TODO: compute integral from m_parameter1 to +Inf
|
||||
m_parameter2 = m_law->evaluateAtAbscissa(m_parameter1);
|
||||
} else {
|
||||
// TODO: find m_parameter1
|
||||
m_parameter1 = m_law->evaluateAtAbscissa(m_parameter2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Calculation::initParameters() {
|
||||
if (m_type == LeftIntegral) {
|
||||
m_parameter1 = 0.0f;
|
||||
computeCalculation(0);
|
||||
}
|
||||
if (m_type == FiniteIntegral) {
|
||||
m_parameter1 = -1.0f;
|
||||
m_parameter2 = 1.0f;
|
||||
computeCalculation(0);
|
||||
}
|
||||
if (m_type == RightIntegral) {
|
||||
m_parameter1 = 0.0f;
|
||||
computeCalculation(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
34
apps/probability/calculation.h
Normal file
34
apps/probability/calculation.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef PROBABILITE_CALCULATION_H
|
||||
#define PROBABILITE_CALCULATION_H
|
||||
|
||||
#include "evaluate_context.h"
|
||||
#include "law.h"
|
||||
|
||||
namespace Probability {
|
||||
|
||||
class Calculation {
|
||||
public:
|
||||
enum Type : uint8_t {
|
||||
LeftIntegral = 0,
|
||||
FiniteIntegral = 1,
|
||||
RightIntegral = 2,
|
||||
};
|
||||
Calculation();
|
||||
void setLaw(Law * law);
|
||||
void setType(Type type);
|
||||
Type type() const;
|
||||
float parameterAtIndex(int index);
|
||||
void setParameterAtIndex(float f, int index);
|
||||
private:
|
||||
void computeCalculation(int indexKnownElement);
|
||||
void initParameters();
|
||||
Type m_type;
|
||||
float m_parameter1;
|
||||
float m_parameter2;
|
||||
float m_parameter3;
|
||||
Law * m_law;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
namespace Probability {
|
||||
|
||||
CalculationController::ContentView::ContentView(Responder * parentResponder, Law * law) :
|
||||
m_lawCurveView(LawCurveView(law)),
|
||||
m_imageTableView(ImageTableView(parentResponder, law)),
|
||||
m_law(law)
|
||||
CalculationController::ContentView::ContentView(Responder * parentResponder,Calculation * calculation) :
|
||||
m_lawCurveView(LawCurveView()),
|
||||
m_imageTableView(ImageTableView(parentResponder, calculation)),
|
||||
m_calculation(calculation)
|
||||
{
|
||||
for (int k = 0; k < k_maxNumberOfEditableFields; k++) {
|
||||
m_calculationCell[k].setParentResponder(parentResponder);
|
||||
@@ -17,8 +17,12 @@ CalculationController::ContentView::ContentView(Responder * parentResponder, Law
|
||||
}
|
||||
}
|
||||
|
||||
void CalculationController::ContentView::setLaw(Law * law) {
|
||||
m_lawCurveView.setLaw(law);
|
||||
}
|
||||
|
||||
int CalculationController::ContentView::numberOfSubviews() const {
|
||||
if ((int)m_law->calculationType() == 1) {
|
||||
if ((int)m_calculation->type() == 1) {
|
||||
return 8;
|
||||
}
|
||||
return 6;
|
||||
@@ -33,7 +37,7 @@ View * CalculationController::ContentView::subviewAtIndex(int index) {
|
||||
return &m_imageTableView;
|
||||
}
|
||||
if (index == 2) {
|
||||
if ((int)m_law->calculationType() == 0) {
|
||||
if ((int)m_calculation->type() == 0) {
|
||||
m_text[0].setText("P(X <= ");
|
||||
} else {
|
||||
m_text[0].setText("P( ");
|
||||
@@ -42,13 +46,13 @@ View * CalculationController::ContentView::subviewAtIndex(int index) {
|
||||
return &m_text[0];
|
||||
}
|
||||
if (index == 4) {
|
||||
if ((int)m_law->calculationType() == 0) {
|
||||
if (m_calculation->type() == Calculation::Type::LeftIntegral) {
|
||||
m_text[1].setText(") = ");
|
||||
}
|
||||
if ((int)m_law->calculationType() == 1) {
|
||||
if (m_calculation->type() == Calculation::Type::FiniteIntegral) {
|
||||
m_text[1].setText(" <= X <= ");
|
||||
}
|
||||
if ((int)m_law->calculationType() == 2) {
|
||||
if (m_calculation->type() == Calculation::Type::RightIntegral) {
|
||||
m_text[1].setText(" <= X ) = ");
|
||||
}
|
||||
m_text[1].setAlignment(0.5f, 0.5f);
|
||||
@@ -67,7 +71,7 @@ View * CalculationController::ContentView::subviewAtIndex(int index) {
|
||||
|
||||
void CalculationController::ContentView::willDisplayEditableCellAtIndex(int index) {
|
||||
char buffer[Constant::FloatBufferSizeInScientificMode];
|
||||
Float(m_law->calculationElementAtIndex(index)).convertFloatToText(buffer, Constant::FloatBufferSizeInScientificMode, Constant::NumberOfDigitsInMantissaInScientificMode);
|
||||
Float(m_calculation->parameterAtIndex(index)).convertFloatToText(buffer, Constant::FloatBufferSizeInScientificMode, Constant::NumberOfDigitsInMantissaInScientificMode);
|
||||
m_calculationCell[index].setText(buffer);
|
||||
}
|
||||
|
||||
@@ -78,20 +82,20 @@ void CalculationController::ContentView::layoutSubviews() {
|
||||
m_imageTableView.setFrame(KDRect(xCoordinate, 0, ImageTableView::k_imageWidth, 3*ImageTableView::k_imageHeight));
|
||||
xCoordinate += ImageTableView::k_imageWidth + k_textMargin;
|
||||
KDCoordinate numberOfCharacters = 7;
|
||||
if ((int)m_law->calculationType() > 0) {
|
||||
if ((int)m_calculation->type() > 0) {
|
||||
numberOfCharacters = 3;
|
||||
}
|
||||
m_text[0].setFrame(KDRect(xCoordinate, 0, numberOfCharacters*k_charWidth, ImageTableView::k_imageHeight));
|
||||
xCoordinate += numberOfCharacters*k_charWidth + k_textMargin;
|
||||
m_calculationCell[0].setFrame(KDRect(xCoordinate, 0, k_textFieldWidth, ImageTableView::k_imageHeight));
|
||||
xCoordinate += k_textFieldWidth + k_textMargin;
|
||||
if ((int)m_law->calculationType() == 0) {
|
||||
if (m_calculation->type() == Calculation::Type::LeftIntegral) {
|
||||
numberOfCharacters = 4;
|
||||
}
|
||||
if ((int)m_law->calculationType() == 1) {
|
||||
if (m_calculation->type() == Calculation::Type::FiniteIntegral) {
|
||||
numberOfCharacters = 9;
|
||||
}
|
||||
if ((int)m_law->calculationType() == 2) {
|
||||
if (m_calculation->type() == Calculation::Type::RightIntegral) {
|
||||
numberOfCharacters = 10;
|
||||
}
|
||||
m_text[1].setFrame(KDRect(xCoordinate, 0, numberOfCharacters*k_charWidth, ImageTableView::k_imageHeight));
|
||||
@@ -125,11 +129,11 @@ EditableTextCell * CalculationController::ContentView::calculationCellAtIndex(in
|
||||
return &m_calculationCell[index];
|
||||
}
|
||||
|
||||
CalculationController::CalculationController(Responder * parentResponder, Law * law) :
|
||||
CalculationController::CalculationController(Responder * parentResponder) :
|
||||
ViewController(parentResponder),
|
||||
m_contentView(ContentView(this, law)),
|
||||
m_contentView(ContentView(this, &m_calculation)),
|
||||
m_highlightedSubviewIndex(1),
|
||||
m_law(law)
|
||||
m_calculation(Calculation())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -141,6 +145,15 @@ const char * CalculationController::title() const {
|
||||
return "Calculer les probabilites";
|
||||
}
|
||||
|
||||
void CalculationController::setLaw(Law * law) {
|
||||
m_contentView.setLaw(law);
|
||||
m_calculation.setLaw(law);
|
||||
}
|
||||
|
||||
Calculation * CalculationController::calculation() {
|
||||
return &m_calculation;
|
||||
}
|
||||
|
||||
bool CalculationController::handleEvent(Ion::Events::Event event) {
|
||||
|
||||
if ((event == Ion::Events::Left && m_highlightedSubviewIndex > 0) || (event == Ion::Events::Right && m_highlightedSubviewIndex < ContentView::k_maxNumberOfEditableFields - 1)) {
|
||||
@@ -181,7 +194,7 @@ bool CalculationController::textFieldDidFinishEditing(TextField * textField, con
|
||||
AppsContainer * appsContainer = (AppsContainer *)app()->container();
|
||||
Context * globalContext = appsContainer->context();
|
||||
float floatBody = Expression::parse(text)->approximate(*globalContext);
|
||||
m_law->setCalculationElementAtIndex(floatBody, m_highlightedSubviewIndex-1);
|
||||
m_calculation.setParameterAtIndex(floatBody, m_highlightedSubviewIndex-1);
|
||||
for (int k = 0; k < ContentView::k_maxNumberOfEditableFields; k++) {
|
||||
m_contentView.willDisplayEditableCellAtIndex(k);
|
||||
}
|
||||
@@ -205,10 +218,6 @@ void CalculationController::didBecomeFirstResponder() {
|
||||
m_contentView.lawCurveView()->reload();
|
||||
}
|
||||
|
||||
Law * CalculationController::law() {
|
||||
return m_law;
|
||||
}
|
||||
|
||||
void CalculationController::selectSubview(int subviewIndex) {
|
||||
m_highlightedSubviewIndex = subviewIndex;
|
||||
}
|
||||
|
||||
@@ -10,19 +10,21 @@ namespace Probability {
|
||||
|
||||
class CalculationController : public ViewController, public TextFieldDelegate {
|
||||
public:
|
||||
CalculationController(Responder * parentResponder, Law * law);
|
||||
CalculationController(Responder * parentResponder);
|
||||
View * view() override;
|
||||
const char * title() const override;
|
||||
void setLaw(Law * law);
|
||||
Calculation * calculation();
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
void didBecomeFirstResponder() override;
|
||||
Law * law();
|
||||
void selectSubview(int subviewIndex);
|
||||
bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
|
||||
bool textFieldDidFinishEditing(TextField * textField, const char * text) override;
|
||||
private:
|
||||
class ContentView : public View {
|
||||
public:
|
||||
ContentView(Responder * parentResponder, Law * law);
|
||||
ContentView(Responder * parentResponder, Calculation * Calculation);
|
||||
void setLaw(Law * law);
|
||||
void layoutSubviews() override;
|
||||
void drawRect(KDContext * ctx, KDRect rect) const override;
|
||||
LawCurveView * lawCurveView();
|
||||
@@ -40,11 +42,11 @@ private:
|
||||
ImageTableView m_imageTableView;
|
||||
PointerTextView m_text[k_maxNumberOfEditableFields];
|
||||
EditableTextCell m_calculationCell[k_maxNumberOfEditableFields];
|
||||
Law * m_law;
|
||||
Calculation * m_calculation;
|
||||
};
|
||||
ContentView m_contentView;
|
||||
int m_highlightedSubviewIndex;
|
||||
Law * m_law;
|
||||
Calculation m_calculation;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
63
apps/probability/exponential_law.cpp
Normal file
63
apps/probability/exponential_law.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "exponential_law.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace Probability {
|
||||
|
||||
ExponentialLaw::ExponentialLaw(EvaluateContext * evaluateContext) :
|
||||
OneParameterLaw(evaluateContext),
|
||||
m_expression(Expression::parse("p1*t"))
|
||||
{
|
||||
//m_expression = Expression::parse("p1*exp(-p1*t)");
|
||||
assert(m_expression != nullptr);
|
||||
}
|
||||
|
||||
ExponentialLaw::~ExponentialLaw() {
|
||||
delete m_expression;
|
||||
}
|
||||
|
||||
const char * ExponentialLaw::title() {
|
||||
return "Loi exponentielle";
|
||||
}
|
||||
|
||||
Expression * ExponentialLaw::expression() const {
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
Law::Type ExponentialLaw::type() const {
|
||||
return Type::Exponential;
|
||||
}
|
||||
|
||||
bool ExponentialLaw::isContinuous() {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char * ExponentialLaw::parameterNameAtIndex(int index) {
|
||||
assert(index == 0);
|
||||
return "l";
|
||||
}
|
||||
|
||||
const char * ExponentialLaw::parameterDefinitionAtIndex(int index) {
|
||||
assert(index == 0);
|
||||
return "l : parametre";
|
||||
}
|
||||
|
||||
float ExponentialLaw::xMin() {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float ExponentialLaw::xMax() {
|
||||
if (m_parameter1 == 0.0f) {
|
||||
return 100.0f;
|
||||
}
|
||||
return 5.0f/m_parameter1;
|
||||
}
|
||||
|
||||
float ExponentialLaw::yMin() {
|
||||
return -0.2f;
|
||||
}
|
||||
|
||||
float ExponentialLaw::yMax() {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
29
apps/probability/exponential_law.h
Normal file
29
apps/probability/exponential_law.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef PROBABILITE_EXPONENTIAL_LAW_H
|
||||
#define PROBABILITE_EXPONENTIAL_LAW_H
|
||||
|
||||
#include "evaluate_context.h"
|
||||
#include "one_parameter_law.h"
|
||||
|
||||
namespace Probability {
|
||||
|
||||
class ExponentialLaw : public OneParameterLaw {
|
||||
public:
|
||||
ExponentialLaw(EvaluateContext * evaluateContext);
|
||||
~ExponentialLaw() override;
|
||||
const char * title() override;
|
||||
Expression * expression() const override;
|
||||
Type type() const override;
|
||||
bool isContinuous() override;
|
||||
float xMin() override;
|
||||
float yMin() override;
|
||||
float xMax() override;
|
||||
float yMax() override;
|
||||
const char * parameterNameAtIndex(int index) override;
|
||||
const char * parameterDefinitionAtIndex(int index) override;
|
||||
private:
|
||||
Expression * m_expression;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -42,12 +42,12 @@ void ImageTableView::ImageCell::setImage(const Image * image, const Image * focu
|
||||
m_focusedIcon = focusedImage;
|
||||
}
|
||||
|
||||
ImageTableView::ImageTableView(Responder * parentResponder, Law * law) :
|
||||
ImageTableView::ImageTableView(Responder * parentResponder, Calculation * calculation) :
|
||||
View(),
|
||||
Responder(parentResponder),
|
||||
m_selectableTableView(SelectableTableView(this, this, 0, 0, 0, 0, nullptr, false, false)),
|
||||
m_isSelected(false),
|
||||
m_law(law)
|
||||
m_calculation(calculation)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ void ImageTableView::didBecomeFirstResponder() {
|
||||
|
||||
bool ImageTableView::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::OK) {
|
||||
m_law->setCalculationType((Law::CalculationType)m_selectableTableView.selectedRow());
|
||||
m_calculation->setType((Calculation::Type)m_selectableTableView.selectedRow());
|
||||
select(false);
|
||||
setHighlight(true);
|
||||
m_selectableTableView.reloadData();
|
||||
@@ -79,7 +79,7 @@ void ImageTableView::select(bool select) {
|
||||
m_isSelected = select;
|
||||
} else {
|
||||
m_isSelected = select;
|
||||
m_selectableTableView.selectCellAtLocation(0, m_law->calculationType());
|
||||
m_selectableTableView.selectCellAtLocation(0, m_calculation->type());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,34 +110,12 @@ int ImageTableView::reusableCellCount() {
|
||||
|
||||
void ImageTableView::willDisplayCellForIndex(TableViewCell * cell, int index) {
|
||||
ImageCell * myCell = (ImageCell *)cell;
|
||||
const Image * images[3] = {ImageStore::Calcul1Icon, ImageStore::Calcul2Icon, ImageStore::Calcul3Icon};
|
||||
const Image * focusedImages[3] = {ImageStore::FocusedCalcul1Icon, ImageStore::FocusedCalcul2Icon, ImageStore::FocusedCalcul3Icon};
|
||||
if (!m_isSelected) {
|
||||
switch (m_law->calculationType()) {
|
||||
case 0:
|
||||
myCell->setImage(ImageStore::Calcul1Icon, ImageStore::FocusedCalcul1Icon);
|
||||
break;
|
||||
case 1:
|
||||
myCell->setImage(ImageStore::Calcul2Icon, ImageStore::FocusedCalcul2Icon);
|
||||
break;
|
||||
case 2:
|
||||
myCell->setImage(ImageStore::Calcul3Icon, ImageStore::FocusedCalcul3Icon);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
myCell->setImage(images[m_calculation->type()], focusedImages[m_calculation->type()]);
|
||||
} else {
|
||||
switch (index) {
|
||||
case 0:
|
||||
myCell->setImage(ImageStore::Calcul1Icon, ImageStore::FocusedCalcul1Icon);
|
||||
break;
|
||||
case 1:
|
||||
myCell->setImage(ImageStore::Calcul2Icon, ImageStore::FocusedCalcul2Icon);
|
||||
break;
|
||||
case 2:
|
||||
myCell->setImage(ImageStore::Calcul3Icon, ImageStore::FocusedCalcul3Icon);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
myCell->setImage(images[index], focusedImages[index]);
|
||||
}
|
||||
myCell->reloadCell();
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
#define PROBABILITY_IMAGE_TABLE_VIEW_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "law.h"
|
||||
#include "calculation.h"
|
||||
|
||||
namespace Probability {
|
||||
|
||||
class ImageTableView : public View, public Responder, public SimpleListViewDataSource {
|
||||
public:
|
||||
ImageTableView(Responder * parentResponder, Law * law);
|
||||
ImageTableView(Responder * parentResponder, Calculation * calculation);
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
void didBecomeFirstResponder() override;
|
||||
void select(bool select);
|
||||
@@ -41,7 +41,7 @@ private:
|
||||
ImageCell m_imageCells[k_numberOfImages];
|
||||
SelectableTableView m_selectableTableView;
|
||||
bool m_isSelected;
|
||||
Law * m_law;
|
||||
Calculation * m_calculation;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,338 +1,35 @@
|
||||
#include "law.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
namespace Probability {
|
||||
|
||||
Law::Law(EvaluateContext * evaluateContext):
|
||||
m_type(Law::Type::NoType),
|
||||
m_calculationType(LeftIntegral),
|
||||
m_parameter1(0.0f),
|
||||
m_parameter2(0.0f),
|
||||
m_expression(nullptr),
|
||||
m_xMin(-10.0f),
|
||||
m_xMax(10.0f),
|
||||
m_yMin(-0.1f),
|
||||
m_yMax(1.0f),
|
||||
m_gridUnit(1.0f),
|
||||
m_calculationElement1(0.0f),
|
||||
m_calculationElement2(0.0f),
|
||||
m_calculationElement3(0.0f),
|
||||
m_evaluateContext(evaluateContext)
|
||||
{
|
||||
computeCalculation(0);
|
||||
}
|
||||
|
||||
Law::~Law() {
|
||||
if (m_expression != nullptr) {
|
||||
delete m_expression;
|
||||
}
|
||||
}
|
||||
|
||||
EvaluateContext * Law::evaluateContext() {
|
||||
return m_evaluateContext;
|
||||
}
|
||||
|
||||
void Law::setType(Type type) {
|
||||
if (m_expression != nullptr) {
|
||||
delete m_expression;
|
||||
m_expression = nullptr;
|
||||
}
|
||||
const char * text = nullptr;
|
||||
switch (type) {
|
||||
// TODO: implement binomial, indicator function
|
||||
case Type::Binomial:
|
||||
text = "binomial(p1, p2)*p2^t*(1-p2)^(p1-t)";
|
||||
//break;
|
||||
case Type::Uniform:
|
||||
text = "1/(p2-p1)";
|
||||
//break;
|
||||
case Type::Exponential:
|
||||
text = "p1*exp(-p1*t)";
|
||||
//break;
|
||||
case Type::Normal:
|
||||
text = "(1/(p2*sqrt(2*Pi))*exp(-0.5*((t-p1)/p2)^2)";
|
||||
//break;
|
||||
case Type::Poisson:
|
||||
text = "exp(-p1)*p1^t/t!";
|
||||
text = "p1+p2*t";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (text) {
|
||||
m_expression = Expression::parse(text);
|
||||
}
|
||||
setParameterAtIndex(0.0f, 0);
|
||||
setParameterAtIndex(0.0f, 1);
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
Law::Type Law::type() const {
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void Law::setCalculationType(CalculationType calculationType) {
|
||||
m_calculationType = calculationType;
|
||||
initCalculationElements();
|
||||
}
|
||||
|
||||
Law::CalculationType Law::calculationType() const {
|
||||
return m_calculationType;
|
||||
}
|
||||
|
||||
Expression * Law::expression() {
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
bool Law::isContinuous() {
|
||||
switch (m_type) {
|
||||
case Type::Binomial:
|
||||
return false;
|
||||
case Type::Uniform:
|
||||
return true;
|
||||
case Type::Exponential:
|
||||
return true;
|
||||
case Type::Normal:
|
||||
return true;
|
||||
case Type::Poisson:
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
float Law::xMin() {
|
||||
return m_xMin;
|
||||
}
|
||||
|
||||
float Law::yMin() {
|
||||
return m_yMin;
|
||||
}
|
||||
|
||||
float Law::xMax() {
|
||||
return m_xMax;
|
||||
}
|
||||
|
||||
float Law::yMax() {
|
||||
return m_yMax;
|
||||
}
|
||||
|
||||
float Law::gridUnit() {
|
||||
return m_gridUnit;
|
||||
}
|
||||
|
||||
float Law::calculationElementAtIndex(int index) {
|
||||
if (index == 0) {
|
||||
return m_calculationElement1;
|
||||
}
|
||||
if (index == 1) {
|
||||
return m_calculationElement2;
|
||||
}
|
||||
return m_calculationElement3;
|
||||
}
|
||||
|
||||
void Law::setCalculationElementAtIndex(float f, int index) {
|
||||
if (index == 0) {
|
||||
m_calculationElement1 = f;
|
||||
}
|
||||
if (index == 1) {
|
||||
m_calculationElement2 = f;
|
||||
}
|
||||
if (index == 2) {
|
||||
m_calculationElement3 = f;
|
||||
}
|
||||
computeCalculation(index);
|
||||
}
|
||||
|
||||
int Law::numberOfParameter() {
|
||||
switch (m_type) {
|
||||
case Type::Binomial:
|
||||
return 2;
|
||||
case Type::Uniform:
|
||||
return 2;
|
||||
case Type::Exponential:
|
||||
return 1;
|
||||
case Type::Normal:
|
||||
return 2;
|
||||
case Type::Poisson:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
float Law::parameterValueAtIndex(int index) {
|
||||
assert(index >= 0 && index < 2);
|
||||
if (index == 0) {
|
||||
return m_parameter1;
|
||||
}
|
||||
return m_parameter2;
|
||||
}
|
||||
|
||||
const char * Law::parameterNameAtIndex(int index) {
|
||||
assert(index >= 0 && index < 2);
|
||||
switch (m_type) {
|
||||
// TODO: replace by greek letter
|
||||
case Type::Binomial:
|
||||
if (index == 0) {
|
||||
return "n";
|
||||
} else {
|
||||
return "p";
|
||||
}
|
||||
case Type::Uniform:
|
||||
if (index == 0) {
|
||||
return "a";
|
||||
} else {
|
||||
return "b";
|
||||
}
|
||||
case Type::Exponential:
|
||||
return "l";
|
||||
case Type::Normal:
|
||||
if (index == 0) {
|
||||
return "u";
|
||||
} else {
|
||||
return "o";
|
||||
}
|
||||
case Type::Poisson:
|
||||
return "l";
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char * Law::parameterDefinitionAtIndex(int index) {
|
||||
assert(index >= 0 && index < 2);
|
||||
switch (m_type) {
|
||||
case Type::Binomial:
|
||||
if (index == 0) {
|
||||
return "n : nombre de repetitions";
|
||||
} else {
|
||||
return "p : probabilites de succes";
|
||||
}
|
||||
case Type::Uniform:
|
||||
if (index == 0) {
|
||||
return "[a, b] intervalle";
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
case Type::Exponential:
|
||||
return "l : parametre";
|
||||
case Type::Normal:
|
||||
if (index == 0) {
|
||||
return "u : moyenne";
|
||||
} else {
|
||||
return "o : ecart-type";
|
||||
}
|
||||
case Type::Poisson:
|
||||
return "l : parametre";
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Law::setParameterAtIndex(float f, int index) {
|
||||
assert(index >= 0 && index < 2);
|
||||
if (index == 0) {
|
||||
m_parameter1 = f;
|
||||
m_evaluateContext->setOverridenValueForFirstParameter(f);
|
||||
} else {
|
||||
m_parameter2 = f;
|
||||
m_evaluateContext->setOverridenValueForSecondParameter(f);
|
||||
}
|
||||
setWindow();
|
||||
}
|
||||
|
||||
float Law::evaluateAtAbscissa(float t, EvaluateContext * context) const {
|
||||
context->setOverridenValueForSymbolT(t);
|
||||
return m_expression->approximate(*context);
|
||||
}
|
||||
|
||||
void Law::setWindow() {
|
||||
switch (m_type) {
|
||||
case Type::Binomial:
|
||||
m_xMin = 0.0f;
|
||||
m_xMax = m_parameter1;
|
||||
break;
|
||||
case Type::Uniform:
|
||||
m_xMin = m_parameter1 - 3.0f;
|
||||
m_xMax = m_parameter2 + 3.0f;
|
||||
break;
|
||||
case Type::Exponential:
|
||||
m_xMin = 0.0f;
|
||||
m_xMax = 5.0f/m_parameter1;
|
||||
break;
|
||||
case Type::Normal:
|
||||
m_xMin = m_parameter1 - 5.0f*m_parameter2;
|
||||
m_xMax = m_parameter1 + 5.0f*m_parameter2;
|
||||
break;
|
||||
case Type::Poisson:
|
||||
m_xMin = 0.0f;
|
||||
m_xMax = m_parameter1 + 5.0f*sqrtf(m_parameter1);
|
||||
default:
|
||||
return;
|
||||
}
|
||||
computeGridUnit();
|
||||
}
|
||||
|
||||
void Law::computeGridUnit() {
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
float d = m_xMax - m_xMin;
|
||||
if (floorf(log10f(d/90.0f)) != floorf(log10f(d/35.0f))) {
|
||||
b = floorf(log10f(d/35.0f));
|
||||
a = 5;
|
||||
}
|
||||
if (floorf(log10f(d/36.0f)) != floorf(log10f(d/14.0f))) {
|
||||
b = floorf(log10f(d/14.0f));
|
||||
a = 2;
|
||||
}
|
||||
if (floorf(log10f(d/18.0f)) != floorf(log10f(d/7.0f))) {
|
||||
b = floorf(log10f(d/7.0f));
|
||||
a = 1;
|
||||
}
|
||||
m_gridUnit = a*powf(10,b);
|
||||
}
|
||||
|
||||
void Law::computeCalculation(int indexKnownElement) {
|
||||
if (m_calculationType == LeftIntegral) {
|
||||
if (indexKnownElement == 0) {
|
||||
// TODO: compute integral from -Inf to m_calculationElement1
|
||||
m_calculationElement2 = 3.0f;
|
||||
} else {
|
||||
// TODO: find m_calculationElement1
|
||||
m_calculationElement1 = 4.0f;
|
||||
}
|
||||
}
|
||||
if (m_calculationType == FiniteIntegral) {
|
||||
// TODO: compute integral from m_calculationElement1 to m_calculationElement2
|
||||
m_calculationElement3 = 5.0f;
|
||||
}
|
||||
if (m_calculationType == RightIntegral) {
|
||||
if (indexKnownElement == 0) {
|
||||
// TODO: compute integral from m_calculationElement1 to +Inf
|
||||
m_calculationElement2 = 6.0f;
|
||||
} else {
|
||||
// TODO: find m_calculationElement1
|
||||
m_calculationElement1 = 7.0f;
|
||||
float d = xMax() - xMin();
|
||||
float units[3] = {k_oneUnit, k_twoUnit, k_fiveUnit};
|
||||
for (int k = 0; k < 3; k++) {
|
||||
float unit = units[k];
|
||||
if (floorf(log10f(d/(unit*k_maxNumberOfXGridUnits))) != floorf(log10f(d/(unit*k_minNumberOfXGridUnits)))) {
|
||||
b = floorf(log10f(d/(unit*k_minNumberOfXGridUnits)));
|
||||
a = unit;
|
||||
}
|
||||
}
|
||||
return a*powf(10,b);
|
||||
}
|
||||
|
||||
void Law::initCalculationElements() {
|
||||
if (m_calculationType == LeftIntegral) {
|
||||
m_calculationElement1 = 0.0f;
|
||||
computeCalculation(0);
|
||||
}
|
||||
if (m_calculationType == FiniteIntegral) {
|
||||
m_calculationElement1 = -1.0f;
|
||||
m_calculationElement2 = 1.0f;
|
||||
computeCalculation(0);
|
||||
}
|
||||
if (m_calculationType == RightIntegral) {
|
||||
m_calculationElement1 = 0.0f;
|
||||
computeCalculation(0);
|
||||
}
|
||||
float Law::evaluateAtAbscissa(float t) const {
|
||||
m_evaluateContext->setOverridenValueForSymbolT(t);
|
||||
return expression()->approximate(*m_evaluateContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,59 +7,37 @@ namespace Probability {
|
||||
|
||||
class Law {
|
||||
public:
|
||||
enum class Type {
|
||||
NoType,
|
||||
enum class Type : uint8_t{
|
||||
Binomial,
|
||||
Uniform,
|
||||
Exponential,
|
||||
Normal,
|
||||
Poisson
|
||||
};
|
||||
enum CalculationType : uint8_t {
|
||||
LeftIntegral = 0,
|
||||
FiniteIntegral = 1,
|
||||
RightIntegral = 2,
|
||||
};
|
||||
Law(EvaluateContext * evaluateContext);
|
||||
~Law();
|
||||
virtual ~Law() {};
|
||||
virtual const char * title() = 0;
|
||||
EvaluateContext * evaluateContext();
|
||||
void setType(Type type);
|
||||
Type type() const;
|
||||
void setCalculationType(CalculationType calculationType);
|
||||
CalculationType calculationType() const;
|
||||
Expression * expression();
|
||||
bool isContinuous();
|
||||
float xMin();
|
||||
float yMin();
|
||||
float xMax();
|
||||
float yMax();
|
||||
virtual Type type() const = 0;
|
||||
virtual Expression * expression() const = 0;
|
||||
virtual bool isContinuous() = 0;
|
||||
virtual float xMin() = 0;
|
||||
virtual float yMin() = 0;
|
||||
virtual float xMax() = 0;
|
||||
virtual float yMax() = 0;
|
||||
float gridUnit();
|
||||
float calculationElementAtIndex(int index);
|
||||
void setCalculationElementAtIndex(float f, int index);
|
||||
int numberOfParameter();
|
||||
float parameterValueAtIndex(int index);
|
||||
const char * parameterNameAtIndex(int index);
|
||||
const char * parameterDefinitionAtIndex(int index);
|
||||
void setParameterAtIndex(float f, int index);
|
||||
float evaluateAtAbscissa(float x, EvaluateContext * context) const;
|
||||
private:
|
||||
void setWindow();
|
||||
void computeGridUnit();
|
||||
void computeCalculation(int indexKnownElement);
|
||||
void initCalculationElements();
|
||||
Type m_type;
|
||||
CalculationType m_calculationType;
|
||||
float m_parameter1;
|
||||
float m_parameter2;
|
||||
Expression * m_expression;
|
||||
float m_xMin;
|
||||
float m_xMax;
|
||||
float m_yMin;
|
||||
float m_yMax;
|
||||
float m_gridUnit;
|
||||
float m_calculationElement1;
|
||||
float m_calculationElement2;
|
||||
float m_calculationElement3;
|
||||
virtual int numberOfParameter() = 0;
|
||||
virtual float parameterValueAtIndex(int index) = 0;
|
||||
virtual const char * parameterNameAtIndex(int index) = 0;
|
||||
virtual const char * parameterDefinitionAtIndex(int index) = 0;
|
||||
virtual void setParameterAtIndex(float f, int index) = 0;
|
||||
float evaluateAtAbscissa(float x) const;
|
||||
protected:
|
||||
constexpr static float k_minNumberOfXGridUnits = 7.0f;
|
||||
constexpr static float k_maxNumberOfXGridUnits = 18.0f;
|
||||
constexpr static float k_oneUnit = 1.0f;
|
||||
constexpr static float k_twoUnit = 2.0f;
|
||||
constexpr static float k_fiveUnit = 5.0f;
|
||||
EvaluateContext * m_evaluateContext;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
#include "law_controller.h"
|
||||
#include <assert.h>
|
||||
#include "app.h"
|
||||
#include "binomial_law.h"
|
||||
#include "exponential_law.h"
|
||||
#include "normal_law.h"
|
||||
#include "poisson_law.h"
|
||||
#include "uniform_law.h"
|
||||
#include "images/binomial_icon.h"
|
||||
#include "images/exponential_icon.h"
|
||||
#include "images/normal_icon.h"
|
||||
@@ -26,8 +31,9 @@ LawController::LawController(Responder * parentResponder, EvaluateContext * eval
|
||||
ViewController(parentResponder),
|
||||
m_selectableTableView(SelectableTableView(this, this, Metric::TopMargin, Metric::RightMargin,
|
||||
Metric::BottomMargin, Metric::LeftMargin)),
|
||||
m_law(evaluateContext),
|
||||
m_parametersController(ParametersController(nullptr, &m_law))
|
||||
m_law(nullptr),
|
||||
m_evaluateContext(evaluateContext),
|
||||
m_parametersController(ParametersController(nullptr))
|
||||
{
|
||||
m_messages = sMessages;
|
||||
}
|
||||
@@ -37,24 +43,18 @@ View * LawController::view() {
|
||||
}
|
||||
|
||||
const char * LawController::title() const {
|
||||
switch (m_law.type()) {
|
||||
case Law::Type::Binomial:
|
||||
return "Loi binomiale";
|
||||
case Law::Type::Uniform:
|
||||
return "Loi uniforme";
|
||||
case Law::Type::Exponential:
|
||||
return "Loi exponentielle";
|
||||
case Law::Type::Normal:
|
||||
return "Loi normale";
|
||||
case Law::Type::Poisson:
|
||||
return "Loi Poisson";
|
||||
default:
|
||||
return "Choisir le type de Loi";
|
||||
if (m_law == nullptr) {
|
||||
return "Choisir le type de Loi";
|
||||
}
|
||||
return m_law->title();
|
||||
}
|
||||
|
||||
void Probability::LawController::didBecomeFirstResponder() {
|
||||
m_law.setType(Law::Type::NoType);
|
||||
if (m_law != nullptr) {
|
||||
delete m_law;
|
||||
m_law = nullptr;
|
||||
m_parametersController.setLaw(m_law);
|
||||
}
|
||||
StackViewController * stack = (StackViewController *)parentResponder();
|
||||
stack->updateTitle();
|
||||
if (m_selectableTableView.selectedRow() == -1) {
|
||||
@@ -68,7 +68,7 @@ void Probability::LawController::didBecomeFirstResponder() {
|
||||
bool Probability::LawController::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::OK) {
|
||||
StackViewController * stack = (StackViewController *)parentResponder();
|
||||
m_law.setType(typeAtIndex(m_selectableTableView.selectedRow()));
|
||||
setLawAccordingToIndex(m_selectableTableView.selectedRow());
|
||||
stack->updateTitle();
|
||||
stack->push(&m_parametersController);
|
||||
return true;
|
||||
@@ -93,25 +93,11 @@ int Probability::LawController::reusableCellCount() {
|
||||
void Probability::LawController::willDisplayCellForIndex(TableViewCell * cell, int index) {
|
||||
Cell * myCell = (Cell *)cell;
|
||||
myCell->setLabel(m_messages[index]);
|
||||
switch (typeAtIndex(index)) {
|
||||
case Law::Type::Binomial:
|
||||
myCell->setImage(ImageStore::BinomialIcon, ImageStore::FocusedBinomialIcon);
|
||||
break;
|
||||
case Law::Type::Uniform:
|
||||
myCell->setImage(ImageStore::UniformIcon, ImageStore::FocusedUniformIcon);
|
||||
break;
|
||||
case Law::Type::Exponential:
|
||||
myCell->setImage(ImageStore::ExponentialIcon, ImageStore::FocusedExponentialIcon);
|
||||
break;
|
||||
case Law::Type::Normal:
|
||||
myCell->setImage(ImageStore::NormalIcon, ImageStore::FocusedNormalIcon);
|
||||
break;
|
||||
case Law::Type::Poisson:
|
||||
myCell->setImage(ImageStore::PoissonIcon, ImageStore::FocusedPoissonIcon);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
const Image * images[5] = {ImageStore::BinomialIcon, ImageStore::UniformIcon, ImageStore::ExponentialIcon,
|
||||
ImageStore::NormalIcon, ImageStore::PoissonIcon};
|
||||
const Image * focusedImages[5] = {ImageStore::FocusedBinomialIcon, ImageStore::FocusedUniformIcon, ImageStore::FocusedExponentialIcon,
|
||||
ImageStore::FocusedNormalIcon, ImageStore::FocusedPoissonIcon};
|
||||
myCell->setImage(images[index], focusedImages[index]);
|
||||
myCell->reloadCell();
|
||||
}
|
||||
|
||||
@@ -119,21 +105,31 @@ KDCoordinate Probability::LawController::cellHeight() {
|
||||
return 35;
|
||||
}
|
||||
|
||||
Law::Type Probability::LawController::typeAtIndex(int index) {
|
||||
void Probability::LawController::setLawAccordingToIndex(int index) {
|
||||
if (m_law != nullptr) {
|
||||
delete m_law;
|
||||
m_law = nullptr;
|
||||
}
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Law::Type::Binomial;
|
||||
m_law = new BinomialLaw(m_evaluateContext);
|
||||
break;
|
||||
case 1:
|
||||
return Law::Type::Uniform;
|
||||
m_law = new UniformLaw(m_evaluateContext);
|
||||
break;
|
||||
case 2:
|
||||
return Law::Type::Exponential;
|
||||
m_law = new ExponentialLaw(m_evaluateContext);
|
||||
break;
|
||||
case 3:
|
||||
return Law::Type::Normal;
|
||||
m_law = new NormalLaw(m_evaluateContext);
|
||||
break;
|
||||
case 4:
|
||||
return Law::Type::Poisson;
|
||||
m_law = new PoissonLaw(m_evaluateContext);
|
||||
break;
|
||||
default:
|
||||
return Law::Type::NoType;
|
||||
return;
|
||||
}
|
||||
m_parametersController.setLaw(m_law);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,14 +23,15 @@ public:
|
||||
TableViewCell * reusableCell(int index) override;
|
||||
int reusableCellCount() override;
|
||||
private:
|
||||
Law::Type typeAtIndex(int index);
|
||||
void setLawAccordingToIndex(int index);
|
||||
constexpr static int k_totalNumberOfModels = 5;
|
||||
// !!! CAUTION: The order here is important
|
||||
// The cells should be initialized *before* the listview!
|
||||
Cell m_cells[k_totalNumberOfModels];
|
||||
SelectableTableView m_selectableTableView;
|
||||
const char ** m_messages;
|
||||
Law m_law;
|
||||
Law * m_law;
|
||||
EvaluateContext * m_evaluateContext;
|
||||
ParametersController m_parametersController;
|
||||
|
||||
};
|
||||
|
||||
@@ -3,12 +3,16 @@
|
||||
|
||||
namespace Probability {
|
||||
|
||||
LawCurveView::LawCurveView(Law * law) :
|
||||
LawCurveView::LawCurveView() :
|
||||
CurveView(),
|
||||
m_law(law)
|
||||
m_law(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void LawCurveView::setLaw(Law * law) {
|
||||
m_law = law;
|
||||
}
|
||||
|
||||
void LawCurveView::reload() {
|
||||
markRectAsDirty(bounds());
|
||||
computeLabels(Axis::Horizontal);
|
||||
|
||||
@@ -11,7 +11,8 @@ namespace Probability {
|
||||
|
||||
class LawCurveView : public CurveView {
|
||||
public:
|
||||
LawCurveView(Law * law);
|
||||
LawCurveView();
|
||||
void setLaw(Law * law);
|
||||
void reload();
|
||||
void drawRect(KDContext * ctx, KDRect rect) const override;
|
||||
protected:
|
||||
|
||||
74
apps/probability/normal_law.cpp
Normal file
74
apps/probability/normal_law.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#include "normal_law.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace Probability {
|
||||
|
||||
NormalLaw::NormalLaw(EvaluateContext * evaluateContext) :
|
||||
TwoParameterLaw(evaluateContext),
|
||||
m_expression(Expression::parse("p1-p2*t"))
|
||||
{
|
||||
//m_expression = Expression::parse("(1/(p2*sqrt(2*Pi))*exp(-0.5*((t-p1)/p2)^2)");
|
||||
assert(m_expression != nullptr);
|
||||
}
|
||||
|
||||
NormalLaw::~NormalLaw() {
|
||||
delete m_expression;
|
||||
}
|
||||
|
||||
const char * NormalLaw::title() {
|
||||
return "Loi normale";
|
||||
}
|
||||
|
||||
Expression * NormalLaw::expression() const {
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
Law::Type NormalLaw::type() const {
|
||||
return Type::Normal;
|
||||
}
|
||||
|
||||
bool NormalLaw::isContinuous() {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char * NormalLaw::parameterNameAtIndex(int index) {
|
||||
assert(index >= 0 && index < 2);
|
||||
if (index == 0) {
|
||||
return "u";
|
||||
} else {
|
||||
return "o";
|
||||
}
|
||||
}
|
||||
|
||||
const char * NormalLaw::parameterDefinitionAtIndex(int index) {
|
||||
assert(index >= 0 && index < 2);
|
||||
if (index == 0) {
|
||||
return "u : moyenne";
|
||||
} else {
|
||||
return "o : ecart-type";
|
||||
}
|
||||
}
|
||||
|
||||
float NormalLaw::xMin() {
|
||||
if (m_parameter2 == 0.0f) {
|
||||
return m_parameter1 - 1.0f;
|
||||
}
|
||||
return m_parameter1 - 5.0f*m_parameter2;
|
||||
}
|
||||
|
||||
float NormalLaw::xMax() {
|
||||
if (m_parameter2 == 0.0f) {
|
||||
return m_parameter1 + 1.0f;
|
||||
}
|
||||
return m_parameter1 + 5.0f*m_parameter2;
|
||||
}
|
||||
|
||||
float NormalLaw::yMin() {
|
||||
return -0.2f;
|
||||
}
|
||||
|
||||
float NormalLaw::yMax() {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
29
apps/probability/normal_law.h
Normal file
29
apps/probability/normal_law.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef PROBABILITE_NORMAL_LAW_H
|
||||
#define PROBABILITE_NORMAL_LAW_H
|
||||
|
||||
#include "evaluate_context.h"
|
||||
#include "two_parameter_law.h"
|
||||
|
||||
namespace Probability {
|
||||
|
||||
class NormalLaw : public TwoParameterLaw {
|
||||
public:
|
||||
NormalLaw(EvaluateContext * evaluateContext);
|
||||
~NormalLaw() override;
|
||||
const char * title() override;
|
||||
Expression * expression() const override;
|
||||
Type type() const override;
|
||||
bool isContinuous() override;
|
||||
float xMin() override;
|
||||
float yMin() override;
|
||||
float xMax() override;
|
||||
float yMax() override;
|
||||
const char * parameterNameAtIndex(int index) override;
|
||||
const char * parameterDefinitionAtIndex(int index) override;
|
||||
private:
|
||||
Expression * m_expression;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
28
apps/probability/one_parameter_law.cpp
Normal file
28
apps/probability/one_parameter_law.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "one_parameter_law.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace Probability {
|
||||
|
||||
OneParameterLaw::OneParameterLaw(EvaluateContext * evaluateContext) :
|
||||
Law(evaluateContext),
|
||||
m_parameter1(0.5f)
|
||||
{
|
||||
m_evaluateContext->setOverridenValueForFirstParameter(m_parameter1);
|
||||
}
|
||||
|
||||
int OneParameterLaw::numberOfParameter() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
float OneParameterLaw::parameterValueAtIndex(int index) {
|
||||
assert(index == 0);
|
||||
return m_parameter1;
|
||||
}
|
||||
|
||||
void OneParameterLaw::setParameterAtIndex(float f, int index) {
|
||||
assert(index == 0);
|
||||
m_parameter1 = f;
|
||||
m_evaluateContext->setOverridenValueForFirstParameter(f);
|
||||
}
|
||||
|
||||
}
|
||||
22
apps/probability/one_parameter_law.h
Normal file
22
apps/probability/one_parameter_law.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef PROBABILITE_ONE_PARAMETER_LAW_H
|
||||
#define PROBABILITE_ONE_PARAMETER_LAW_H
|
||||
|
||||
#include "evaluate_context.h"
|
||||
#include "law.h"
|
||||
|
||||
namespace Probability {
|
||||
|
||||
class OneParameterLaw : public Law {
|
||||
public:
|
||||
OneParameterLaw(EvaluateContext * evaluateContext);
|
||||
virtual ~OneParameterLaw() {};
|
||||
int numberOfParameter() override;
|
||||
float parameterValueAtIndex(int index) override;
|
||||
void setParameterAtIndex(float f, int index) override;
|
||||
protected:
|
||||
float m_parameter1;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -11,8 +11,8 @@ ParametersController::ContentView::ContentView(Responder * parentResponder, Sele
|
||||
ParametersController * parameterController = (ParametersController *) context;
|
||||
CalculationController * calculationController = parameterController->calculationController();
|
||||
calculationController->selectSubview(1);
|
||||
Law * law = calculationController->law();
|
||||
law->setCalculationType(Law::CalculationType::LeftIntegral);
|
||||
Calculation * calculation = calculationController->calculation();
|
||||
calculation->setType(Calculation::Type::LeftIntegral);
|
||||
StackViewController * stack = parameterController->stackController();
|
||||
stack->updateTitle();
|
||||
stack->push(calculationController);
|
||||
@@ -68,12 +68,12 @@ void ParametersController::ContentView::layoutSubviews() {
|
||||
|
||||
/* Parameters Controller */
|
||||
|
||||
ParametersController::ParametersController(Responder * parentResponder, Law * law) :
|
||||
ParametersController::ParametersController(Responder * parentResponder) :
|
||||
FloatParameterController(parentResponder),
|
||||
m_contentView(ContentView(this, &m_selectableTableView)),
|
||||
m_law(law),
|
||||
m_law(nullptr),
|
||||
m_buttonSelected(false),
|
||||
m_calculationController(CalculationController(nullptr, law))
|
||||
m_calculationController(CalculationController(nullptr))
|
||||
{
|
||||
for (int k = 0; k < k_maxNumberOfCells; k++) {
|
||||
m_menuListCell[k].setParentResponder(&m_selectableTableView);
|
||||
@@ -97,6 +97,11 @@ const char * ParametersController::title() const {
|
||||
return m_titleBuffer;
|
||||
}
|
||||
|
||||
void ParametersController::setLaw(Law * law) {
|
||||
m_law = law;
|
||||
m_calculationController.setLaw(law);
|
||||
}
|
||||
|
||||
void ParametersController::updateTitle() {
|
||||
int currentChar = 0;
|
||||
for (int index = 0; index < m_law->numberOfParameter(); index++) {
|
||||
|
||||
@@ -10,10 +10,11 @@ namespace Probability {
|
||||
|
||||
class ParametersController : public FloatParameterController {
|
||||
public:
|
||||
ParametersController(Responder * parentResponder, Law * law);
|
||||
ParametersController(Responder * parentResponder);
|
||||
ExpressionTextFieldDelegate * textFieldDelegate() override;
|
||||
View * view() override;
|
||||
const char * title() const override;
|
||||
void setLaw(Law * law);
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
void didBecomeFirstResponder() override;
|
||||
StackViewController * stackController();
|
||||
|
||||
64
apps/probability/poisson_law.cpp
Normal file
64
apps/probability/poisson_law.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "poisson_law.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
namespace Probability {
|
||||
|
||||
PoissonLaw::PoissonLaw(EvaluateContext * evaluateContext) :
|
||||
OneParameterLaw(evaluateContext),
|
||||
m_expression(Expression::parse("p1*t"))
|
||||
{
|
||||
//m_expression = Expression::parse("exp(-p1)*p1^t/t!");
|
||||
assert(m_expression != nullptr);
|
||||
}
|
||||
|
||||
PoissonLaw::~PoissonLaw() {
|
||||
delete m_expression;
|
||||
}
|
||||
|
||||
const char * PoissonLaw::title() {
|
||||
return "Loi Poisson";
|
||||
}
|
||||
|
||||
Expression * PoissonLaw::expression() const {
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
Law::Type PoissonLaw::type() const {
|
||||
return Type::Poisson;
|
||||
}
|
||||
|
||||
bool PoissonLaw::isContinuous() {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char * PoissonLaw::parameterNameAtIndex(int index) {
|
||||
assert(index == 0);
|
||||
return "l";
|
||||
}
|
||||
|
||||
const char * PoissonLaw::parameterDefinitionAtIndex(int index) {
|
||||
assert(index == 0);
|
||||
return "l : parametre";
|
||||
}
|
||||
|
||||
float PoissonLaw::xMin() {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float PoissonLaw::xMax() {
|
||||
if (m_parameter1 == 0.0f) {
|
||||
return 1.0f;
|
||||
}
|
||||
return m_parameter1 + 5.0f*sqrtf(m_parameter1);
|
||||
}
|
||||
|
||||
float PoissonLaw::yMin() {
|
||||
return -0.2f;
|
||||
}
|
||||
|
||||
float PoissonLaw::yMax() {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
29
apps/probability/poisson_law.h
Normal file
29
apps/probability/poisson_law.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef PROBABILITE_POISSON_LAW_H
|
||||
#define PROBABILITE_POISSON_LAW_H
|
||||
|
||||
#include "evaluate_context.h"
|
||||
#include "one_parameter_law.h"
|
||||
|
||||
namespace Probability {
|
||||
|
||||
class PoissonLaw : public OneParameterLaw {
|
||||
public:
|
||||
PoissonLaw(EvaluateContext * evaluateContext);
|
||||
~PoissonLaw() override;
|
||||
const char * title() override;
|
||||
Expression * expression() const override;
|
||||
Type type() const override;
|
||||
bool isContinuous() override;
|
||||
float xMin() override;
|
||||
float yMin() override;
|
||||
float xMax() override;
|
||||
float yMax() override;
|
||||
const char * parameterNameAtIndex(int index) override;
|
||||
const char * parameterDefinitionAtIndex(int index) override;
|
||||
private:
|
||||
Expression * m_expression;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
38
apps/probability/two_parameter_law.cpp
Normal file
38
apps/probability/two_parameter_law.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "two_parameter_law.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace Probability {
|
||||
|
||||
TwoParameterLaw::TwoParameterLaw(EvaluateContext * evaluateContext) :
|
||||
Law(evaluateContext),
|
||||
m_parameter1(0.0f),
|
||||
m_parameter2(0.0f)
|
||||
{
|
||||
m_evaluateContext->setOverridenValueForFirstParameter(m_parameter1);
|
||||
m_evaluateContext->setOverridenValueForSecondParameter(m_parameter2);
|
||||
}
|
||||
|
||||
int TwoParameterLaw::numberOfParameter() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
float TwoParameterLaw::parameterValueAtIndex(int index) {
|
||||
assert(index >= 0 && index < 2);
|
||||
if (index == 0) {
|
||||
return m_parameter1;
|
||||
}
|
||||
return m_parameter2;
|
||||
}
|
||||
|
||||
void TwoParameterLaw::setParameterAtIndex(float f, int index) {
|
||||
assert(index >= 0 && index < 2);
|
||||
if (index == 0) {
|
||||
m_parameter1 = f;
|
||||
m_evaluateContext->setOverridenValueForFirstParameter(f);
|
||||
} else {
|
||||
m_parameter2 = f;
|
||||
m_evaluateContext->setOverridenValueForSecondParameter(f);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
23
apps/probability/two_parameter_law.h
Normal file
23
apps/probability/two_parameter_law.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef PROBABILITE_TWO_PARAMETER_LAW_H
|
||||
#define PROBABILITE_TWO_PARAMETER_LAW_H
|
||||
|
||||
#include "evaluate_context.h"
|
||||
#include "law.h"
|
||||
|
||||
namespace Probability {
|
||||
|
||||
class TwoParameterLaw : public Law {
|
||||
public:
|
||||
TwoParameterLaw(EvaluateContext * evaluateContext);
|
||||
virtual ~TwoParameterLaw() {};
|
||||
int numberOfParameter() override;
|
||||
float parameterValueAtIndex(int index) override;
|
||||
void setParameterAtIndex(float f, int index) override;
|
||||
protected:
|
||||
float m_parameter1;
|
||||
float m_parameter2;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
74
apps/probability/uniform_law.cpp
Normal file
74
apps/probability/uniform_law.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#include "uniform_law.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace Probability {
|
||||
|
||||
UniformLaw::UniformLaw(EvaluateContext * evaluateContext) :
|
||||
TwoParameterLaw(evaluateContext)
|
||||
{
|
||||
// TODO: parse indicator function
|
||||
m_expression = Expression::parse("1/(p2-p1)");
|
||||
assert(m_expression != nullptr);
|
||||
}
|
||||
|
||||
UniformLaw::~UniformLaw() {
|
||||
delete m_expression;
|
||||
}
|
||||
|
||||
const char * UniformLaw::title() {
|
||||
return "Loi uniforme";
|
||||
}
|
||||
|
||||
Expression * UniformLaw::expression() const {
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
Law::Type UniformLaw::type() const {
|
||||
return Type::Uniform;
|
||||
}
|
||||
|
||||
bool UniformLaw::isContinuous() {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char * UniformLaw::parameterNameAtIndex(int index) {
|
||||
assert(index >= 0 && index < 2);
|
||||
if (index == 0) {
|
||||
return "a";
|
||||
} else {
|
||||
return "b";
|
||||
}
|
||||
}
|
||||
|
||||
const char * UniformLaw::parameterDefinitionAtIndex(int index) {
|
||||
assert(index >= 0 && index < 2);
|
||||
if (index == 0) {
|
||||
return "[a, b] intervalle";
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
float UniformLaw::xMin() {
|
||||
if (m_parameter2 < m_parameter1) {
|
||||
return m_parameter2 - 3.0f;
|
||||
}
|
||||
return m_parameter1 - 3.0f;
|
||||
}
|
||||
|
||||
float UniformLaw::xMax() {
|
||||
if (m_parameter2 < m_parameter1) {
|
||||
return m_parameter1 + 3.0f;
|
||||
}
|
||||
return m_parameter2 + 3.0f;;
|
||||
}
|
||||
|
||||
float UniformLaw::yMin() {
|
||||
return -0.2f;
|
||||
}
|
||||
|
||||
float UniformLaw::yMax() {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
29
apps/probability/uniform_law.h
Normal file
29
apps/probability/uniform_law.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef PROBABILITE_UNIFORM_LAW_H
|
||||
#define PROBABILITE_UNIFORM_LAW_H
|
||||
|
||||
#include "evaluate_context.h"
|
||||
#include "two_parameter_law.h"
|
||||
|
||||
namespace Probability {
|
||||
|
||||
class UniformLaw : public TwoParameterLaw {
|
||||
public:
|
||||
UniformLaw(EvaluateContext * evaluateContext);
|
||||
~UniformLaw() override;
|
||||
const char * title() override;
|
||||
Expression * expression() const override;
|
||||
Type type() const override;
|
||||
bool isContinuous() override;
|
||||
float xMin() override;
|
||||
float yMin() override;
|
||||
float xMax() override;
|
||||
float yMax() override;
|
||||
const char * parameterNameAtIndex(int index) override;
|
||||
const char * parameterDefinitionAtIndex(int index) override;
|
||||
private:
|
||||
Expression * m_expression;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user