From 2a79d8bfd948aab12f7cfc80a3cafdca7f95c516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Wed, 14 Dec 2016 11:16:11 +0100 Subject: [PATCH] [apps/probability] Make law model an abstract class with inheritance for all specific laws (binomial...) Change-Id: Ida6d5bfb7a3fbfc288393cd2f7e9e9b934798073 --- apps/probability/Makefile | 8 + apps/probability/binomial_law.cpp | 71 +++++ apps/probability/binomial_law.h | 29 ++ apps/probability/calculation.cpp | 97 ++++++ apps/probability/calculation.h | 34 ++ apps/probability/calculation_controller.cpp | 53 ++-- apps/probability/calculation_controller.h | 12 +- apps/probability/exponential_law.cpp | 63 ++++ apps/probability/exponential_law.h | 29 ++ apps/probability/image_table_view.cpp | 38 +-- apps/probability/image_table_view.h | 6 +- apps/probability/law.cpp | 325 +------------------- apps/probability/law.h | 66 ++-- apps/probability/law_controller.cpp | 82 +++-- apps/probability/law_controller.h | 5 +- apps/probability/law_curve_view.cpp | 8 +- apps/probability/law_curve_view.h | 3 +- apps/probability/normal_law.cpp | 74 +++++ apps/probability/normal_law.h | 29 ++ apps/probability/one_parameter_law.cpp | 28 ++ apps/probability/one_parameter_law.h | 22 ++ apps/probability/parameters_controller.cpp | 15 +- apps/probability/parameters_controller.h | 3 +- apps/probability/poisson_law.cpp | 64 ++++ apps/probability/poisson_law.h | 29 ++ apps/probability/two_parameter_law.cpp | 38 +++ apps/probability/two_parameter_law.h | 23 ++ apps/probability/uniform_law.cpp | 74 +++++ apps/probability/uniform_law.h | 29 ++ 29 files changed, 885 insertions(+), 472 deletions(-) create mode 100644 apps/probability/binomial_law.cpp create mode 100644 apps/probability/binomial_law.h create mode 100644 apps/probability/calculation.cpp create mode 100644 apps/probability/calculation.h create mode 100644 apps/probability/exponential_law.cpp create mode 100644 apps/probability/exponential_law.h create mode 100644 apps/probability/normal_law.cpp create mode 100644 apps/probability/normal_law.h create mode 100644 apps/probability/one_parameter_law.cpp create mode 100644 apps/probability/one_parameter_law.h create mode 100644 apps/probability/poisson_law.cpp create mode 100644 apps/probability/poisson_law.h create mode 100644 apps/probability/two_parameter_law.cpp create mode 100644 apps/probability/two_parameter_law.h create mode 100644 apps/probability/uniform_law.cpp create mode 100644 apps/probability/uniform_law.h diff --git a/apps/probability/Makefile b/apps/probability/Makefile index a5d345437..e2b73b3d8 100644 --- a/apps/probability/Makefile +++ b/apps/probability/Makefile @@ -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/,\ diff --git a/apps/probability/binomial_law.cpp b/apps/probability/binomial_law.cpp new file mode 100644 index 000000000..ee7b28205 --- /dev/null +++ b/apps/probability/binomial_law.cpp @@ -0,0 +1,71 @@ +#include "binomial_law.h" +#include + +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; +} + +} diff --git a/apps/probability/binomial_law.h b/apps/probability/binomial_law.h new file mode 100644 index 000000000..e09d3c0f4 --- /dev/null +++ b/apps/probability/binomial_law.h @@ -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 diff --git a/apps/probability/calculation.cpp b/apps/probability/calculation.cpp new file mode 100644 index 000000000..dae5d4800 --- /dev/null +++ b/apps/probability/calculation.cpp @@ -0,0 +1,97 @@ +#include "calculation.h" +#include +#include + +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); + } +} + +} diff --git a/apps/probability/calculation.h b/apps/probability/calculation.h new file mode 100644 index 000000000..3d4fd9eed --- /dev/null +++ b/apps/probability/calculation.h @@ -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 diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index 2df0d5b9b..c141ae377 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -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; } diff --git a/apps/probability/calculation_controller.h b/apps/probability/calculation_controller.h index 15c2779bc..8863d024e 100644 --- a/apps/probability/calculation_controller.h +++ b/apps/probability/calculation_controller.h @@ -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; }; } diff --git a/apps/probability/exponential_law.cpp b/apps/probability/exponential_law.cpp new file mode 100644 index 000000000..562d09a76 --- /dev/null +++ b/apps/probability/exponential_law.cpp @@ -0,0 +1,63 @@ +#include "exponential_law.h" +#include + +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; +} + +} diff --git a/apps/probability/exponential_law.h b/apps/probability/exponential_law.h new file mode 100644 index 000000000..8fd18ef7a --- /dev/null +++ b/apps/probability/exponential_law.h @@ -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 diff --git a/apps/probability/image_table_view.cpp b/apps/probability/image_table_view.cpp index c06a089f2..0d5d11550 100644 --- a/apps/probability/image_table_view.cpp +++ b/apps/probability/image_table_view.cpp @@ -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(); } diff --git a/apps/probability/image_table_view.h b/apps/probability/image_table_view.h index 144b4d6bc..b180c5ab8 100644 --- a/apps/probability/image_table_view.h +++ b/apps/probability/image_table_view.h @@ -2,13 +2,13 @@ #define PROBABILITY_IMAGE_TABLE_VIEW_H #include -#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; }; } diff --git a/apps/probability/law.cpp b/apps/probability/law.cpp index 4a26359df..331736f48 100644 --- a/apps/probability/law.cpp +++ b/apps/probability/law.cpp @@ -1,338 +1,35 @@ #include "law.h" -#include #include 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); } } diff --git a/apps/probability/law.h b/apps/probability/law.h index 5c1d4bf5f..d54ec2c7f 100644 --- a/apps/probability/law.h +++ b/apps/probability/law.h @@ -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; }; diff --git a/apps/probability/law_controller.cpp b/apps/probability/law_controller.cpp index ff96ddd1d..fc4c3071b 100644 --- a/apps/probability/law_controller.cpp +++ b/apps/probability/law_controller.cpp @@ -1,6 +1,11 @@ #include "law_controller.h" #include #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); } } diff --git a/apps/probability/law_controller.h b/apps/probability/law_controller.h index 81fe12be3..735cf8972 100644 --- a/apps/probability/law_controller.h +++ b/apps/probability/law_controller.h @@ -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; }; diff --git a/apps/probability/law_curve_view.cpp b/apps/probability/law_curve_view.cpp index c15b4f62d..bdba7fd2c 100644 --- a/apps/probability/law_curve_view.cpp +++ b/apps/probability/law_curve_view.cpp @@ -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); diff --git a/apps/probability/law_curve_view.h b/apps/probability/law_curve_view.h index 533240aec..ab8aa2c5d 100644 --- a/apps/probability/law_curve_view.h +++ b/apps/probability/law_curve_view.h @@ -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: diff --git a/apps/probability/normal_law.cpp b/apps/probability/normal_law.cpp new file mode 100644 index 000000000..9f3c86b8a --- /dev/null +++ b/apps/probability/normal_law.cpp @@ -0,0 +1,74 @@ +#include "normal_law.h" +#include + +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; +} + +} diff --git a/apps/probability/normal_law.h b/apps/probability/normal_law.h new file mode 100644 index 000000000..5c398ef64 --- /dev/null +++ b/apps/probability/normal_law.h @@ -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 diff --git a/apps/probability/one_parameter_law.cpp b/apps/probability/one_parameter_law.cpp new file mode 100644 index 000000000..789accdcc --- /dev/null +++ b/apps/probability/one_parameter_law.cpp @@ -0,0 +1,28 @@ +#include "one_parameter_law.h" +#include + +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); +} + +} diff --git a/apps/probability/one_parameter_law.h b/apps/probability/one_parameter_law.h new file mode 100644 index 000000000..5820361e2 --- /dev/null +++ b/apps/probability/one_parameter_law.h @@ -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 diff --git a/apps/probability/parameters_controller.cpp b/apps/probability/parameters_controller.cpp index 78e5eabbd..9e7884a8b 100644 --- a/apps/probability/parameters_controller.cpp +++ b/apps/probability/parameters_controller.cpp @@ -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++) { diff --git a/apps/probability/parameters_controller.h b/apps/probability/parameters_controller.h index a425f3435..1a1c842db 100644 --- a/apps/probability/parameters_controller.h +++ b/apps/probability/parameters_controller.h @@ -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(); diff --git a/apps/probability/poisson_law.cpp b/apps/probability/poisson_law.cpp new file mode 100644 index 000000000..7bbfe043a --- /dev/null +++ b/apps/probability/poisson_law.cpp @@ -0,0 +1,64 @@ +#include "poisson_law.h" +#include +#include + +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; +} + +} diff --git a/apps/probability/poisson_law.h b/apps/probability/poisson_law.h new file mode 100644 index 000000000..76a53e239 --- /dev/null +++ b/apps/probability/poisson_law.h @@ -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 diff --git a/apps/probability/two_parameter_law.cpp b/apps/probability/two_parameter_law.cpp new file mode 100644 index 000000000..62f295aeb --- /dev/null +++ b/apps/probability/two_parameter_law.cpp @@ -0,0 +1,38 @@ +#include "two_parameter_law.h" +#include + +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); + } +} + +} diff --git a/apps/probability/two_parameter_law.h b/apps/probability/two_parameter_law.h new file mode 100644 index 000000000..d92ade023 --- /dev/null +++ b/apps/probability/two_parameter_law.h @@ -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 diff --git a/apps/probability/uniform_law.cpp b/apps/probability/uniform_law.cpp new file mode 100644 index 000000000..8f379d3c4 --- /dev/null +++ b/apps/probability/uniform_law.cpp @@ -0,0 +1,74 @@ +#include "uniform_law.h" +#include + +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; +} + +} diff --git a/apps/probability/uniform_law.h b/apps/probability/uniform_law.h new file mode 100644 index 000000000..a50f5d4d3 --- /dev/null +++ b/apps/probability/uniform_law.h @@ -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