diff --git a/apps/probability/app.cpp b/apps/probability/app.cpp index 7b840ce50..f2b9f981c 100644 --- a/apps/probability/app.cpp +++ b/apps/probability/app.cpp @@ -24,14 +24,11 @@ App::Snapshot::Snapshot() : m_calculation{}, m_activePage(Page::Distribution) { - new(m_distribution) BinomialDistribution(); - new(m_calculation) LeftIntegralCalculation(); - calculation()->setDistribution(distribution()); + initializeDistributionAndCalculation(); } App::Snapshot::~Snapshot() { - distribution()->~Distribution(); - calculation()->~Calculation(); + deleteDistributionAndCalculation(); } App * App::Snapshot::unpack(Container * container) { @@ -44,10 +41,8 @@ App::Descriptor * App::Snapshot::descriptor() { } void App::Snapshot::reset() { - distribution()->~Distribution(); - new(m_distribution) BinomialDistribution(); - calculation()->~Calculation(); - new(m_calculation) LeftIntegralCalculation(); + deleteDistributionAndCalculation(); + initializeDistributionAndCalculation(); m_activePage = Page::Distribution; } @@ -59,6 +54,16 @@ Calculation * App::Snapshot::calculation() { return (Calculation *)m_calculation; } +void App::Snapshot::deleteDistributionAndCalculation() { + distribution()->~Distribution(); + calculation()->~Calculation(); +} + +void App::Snapshot::initializeDistributionAndCalculation() { + new(m_distribution) BinomialDistribution(); + new(m_calculation) LeftIntegralCalculation(distribution()); +} + void App::Snapshot::setActivePage(Page activePage) { m_activePage = activePage; } diff --git a/apps/probability/app.h b/apps/probability/app.h index fcf41951a..afb9075a7 100644 --- a/apps/probability/app.h +++ b/apps/probability/app.h @@ -45,9 +45,14 @@ public: Calculation * calculation(); Page activePage(); void setActivePage(Page activePage); + private: constexpr static int k_distributionSizes[] = {sizeof(BinomialDistribution),sizeof(ExponentialDistribution), sizeof(NormalDistribution), sizeof(PoissonDistribution), sizeof(UniformDistribution), 0}; constexpr static size_t k_distributionSize = max(k_distributionSizes); + + void deleteDistributionAndCalculation(); + void initializeDistributionAndCalculation(); + char m_distribution[k_distributionSize]; constexpr static int k_calculationSizes[] = {sizeof(LeftIntegralCalculation),sizeof(FiniteIntegralCalculation), sizeof(RightIntegralCalculation), 0}; constexpr static size_t k_calculationSize = max(k_calculationSizes); diff --git a/apps/probability/calculation/calculation.cpp b/apps/probability/calculation/calculation.cpp index f45f31460..a059a938e 100644 --- a/apps/probability/calculation/calculation.cpp +++ b/apps/probability/calculation/calculation.cpp @@ -4,11 +4,6 @@ namespace Probability { -void Calculation::setDistribution(Distribution * distribution) { - m_distribution = distribution; - compute(0); -} - double Calculation::lowerBound() { return -INFINITY; } diff --git a/apps/probability/calculation/calculation.h b/apps/probability/calculation/calculation.h index 215daece6..f7847dba4 100644 --- a/apps/probability/calculation/calculation.h +++ b/apps/probability/calculation/calculation.h @@ -13,10 +13,11 @@ public: RightIntegral, Discrete, }; - Calculation() : m_distribution(nullptr) {} + Calculation(Distribution * distribution) : m_distribution(distribution) { + assert(distribution != nullptr); + } virtual ~Calculation() = default; virtual Type type() = 0; - void setDistribution(Distribution * distribution); virtual int numberOfParameters() = 0; virtual I18n::Message legendForParameterAtIndex(int index) = 0; virtual void setParameterAtIndex(double f, int index) = 0; diff --git a/apps/probability/calculation/discrete_calculation.cpp b/apps/probability/calculation/discrete_calculation.cpp index 075038512..798281e70 100644 --- a/apps/probability/calculation/discrete_calculation.cpp +++ b/apps/probability/calculation/discrete_calculation.cpp @@ -5,10 +5,9 @@ namespace Probability { -DiscreteCalculation::DiscreteCalculation() : - Calculation(), - m_abscissa(0.0), - m_result(0.0) +DiscreteCalculation::DiscreteCalculation(Distribution * distribution) : + Calculation(distribution), + m_abscissa(distribution->defaultComputedValue()) { compute(0); } diff --git a/apps/probability/calculation/discrete_calculation.h b/apps/probability/calculation/discrete_calculation.h index 6bf1b332a..9ca655e94 100644 --- a/apps/probability/calculation/discrete_calculation.h +++ b/apps/probability/calculation/discrete_calculation.h @@ -7,7 +7,7 @@ namespace Probability { class DiscreteCalculation final : public Calculation { public: - DiscreteCalculation(); + DiscreteCalculation(Distribution * distribution); Type type() override { return Type::Discrete; } int numberOfParameters() override { return 2; } I18n::Message legendForParameterAtIndex(int index) override; diff --git a/apps/probability/calculation/finite_integral_calculation.cpp b/apps/probability/calculation/finite_integral_calculation.cpp index a1ac5d9c8..2341bc15b 100644 --- a/apps/probability/calculation/finite_integral_calculation.cpp +++ b/apps/probability/calculation/finite_integral_calculation.cpp @@ -6,11 +6,10 @@ namespace Probability { -FiniteIntegralCalculation::FiniteIntegralCalculation() : - Calculation(), - m_lowerBound(0.0), - m_upperBound(1.0), - m_result(0.0) +FiniteIntegralCalculation::FiniteIntegralCalculation(Distribution * distribution) : + Calculation(distribution), + m_lowerBound(distribution->defaultComputedValue()), + m_upperBound(m_lowerBound + 1.0) { compute(0); } diff --git a/apps/probability/calculation/finite_integral_calculation.h b/apps/probability/calculation/finite_integral_calculation.h index ccbd2afd0..fbbb867ac 100644 --- a/apps/probability/calculation/finite_integral_calculation.h +++ b/apps/probability/calculation/finite_integral_calculation.h @@ -7,7 +7,7 @@ namespace Probability { class FiniteIntegralCalculation : public Calculation { public: - FiniteIntegralCalculation(); + FiniteIntegralCalculation(Distribution * distribution); Type type() override { return Type::FiniteIntegral; } int numberOfParameters() override { return 3; } I18n::Message legendForParameterAtIndex(int index) override; diff --git a/apps/probability/calculation/left_integral_calculation.cpp b/apps/probability/calculation/left_integral_calculation.cpp index f589ce4e8..d24430b74 100644 --- a/apps/probability/calculation/left_integral_calculation.cpp +++ b/apps/probability/calculation/left_integral_calculation.cpp @@ -5,10 +5,9 @@ namespace Probability { -LeftIntegralCalculation::LeftIntegralCalculation() : - Calculation(), - m_upperBound(0.0), - m_result(0.0) +LeftIntegralCalculation::LeftIntegralCalculation(Distribution * distribution) : + Calculation(distribution), + m_upperBound(distribution->defaultComputedValue()) { compute(0); } diff --git a/apps/probability/calculation/left_integral_calculation.h b/apps/probability/calculation/left_integral_calculation.h index f998cdb12..032a52581 100644 --- a/apps/probability/calculation/left_integral_calculation.h +++ b/apps/probability/calculation/left_integral_calculation.h @@ -7,7 +7,7 @@ namespace Probability { class LeftIntegralCalculation final : public Calculation { public: - LeftIntegralCalculation(); + LeftIntegralCalculation(Distribution * distribution); Type type() override { return Type::LeftIntegral; } int numberOfParameters() override { return 2; } I18n::Message legendForParameterAtIndex(int index) override; diff --git a/apps/probability/calculation/right_integral_calculation.cpp b/apps/probability/calculation/right_integral_calculation.cpp index 08903df47..068fe3552 100644 --- a/apps/probability/calculation/right_integral_calculation.cpp +++ b/apps/probability/calculation/right_integral_calculation.cpp @@ -5,10 +5,9 @@ namespace Probability { -RightIntegralCalculation::RightIntegralCalculation() : - Calculation(), - m_lowerBound(0.0), - m_result(0.0) +RightIntegralCalculation::RightIntegralCalculation(Distribution * distribution) : + Calculation(distribution), + m_lowerBound(distribution->defaultComputedValue()) { compute(0); } diff --git a/apps/probability/calculation/right_integral_calculation.h b/apps/probability/calculation/right_integral_calculation.h index 71f1e5530..9cb8f001d 100644 --- a/apps/probability/calculation/right_integral_calculation.h +++ b/apps/probability/calculation/right_integral_calculation.h @@ -7,7 +7,7 @@ namespace Probability { class RightIntegralCalculation final : public Calculation { public: - RightIntegralCalculation(); + RightIntegralCalculation(Distribution * distribution); Type type() override { return Type::RightIntegral; } int numberOfParameters() override { return 2; } I18n::Message legendForParameterAtIndex(int index) override; diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index a0782cdf3..2869f5abf 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -251,21 +251,20 @@ void CalculationController::setCalculationAccordingToIndex(int index, bool force m_calculation->~Calculation(); switch (index) { case 0: - new(m_calculation) LeftIntegralCalculation(); - break; + new(m_calculation) LeftIntegralCalculation(m_distribution); + return; case 1: - new(m_calculation) FiniteIntegralCalculation(); - break; + new(m_calculation) FiniteIntegralCalculation(m_distribution); + return; case 2: - new(m_calculation) RightIntegralCalculation(); - break; + new(m_calculation) RightIntegralCalculation(m_distribution); + return; case 3: - new(m_calculation) DiscreteCalculation(); - break; + new(m_calculation) DiscreteCalculation(m_distribution); + return; default: return; } - m_calculation->setDistribution(m_distribution); } void CalculationController::updateTitle() { diff --git a/apps/probability/distribution/distribution.h b/apps/probability/distribution/distribution.h index 95575ed43..e7e9d5332 100644 --- a/apps/probability/distribution/distribution.h +++ b/apps/probability/distribution/distribution.h @@ -39,6 +39,7 @@ public: virtual double rightIntegralInverseForProbability(double * probability); virtual double evaluateAtDiscreteAbscissa(int k) const; constexpr static int k_maxNumberOfOperations = 1000000; + virtual double defaultComputedValue() const { return 0.0f; } protected: static_assert(Poincare::Preferences::LargeNumberOfSignificantDigits == 7, "k_maxProbability is ill-defined compared to LargeNumberOfSignificantDigits"); constexpr static double k_maxProbability = 0.9999995; diff --git a/apps/probability/distribution/geometric_distribution.h b/apps/probability/distribution/geometric_distribution.h index e6903555a..e3323abfa 100644 --- a/apps/probability/distribution/geometric_distribution.h +++ b/apps/probability/distribution/geometric_distribution.h @@ -30,6 +30,7 @@ public: return templatedApproximateAtAbscissa(x); } bool authorizedValueAtIndex(float x, int index) const override; + double defaultComputedValue() const override { return 1.0f; } private: double evaluateAtDiscreteAbscissa(int k) const override { return templatedApproximateAtAbscissa((double)k);