diff --git a/apps/probability/app.cpp b/apps/probability/app.cpp index 0cae4049b..f200761a3 100644 --- a/apps/probability/app.cpp +++ b/apps/probability/app.cpp @@ -5,14 +5,14 @@ namespace Probability { App::App(Container * container, Context * context) : ::App(container, &m_stackViewController, "Probability", ImageStore::ProbabilityIcon), - m_context(context), - m_lawController(LawController(nullptr)), + m_evaluateContext(EvaluateContext(context)), + m_lawController(LawController(nullptr, &m_evaluateContext)), m_stackViewController(&m_modalViewController, &m_lawController, true) { } Context * App::evaluateContext() { - return m_context; + return &m_evaluateContext; } } \ No newline at end of file diff --git a/apps/probability/app.h b/apps/probability/app.h index 4dca564cb..511f9027e 100644 --- a/apps/probability/app.h +++ b/apps/probability/app.h @@ -3,6 +3,7 @@ #include #include "law_controller.h" +#include "evaluate_context.h" #include "../expression_text_field_delegate.h" namespace Probability { @@ -16,7 +17,7 @@ public: App(Container * container, Context * context); Context * evaluateContext() override; private: - Context * m_context; + EvaluateContext m_evaluateContext; LawController m_lawController; StackViewController m_stackViewController; }; diff --git a/apps/probability/law.cpp b/apps/probability/law.cpp index 00ad0f9d2..331c6940a 100644 --- a/apps/probability/law.cpp +++ b/apps/probability/law.cpp @@ -1,29 +1,119 @@ #include "law.h" #include +#include namespace Probability { -Law::Law(): +Law::Law(EvaluateContext * evaluateContext): m_type(Law::Type::NoType), m_parameter1(0.0f), m_parameter2(0.0f), m_expression(nullptr), m_xMin(-10.0f), - m_xMax(10.0f) + m_xMax(10.0f), + m_yMin(-0.1f), + m_yMax(1.0f), + m_evaluateContext(evaluateContext) { } +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; +} + +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; +} + int Law::numberOfParameter() { switch (m_type) { - case Law::Type::Binomial: + case Type::Binomial: return 2; - case Law::Type::Uniform: + case Type::Uniform: return 2; - case Law::Type::Exponential: + case Type::Exponential: return 1; - case Law::Type::Normal: + case Type::Normal: return 2; - case Law::Type::Poisson: + case Type::Poisson: return 1; default: return 0; @@ -41,27 +131,28 @@ float Law::parameterValueAtIndex(int index) { const char * Law::parameterNameAtIndex(int index) { assert(index >= 0 && index < 2); switch (m_type) { - case Law::Type::Binomial: + // TODO: replace by greek letter + case Type::Binomial: if (index == 0) { return "n"; } else { return "p"; } - case Law::Type::Uniform: + case Type::Uniform: if (index == 0) { return "a"; } else { return "b"; } - case Law::Type::Exponential: + case Type::Exponential: return "l"; - case Law::Type::Normal: + case Type::Normal: if (index == 0) { return "u"; } else { return "o"; } - case Law::Type::Poisson: + case Type::Poisson: return "l"; default: return 0; @@ -71,27 +162,27 @@ const char * Law::parameterNameAtIndex(int index) { const char * Law::parameterDefinitionAtIndex(int index) { assert(index >= 0 && index < 2); switch (m_type) { - case Law::Type::Binomial: + case Type::Binomial: if (index == 0) { return "n : nombre de repetitions"; } else { return "p : probabilites de succes"; } - case Law::Type::Uniform: + case Type::Uniform: if (index == 0) { return "[a, b] intervalle"; } else { return nullptr; } - case Law::Type::Exponential: + case Type::Exponential: return "l : parametre"; - case Law::Type::Normal: + case Type::Normal: if (index == 0) { return "u : moyenne"; } else { return "o : ecart-type"; } - case Law::Type::Poisson: + case Type::Poisson: return "l : parametre"; default: return 0; @@ -102,38 +193,42 @@ void Law::setParameterAtIndex(float f, int index) { assert(index >= 0 && index < 2); if (index == 0) { m_parameter1 = f; - return; + m_evaluateContext->setOverridenValueForFirstParameter(f); + } else { + m_parameter2 = f; + m_evaluateContext->setOverridenValueForSecondParameter(f); } - m_parameter2 = f; + setWindow(); } -float Law::evaluateAtAbscissa(float x, Graph::EvaluateContext * context) const { - context->setOverridenValueForSymbolX(x); +float Law::evaluateAtAbscissa(float t, EvaluateContext * context) const { + context->setOverridenValueForSymbolT(t); return m_expression->approximate(*context); } -Law::Type Law::type() const { - return m_type; -} - -void Law::setType(Type type) { - m_type = type; -} - -bool Law::isContinuous() { +void Law::setWindow() { switch (m_type) { - case Law::Type::Binomial: - return false; - case Law::Type::Uniform: - return true; - case Law::Type::Exponential: - return true; - case Law::Type::Normal: - return true; - case Law::Type::Poisson: - return false; + 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 false; + return; } } diff --git a/apps/probability/law.h b/apps/probability/law.h index 13c14fbf5..cac564837 100644 --- a/apps/probability/law.h +++ b/apps/probability/law.h @@ -1,7 +1,7 @@ #ifndef PROBABILITE_LAW_H #define PROBABILITE_LAW_H -#include "../graph/evaluate_context.h" +#include "evaluate_context.h" namespace Probability { @@ -15,24 +15,34 @@ public: Normal, Poisson }; - Law(); + Law(EvaluateContext * evaluateContext); + ~Law(); + EvaluateContext * evaluateContext(); + void setType(Type type); + Type type() const; + Expression * expression(); + bool isContinuous(); + float xMin(); + float yMin(); + float xMax(); + float yMax(); 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, Graph::EvaluateContext * context) const; - Type type() const; - void setType(Type type); - bool isContinuous(); + float evaluateAtAbscissa(float x, EvaluateContext * context) const; private: + void setWindow(); Type m_type; float m_parameter1; float m_parameter2; Expression * m_expression; float m_xMin; float m_xMax; - + float m_yMin; + float m_yMax; + EvaluateContext * m_evaluateContext; }; } diff --git a/apps/probability/law_controller.cpp b/apps/probability/law_controller.cpp index 70bc77483..ff96ddd1d 100644 --- a/apps/probability/law_controller.cpp +++ b/apps/probability/law_controller.cpp @@ -22,10 +22,11 @@ static const char * sMessages[] = { "Poisson" }; -LawController::LawController(Responder * parentResponder) : +LawController::LawController(Responder * parentResponder, EvaluateContext * evaluateContext) : 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_messages = sMessages; diff --git a/apps/probability/law_controller.h b/apps/probability/law_controller.h index af3d1c484..81fe12be3 100644 --- a/apps/probability/law_controller.h +++ b/apps/probability/law_controller.h @@ -5,12 +5,13 @@ #include "cell.h" #include "law.h" #include "parameters_controller.h" +#include "evaluate_context.h" namespace Probability { class LawController : public ViewController, public SimpleListViewDataSource { public: - LawController(Responder * parentResponder); + LawController(Responder * parentResponder, EvaluateContext * EvaluateContext); View * view() override; const char * title() const override; bool handleEvent(Ion::Events::Event event) override;