From 20bca8ab195c6eddff29c7e7258a199121e1ad21 Mon Sep 17 00:00:00 2001 From: regislebrun Date: Sun, 2 Jun 2024 15:10:30 +0200 Subject: [PATCH] Improved DistributionFactory Now the user can fix the value of an arbitrary subset of parameters and estimate the others by MLE in all the factories. --- .../AliMikhailHaqCopulaFactory.cxx | 1 + .../Distribution/ArcsineFactory.cxx | 1 + .../Distribution/BernoulliFactory.cxx | 1 + .../Uncertainty/Distribution/BetaFactory.cxx | 5 +- .../Distribution/BinomialFactory.cxx | 1 + .../Uncertainty/Distribution/BurrFactory.cxx | 1 + .../Uncertainty/Distribution/ChiFactory.cxx | 1 + .../Distribution/ChiSquareFactory.cxx | 1 + .../Distribution/ClaytonCopulaFactory.cxx | 1 + .../Distribution/DirichletFactory.cxx | 1 + .../Distribution/ExponentialFactory.cxx | 2 + .../FarlieGumbelMorgensternCopulaFactory.cxx | 1 + .../Distribution/FisherSnedecorFactory.cxx | 6 +- .../Distribution/FrankCopulaFactory.cxx | 1 + .../Distribution/FrechetFactory.cxx | 5 +- .../Uncertainty/Distribution/GammaFactory.cxx | 1 + .../Distribution/GeometricFactory.cxx | 1 + .../Distribution/GumbelCopulaFactory.cxx | 1 + .../Distribution/GumbelFactory.cxx | 1 + .../Distribution/InverseNormalFactory.cxx | 1 + .../Distribution/LaplaceFactory.cxx | 1 + .../LeastSquaresDistributionFactory.cxx | 35 +++-------- .../Distribution/LogNormalFactory.cxx | 19 ++++-- .../Distribution/LogUniformFactory.cxx | 1 + .../Distribution/LogisticFactory.cxx | 1 + .../Distribution/MaximumLikelihoodFactory.cxx | 30 +++------ .../MeixnerDistributionFactory.cxx | 1 + .../Distribution/MethodOfMomentsFactory.cxx | 35 ++++------- .../Distribution/MultinomialFactory.cxx | 1 + .../Distribution/NegativeBinomialFactory.cxx | 1 + .../Distribution/NormalCopulaFactory.cxx | 1 + .../Distribution/NormalFactory.cxx | 1 + .../Distribution/ParetoFactory.cxx | 12 ++-- .../Distribution/PlackettCopulaFactory.cxx | 6 +- .../Distribution/PoissonFactory.cxx | 1 + .../Distribution/QuantileMatchingFactory.cxx | 38 ++++-------- .../Distribution/RayleighFactory.cxx | 1 + .../Uncertainty/Distribution/RiceFactory.cxx | 1 + .../Distribution/SkellamFactory.cxx | 1 + .../Distribution/SmoothedUniformFactory.cxx | 3 +- .../Distribution/StudentCopulaFactory.cxx | 5 +- .../Distribution/StudentFactory.cxx | 1 + .../Distribution/TrapezoidalFactory.cxx | 1 + .../Distribution/TriangularFactory.cxx | 1 + .../Distribution/TruncatedNormalFactory.cxx | 1 + .../Distribution/UniformFactory.cxx | 1 + .../Distribution/VonMisesFactory.cxx | 1 + .../Distribution/WeibullMaxFactory.cxx | 11 +++- .../Distribution/WeibullMinFactory.cxx | 4 +- .../LeastSquaresDistributionFactory.hxx | 9 --- .../openturns/MaximumLikelihoodFactory.hxx | 9 --- .../openturns/MethodOfMomentsFactory.hxx | 9 --- .../openturns/QuantileMatchingFactory.hxx | 9 --- .../Uncertainty/Model/DistributionFactory.cxx | 18 ++++++ .../DistributionFactoryImplementation.cxx | 36 +++++++++++ .../Model/openturns/DistributionFactory.hxx | 5 ++ .../DistributionFactoryImplementation.hxx | 11 ++++ ...DistributionFactoryImplementation_doc.i.in | 61 +++++++++++++++++++ python/src/DistributionFactory_doc.i.in | 6 ++ .../LeastSquaresDistributionFactory_doc.i.in | 42 ------------- python/src/MaximumLikelihoodFactory_doc.i.in | 52 ---------------- python/src/MethodOfMomentsFactory_doc.i.in | 44 ------------- python/src/QuantileMatchingFactory_doc.i.in | 20 ------ python/test/t_DistributionFactory_std.py | 56 +++++++++++++++-- 64 files changed, 323 insertions(+), 314 deletions(-) diff --git a/lib/src/Uncertainty/Distribution/AliMikhailHaqCopulaFactory.cxx b/lib/src/Uncertainty/Distribution/AliMikhailHaqCopulaFactory.cxx index 21af267a76f..ab3b6449a77 100644 --- a/lib/src/Uncertainty/Distribution/AliMikhailHaqCopulaFactory.cxx +++ b/lib/src/Uncertainty/Distribution/AliMikhailHaqCopulaFactory.cxx @@ -109,6 +109,7 @@ AliMikhailHaqCopula AliMikhailHaqCopulaFactory::buildAsAliMikhailHaqCopula(const } AliMikhailHaqCopula result(theta); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/ArcsineFactory.cxx b/lib/src/Uncertainty/Distribution/ArcsineFactory.cxx index 61127592ea9..e72ee205216 100644 --- a/lib/src/Uncertainty/Distribution/ArcsineFactory.cxx +++ b/lib/src/Uncertainty/Distribution/ArcsineFactory.cxx @@ -76,6 +76,7 @@ Arcsine ArcsineFactory::buildAsArcsine(const Sample & sample) const parameters[1] = standardDeviation; Arcsine result(buildAsArcsine(ArcsineMuSigma()(parameters))); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/BernoulliFactory.cxx b/lib/src/Uncertainty/Distribution/BernoulliFactory.cxx index 01616071697..dd4889e5296 100644 --- a/lib/src/Uncertainty/Distribution/BernoulliFactory.cxx +++ b/lib/src/Uncertainty/Distribution/BernoulliFactory.cxx @@ -80,6 +80,7 @@ Bernoulli BernoulliFactory::buildAsBernoulli(const Sample & sample) const } Bernoulli result(sum / size); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/BetaFactory.cxx b/lib/src/Uncertainty/Distribution/BetaFactory.cxx index a1d1e0b3aaf..79b4c2f53fa 100644 --- a/lib/src/Uncertainty/Distribution/BetaFactory.cxx +++ b/lib/src/Uncertainty/Distribution/BetaFactory.cxx @@ -75,7 +75,10 @@ Beta BetaFactory::buildAsBeta(const Sample & sample) const const Scalar mu = sample.computeMean()[0]; const Scalar sigma = sample.computeStandardDeviation()[0]; - return buildAsBeta(BetaMuSigma(mu, sigma, a, b).evaluate()); + Beta result(buildAsBeta(BetaMuSigma(mu, sigma, a, b).evaluate())); + result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); + return result; } Beta BetaFactory::buildAsBeta(const Point & parameters) const diff --git a/lib/src/Uncertainty/Distribution/BinomialFactory.cxx b/lib/src/Uncertainty/Distribution/BinomialFactory.cxx index 916624dbb06..409d26fb8f8 100644 --- a/lib/src/Uncertainty/Distribution/BinomialFactory.cxx +++ b/lib/src/Uncertainty/Distribution/BinomialFactory.cxx @@ -135,6 +135,7 @@ Binomial BinomialFactory::buildAsBinomial(const Sample & sample) const } Binomial result(maxN, mean / maxN); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/BurrFactory.cxx b/lib/src/Uncertainty/Distribution/BurrFactory.cxx index fe8916cc47b..f4460e52281 100644 --- a/lib/src/Uncertainty/Distribution/BurrFactory.cxx +++ b/lib/src/Uncertainty/Distribution/BurrFactory.cxx @@ -140,6 +140,7 @@ Burr BurrFactory::buildAsBurr(const Sample & sample) const const Scalar k = size / sumLogXC; Burr result(c, k); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/ChiFactory.cxx b/lib/src/Uncertainty/Distribution/ChiFactory.cxx index 9b699afec96..2ebf9a65d7e 100644 --- a/lib/src/Uncertainty/Distribution/ChiFactory.cxx +++ b/lib/src/Uncertainty/Distribution/ChiFactory.cxx @@ -78,6 +78,7 @@ Chi ChiFactory::buildAsChi(const Sample & sample) const { Chi result(sumSquares / size); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } catch (const InvalidArgumentException &) diff --git a/lib/src/Uncertainty/Distribution/ChiSquareFactory.cxx b/lib/src/Uncertainty/Distribution/ChiSquareFactory.cxx index 2609b0ad388..c6707a6ae3b 100644 --- a/lib/src/Uncertainty/Distribution/ChiSquareFactory.cxx +++ b/lib/src/Uncertainty/Distribution/ChiSquareFactory.cxx @@ -75,6 +75,7 @@ ChiSquare ChiSquareFactory::buildAsChiSquare(const Sample & sample) const if (xMin == xMax) throw InvalidArgumentException(HERE) << "Error: cannot estimate a ChiSquare distribution from a constant sample."; ChiSquare result(mean); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/ClaytonCopulaFactory.cxx b/lib/src/Uncertainty/Distribution/ClaytonCopulaFactory.cxx index c79384dcffb..50b3f06b483 100644 --- a/lib/src/Uncertainty/Distribution/ClaytonCopulaFactory.cxx +++ b/lib/src/Uncertainty/Distribution/ClaytonCopulaFactory.cxx @@ -66,6 +66,7 @@ ClaytonCopula ClaytonCopulaFactory::buildAsClaytonCopula(const Sample & sample) if (tau == 1) throw InvalidArgumentException(HERE) << "Error: cannot build a ClaytonCopula distribution from a sample with Kendall tau equal to 1"; ClaytonCopula result(2.0 * tau / (1.0 - tau)); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/DirichletFactory.cxx b/lib/src/Uncertainty/Distribution/DirichletFactory.cxx index b478a97e27d..80aa3768504 100644 --- a/lib/src/Uncertainty/Distribution/DirichletFactory.cxx +++ b/lib/src/Uncertainty/Distribution/DirichletFactory.cxx @@ -160,6 +160,7 @@ Dirichlet DirichletFactory::buildAsDirichlet(const Sample & sample) const } Dirichlet result(theta); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/ExponentialFactory.cxx b/lib/src/Uncertainty/Distribution/ExponentialFactory.cxx index 01f4cd1ae17..ba10657eec2 100644 --- a/lib/src/Uncertainty/Distribution/ExponentialFactory.cxx +++ b/lib/src/Uncertainty/Distribution/ExponentialFactory.cxx @@ -19,6 +19,7 @@ * */ #include "openturns/ExponentialFactory.hxx" +#include "openturns/MaximumLikelihoodFactory.hxx" #include "openturns/SpecFunc.hxx" #include "openturns/PersistentObjectFactory.hxx" @@ -73,6 +74,7 @@ Exponential ExponentialFactory::buildAsExponential(const Sample & sample) const const Scalar lambda = 1.0 / (mean - gamma); Exponential result(lambda, gamma); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/FarlieGumbelMorgensternCopulaFactory.cxx b/lib/src/Uncertainty/Distribution/FarlieGumbelMorgensternCopulaFactory.cxx index 81e8dabcfaa..79dffffdad7 100644 --- a/lib/src/Uncertainty/Distribution/FarlieGumbelMorgensternCopulaFactory.cxx +++ b/lib/src/Uncertainty/Distribution/FarlieGumbelMorgensternCopulaFactory.cxx @@ -76,6 +76,7 @@ FarlieGumbelMorgensternCopula FarlieGumbelMorgensternCopulaFactory::buildAsFarli } FarlieGumbelMorgensternCopula result(theta); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/FisherSnedecorFactory.cxx b/lib/src/Uncertainty/Distribution/FisherSnedecorFactory.cxx index 06f8a536321..989cec564df 100644 --- a/lib/src/Uncertainty/Distribution/FisherSnedecorFactory.cxx +++ b/lib/src/Uncertainty/Distribution/FisherSnedecorFactory.cxx @@ -101,8 +101,10 @@ FisherSnedecor FisherSnedecorFactory::buildMethodOfLikelihoodMaximization(const factory.setOptimizationAlgorithm(solver); // Configure bounds - Interval bounds(parametersLowerBound, Point(dimension, SpecFunc::MaxScalar), Interval::BoolCollection(dimension, true), Interval::BoolCollection(dimension, false)); - factory.setOptimizationBounds(bounds); + const Interval bounds(parametersLowerBound, Point(dimension, SpecFunc::MaxScalar), Interval::BoolCollection(dimension, true), Interval::BoolCollection(dimension, false)); + // Use bounds only for unknown parameters + factory.setOptimizationBounds(bounds.getMarginal(knownParameterIndices_.complement(bounds.getDimension()))); + factory.setKnownParameter(knownParameterValues_, knownParameterIndices_); return buildAsFisherSnedecor(factory.buildParameter(sample)); } diff --git a/lib/src/Uncertainty/Distribution/FrankCopulaFactory.cxx b/lib/src/Uncertainty/Distribution/FrankCopulaFactory.cxx index 31c66c87b4c..ad7f0ce4b57 100644 --- a/lib/src/Uncertainty/Distribution/FrankCopulaFactory.cxx +++ b/lib/src/Uncertainty/Distribution/FrankCopulaFactory.cxx @@ -102,6 +102,7 @@ FrankCopula FrankCopulaFactory::buildAsFrankCopula(const Sample & sample) const theta = solver.solve(f, tau, minTheta, maxTheta, minTau, maxTau); FrankCopula result(isTauNegative ? -theta : theta); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/FrechetFactory.cxx b/lib/src/Uncertainty/Distribution/FrechetFactory.cxx index ba322ff4bc5..92fb0dbfe25 100644 --- a/lib/src/Uncertainty/Distribution/FrechetFactory.cxx +++ b/lib/src/Uncertainty/Distribution/FrechetFactory.cxx @@ -94,7 +94,10 @@ Frechet FrechetFactory::buildAsFrechet(const Sample & sample) const const Scalar margin = std::max(1.0, ResourceMap::GetAsScalar("FrechetFactory-BoundMargin")); const Point lower = {betaFrechet / margin, alphaFrechet / margin, gamma - margin * std::abs(gamma)}; const Point upper = {margin * betaFrechet, margin * alphaFrechet, gamma + margin * std::abs(gamma)}; - mleFactory.setOptimizationBounds(Interval(lower, upper)); + const Interval bounds(lower, upper); + // Use bounds only for unknown parameters + mleFactory.setOptimizationBounds(bounds.getMarginal(knownParameterIndices_.complement(bounds.getDimension()))); + mleFactory.setKnownParameter(knownParameterValues_, knownParameterIndices_); const Point parameters(mleFactory.buildParameter(sample)); return buildAsFrechet(parameters); } diff --git a/lib/src/Uncertainty/Distribution/GammaFactory.cxx b/lib/src/Uncertainty/Distribution/GammaFactory.cxx index ba9da999d22..2a2c7d179ba 100644 --- a/lib/src/Uncertainty/Distribution/GammaFactory.cxx +++ b/lib/src/Uncertainty/Distribution/GammaFactory.cxx @@ -75,6 +75,7 @@ Gamma GammaFactory::buildAsGamma(const Sample & sample) const lambda /= sigma; Gamma result(k, lambda, gamma); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/GeometricFactory.cxx b/lib/src/Uncertainty/Distribution/GeometricFactory.cxx index 61715124e12..91da9acb7a5 100644 --- a/lib/src/Uncertainty/Distribution/GeometricFactory.cxx +++ b/lib/src/Uncertainty/Distribution/GeometricFactory.cxx @@ -75,6 +75,7 @@ Geometric GeometricFactory::buildAsGeometric(const Sample & sample) const } Geometric result(size / sum); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/GumbelCopulaFactory.cxx b/lib/src/Uncertainty/Distribution/GumbelCopulaFactory.cxx index ba801bfe1a2..5ef73c8a3c5 100644 --- a/lib/src/Uncertainty/Distribution/GumbelCopulaFactory.cxx +++ b/lib/src/Uncertainty/Distribution/GumbelCopulaFactory.cxx @@ -66,6 +66,7 @@ GumbelCopula GumbelCopulaFactory::buildAsGumbelCopula(const Sample & sample) con if (tau == 1) throw InvalidArgumentException(HERE) << "Error: cannot build a GumbelCopula distribution from a sample with Kendall tau equal to 1"; GumbelCopula result(1.0 / (1.0 - tau)); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/GumbelFactory.cxx b/lib/src/Uncertainty/Distribution/GumbelFactory.cxx index b1d4795475f..0c010f03ce6 100644 --- a/lib/src/Uncertainty/Distribution/GumbelFactory.cxx +++ b/lib/src/Uncertainty/Distribution/GumbelFactory.cxx @@ -73,6 +73,7 @@ Gumbel GumbelFactory::buildAsGumbel(const Sample & sample) const const Point parameters = {mu, sigma}; Gumbel result(buildAsGumbel(GumbelMuSigma()(parameters))); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/InverseNormalFactory.cxx b/lib/src/Uncertainty/Distribution/InverseNormalFactory.cxx index d7791800a84..4f327cc02ea 100644 --- a/lib/src/Uncertainty/Distribution/InverseNormalFactory.cxx +++ b/lib/src/Uncertainty/Distribution/InverseNormalFactory.cxx @@ -87,6 +87,7 @@ InverseNormal InverseNormalFactory::buildAsInverseNormal(const Sample & sample) lambda = std::pow(mu, 3) / (sigma * sigma); InverseNormal result(mu, lambda); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/LaplaceFactory.cxx b/lib/src/Uncertainty/Distribution/LaplaceFactory.cxx index f17b4a74211..2b0b361aa9c 100644 --- a/lib/src/Uncertainty/Distribution/LaplaceFactory.cxx +++ b/lib/src/Uncertainty/Distribution/LaplaceFactory.cxx @@ -68,6 +68,7 @@ Laplace LaplaceFactory::buildAsLaplace(const Sample & sample) const if (tau == 0) throw InvalidArgumentException(HERE) << "Error: cannot build a Laplace distribution with infinite lambda."; Laplace result(mu, size / tau); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/LeastSquaresDistributionFactory.cxx b/lib/src/Uncertainty/Distribution/LeastSquaresDistributionFactory.cxx index 149ebff94fa..9b83a917e1e 100644 --- a/lib/src/Uncertainty/Distribution/LeastSquaresDistributionFactory.cxx +++ b/lib/src/Uncertainty/Distribution/LeastSquaresDistributionFactory.cxx @@ -189,6 +189,9 @@ Point LeastSquaresDistributionFactory::buildParameter(const Sample & sample) con if (knownParameterValues_.getSize() != knownParameterIndices_.getSize()) throw InvalidArgumentException(HERE) << "Error: known values size must match indices"; + // Quick return if all the parameter values are known + if (knownParameterValues_.getSize() == effectiveParameterSize) return knownParameterValues_; + LeastSquaresFactoryResidualEvaluation residualEvaluation(sample, distribution_, knownParameterValues_, knownParameterIndices_); Function residual(residualEvaluation.clone()); @@ -294,46 +297,26 @@ OptimizationAlgorithm LeastSquaresDistributionFactory::getOptimizationAlgorithm( return solver_; } -void LeastSquaresDistributionFactory::setKnownParameter(const Point & values, - const Indices & indices) -{ - if (values.getSize() != indices.getSize()) - throw InvalidArgumentException(HERE) << "Known parameters values and indices must have the same size"; - if (!indices.check(distribution_.getParameter().getSize())) - throw InvalidArgumentException(HERE) << "Know parameters indices must be < parameter dimension"; - knownParameterValues_ = values; - knownParameterIndices_ = indices; -} - -Indices LeastSquaresDistributionFactory::getKnownParameterIndices() const -{ - return knownParameterIndices_; -} - -Point LeastSquaresDistributionFactory::getKnownParameterValues() const -{ - return knownParameterValues_; -} - - /* Method save() stores the object through the StorageManager */ void LeastSquaresDistributionFactory::save(Advocate & adv) const { DistributionFactoryImplementation::save(adv); - adv.saveAttribute("knownParameterValues_", knownParameterValues_); - adv.saveAttribute("knownParameterIndices_", knownParameterIndices_); adv.saveAttribute("optimizationBounds_", optimizationBounds_); adv.saveAttribute("optimizationInequalityConstraint_", optimizationInequalityConstraint_); + adv.saveAttribute("knownParameterValues_", knownParameterValues_); + adv.saveAttribute("knownParameterIndices_", knownParameterIndices_); } /* Method load() reloads the object from the StorageManager */ void LeastSquaresDistributionFactory::load(Advocate & adv) { DistributionFactoryImplementation::load(adv); - adv.loadAttribute("knownParameterValues_", knownParameterValues_); - adv.loadAttribute("knownParameterIndices_", knownParameterIndices_); adv.loadAttribute("optimizationBounds_", optimizationBounds_); adv.loadAttribute("optimizationInequalityConstraint_", optimizationInequalityConstraint_); + if (adv.hasAttribute("knownParameterValues_")) + adv.loadAttribute("knownParameterValues_", knownParameterValues_); + if (adv.hasAttribute("knownParameterIndices_")) + adv.loadAttribute("knownParameterIndices_", knownParameterIndices_); } END_NAMESPACE_OPENTURNS diff --git a/lib/src/Uncertainty/Distribution/LogNormalFactory.cxx b/lib/src/Uncertainty/Distribution/LogNormalFactory.cxx index c68d4ebc3bb..be40c0229a3 100644 --- a/lib/src/Uncertainty/Distribution/LogNormalFactory.cxx +++ b/lib/src/Uncertainty/Distribution/LogNormalFactory.cxx @@ -231,41 +231,48 @@ LogNormal LogNormalFactory::buildAsLogNormal(const Sample & sample, const UnsignedInteger size = sample.getSize(); if (size < 3) throw InvalidArgumentException(HERE) << "Error: cannot build a LogNormal distribution from a sample of size < 3"; if (sample.getDimension() != 1) throw InvalidArgumentException(HERE) << "Error: can build a LogNormal distribution only from a sample of dimension 1, here dimension=" << sample.getDimension(); + LogNormal result; switch (method) { case 0: try { - return buildMethodOfLocalLikelihoodMaximization(sample); + result = buildMethodOfLocalLikelihoodMaximization(sample); + break; } catch (const InvalidArgumentException & ex) { // We switch to the moment estimate LOGWARN(OSS() << ex.what()); - return buildAsLogNormal(sample, 1); + result = buildAsLogNormal(sample, 1); + break; } break; case 1: try { - return buildMethodOfModifiedMoments(sample); + result = buildMethodOfModifiedMoments(sample); + break; } catch (const InvalidArgumentException & ex) { // We switch to the moment estimate LOGWARN(OSS() << ex.what()); - return buildAsLogNormal(sample, 2); + result = buildAsLogNormal(sample, 2); + break; } break; case 2: - return buildMethodOfMoments(sample); + result = buildMethodOfMoments(sample); break; case 3: - return buildMethodOfLeastSquares(sample); + result = buildMethodOfLeastSquares(sample); break; default: throw InvalidArgumentException(HERE) << "Error: invalid value=" << method << " for the key 'LogNormalFactory-EstimationMethod' in ResourceMap"; } + adaptToKnownParameter(sample, &result); + return result; } LogNormal LogNormalFactory::buildAsLogNormal(const Point & parameters) const diff --git a/lib/src/Uncertainty/Distribution/LogUniformFactory.cxx b/lib/src/Uncertainty/Distribution/LogUniformFactory.cxx index 772cf2b89e1..2386cae606d 100644 --- a/lib/src/Uncertainty/Distribution/LogUniformFactory.cxx +++ b/lib/src/Uncertainty/Distribution/LogUniformFactory.cxx @@ -76,6 +76,7 @@ LogUniform LogUniformFactory::buildAsLogUniform(const Sample & sample) const Scalar bLog = std::log(b); LogUniform result(aLog, bLog); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/LogisticFactory.cxx b/lib/src/Uncertainty/Distribution/LogisticFactory.cxx index b0ce952c8a3..15e911c5031 100644 --- a/lib/src/Uncertainty/Distribution/LogisticFactory.cxx +++ b/lib/src/Uncertainty/Distribution/LogisticFactory.cxx @@ -73,6 +73,7 @@ Logistic LogisticFactory::buildAsLogistic(const Sample & sample) const if (!(beta > 0.0)) throw InvalidArgumentException(HERE) << "Error: can build a Logistic distribution only if beta > 0.0, here beta=" << beta; Logistic result(mu, beta); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/MaximumLikelihoodFactory.cxx b/lib/src/Uncertainty/Distribution/MaximumLikelihoodFactory.cxx index f0bd4b91c0b..10d109f4b0d 100644 --- a/lib/src/Uncertainty/Distribution/MaximumLikelihoodFactory.cxx +++ b/lib/src/Uncertainty/Distribution/MaximumLikelihoodFactory.cxx @@ -287,6 +287,9 @@ Point MaximumLikelihoodFactory::buildParameter(const Sample & sample) const if (knownParameterValues_.getSize() != knownParameterIndices_.getSize()) throw InvalidArgumentException(HERE) << "Error: known values size must match indices"; + // Quick return if all the parameter values are known + if (knownParameterValues_.getSize() == effectiveParameterSize) return knownParameterValues_; + // Define evaluation LogLikelihoodEvaluation logLikelihoodWrapper(sample, distribution_, knownParameterValues_, knownParameterIndices_); Function logLikelihood(logLikelihoodWrapper.clone()); @@ -398,31 +401,10 @@ OptimizationAlgorithm MaximumLikelihoodFactory::getOptimizationAlgorithm() const return solver_; } -void MaximumLikelihoodFactory::setKnownParameter(const Point & values, - const Indices & indices) -{ - if (values.getSize() != indices.getSize()) - throw InvalidArgumentException(HERE) << "Known parameters values and indices must have the same size"; - knownParameterValues_ = values; - knownParameterIndices_ = indices; -} - -Indices MaximumLikelihoodFactory::getKnownParameterIndices() const -{ - return knownParameterIndices_; -} - -Point MaximumLikelihoodFactory::getKnownParameterValues() const -{ - return knownParameterValues_; -} - /* Method save() stores the object through the StorageManager */ void MaximumLikelihoodFactory::save(Advocate & adv) const { DistributionFactoryImplementation::save(adv); - adv.saveAttribute("knownParameterValues_", knownParameterValues_); - adv.saveAttribute("knownParameterIndices_", knownParameterIndices_); adv.saveAttribute("optimizationBounds_", optimizationBounds_); adv.saveAttribute("optimizationInequalityConstraint_", optimizationInequalityConstraint_); } @@ -431,10 +413,12 @@ void MaximumLikelihoodFactory::save(Advocate & adv) const void MaximumLikelihoodFactory::load(Advocate & adv) { DistributionFactoryImplementation::load(adv); - adv.loadAttribute("knownParameterValues_", knownParameterValues_); - adv.loadAttribute("knownParameterIndices_", knownParameterIndices_); adv.loadAttribute("optimizationBounds_", optimizationBounds_); adv.loadAttribute("optimizationInequalityConstraint_", optimizationInequalityConstraint_); + if (adv.hasAttribute("knownParameterValues_")) + adv.loadAttribute("knownParameterValues_", knownParameterValues_); + if (adv.hasAttribute("knownParameterIndices_")) + adv.loadAttribute("knownParameterIndices_", knownParameterIndices_); } diff --git a/lib/src/Uncertainty/Distribution/MeixnerDistributionFactory.cxx b/lib/src/Uncertainty/Distribution/MeixnerDistributionFactory.cxx index 5e6056710ba..656cb101d8f 100644 --- a/lib/src/Uncertainty/Distribution/MeixnerDistributionFactory.cxx +++ b/lib/src/Uncertainty/Distribution/MeixnerDistributionFactory.cxx @@ -76,6 +76,7 @@ MeixnerDistribution MeixnerDistributionFactory::buildAsMeixnerDistribution(const const Scalar mu = m - alpha * delta * std::tan(0.5 * beta); MeixnerDistribution result(alpha, beta, delta, mu); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/MethodOfMomentsFactory.cxx b/lib/src/Uncertainty/Distribution/MethodOfMomentsFactory.cxx index 4cdbcc70eb4..ccae09c1781 100644 --- a/lib/src/Uncertainty/Distribution/MethodOfMomentsFactory.cxx +++ b/lib/src/Uncertainty/Distribution/MethodOfMomentsFactory.cxx @@ -270,6 +270,14 @@ Distribution MethodOfMomentsFactory::buildFromMoments(const Point & moments) con if (optimizationBounds_.getDimension() && (optimizationBounds_.getDimension() != momentOrders_.getSize())) throw InvalidArgumentException(HERE) << "The bounds dimension must match the moments order size (" << momentOrders_.getSize() << ")"; + // Quick return if all the parameter values are known + if (knownParameterValues_.getSize() == parameterDimension) + { + Distribution result(distribution_); + result.setParameter(knownParameterValues_); + return result; + } + // Define evaluation const MethodOfMomentsEvaluation methodOfMomentsWrapper(moments, distribution_, momentOrders_, knownParameterValues_, knownParameterIndices_); Function momentsObjective(methodOfMomentsWrapper.clone()); @@ -357,25 +365,6 @@ Interval MethodOfMomentsFactory::getOptimizationBounds() const return optimizationBounds_; } -void MethodOfMomentsFactory::setKnownParameter(const Point & values, - const Indices & indices) -{ - if (values.getSize() != indices.getSize()) - throw InvalidArgumentException(HERE) << "Indices and values size must match"; - knownParameterValues_ = values; - knownParameterIndices_ = indices; -} - -Indices MethodOfMomentsFactory::getKnownParameterIndices() const -{ - return knownParameterIndices_; -} - -Point MethodOfMomentsFactory::getKnownParameterValues() const -{ - return knownParameterValues_; -} - /* Moments orders accessor */ void MethodOfMomentsFactory::setMomentOrders(const Indices & momentsOrders) { @@ -401,9 +390,9 @@ void MethodOfMomentsFactory::save(Advocate & adv) const DistributionFactoryImplementation::save(adv); adv.saveAttribute("distribution_", distribution_); adv.saveAttribute("momentOrders_", momentOrders_); + adv.saveAttribute("optimizationBounds_", optimizationBounds_); adv.saveAttribute("knownParameterValues_", knownParameterValues_); adv.saveAttribute("knownParameterIndices_", knownParameterIndices_); - adv.saveAttribute("optimizationBounds_", optimizationBounds_); } /* Method load() reloads the object from the StorageManager */ @@ -412,9 +401,11 @@ void MethodOfMomentsFactory::load(Advocate & adv) DistributionFactoryImplementation::load(adv); adv.loadAttribute("distribution_", distribution_); adv.loadAttribute("momentOrders_", momentOrders_); - adv.loadAttribute("knownParameterValues_", knownParameterValues_); - adv.loadAttribute("knownParameterIndices_", knownParameterIndices_); adv.loadAttribute("optimizationBounds_", optimizationBounds_); + if (adv.hasAttribute("knownParameterValues_")) + adv.loadAttribute("knownParameterValues_", knownParameterValues_); + if (adv.hasAttribute("knownParameterIndices_")) + adv.loadAttribute("knownParameterIndices_", knownParameterIndices_); } END_NAMESPACE_OPENTURNS diff --git a/lib/src/Uncertainty/Distribution/MultinomialFactory.cxx b/lib/src/Uncertainty/Distribution/MultinomialFactory.cxx index 765cd5043f5..87a2e1232c3 100644 --- a/lib/src/Uncertainty/Distribution/MultinomialFactory.cxx +++ b/lib/src/Uncertainty/Distribution/MultinomialFactory.cxx @@ -80,6 +80,7 @@ Multinomial MultinomialFactory::buildAsMultinomial(const Sample & sample) const p *= 1.0 / (maxSum * size); Multinomial result(maxSum, p); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/NegativeBinomialFactory.cxx b/lib/src/Uncertainty/Distribution/NegativeBinomialFactory.cxx index 0d394bf0aae..971318ac46a 100644 --- a/lib/src/Uncertainty/Distribution/NegativeBinomialFactory.cxx +++ b/lib/src/Uncertainty/Distribution/NegativeBinomialFactory.cxx @@ -141,6 +141,7 @@ NegativeBinomial NegativeBinomialFactory::buildAsNegativeBinomial(const Sample & const Scalar p = 1.0 / (r / mean + 1.0); NegativeBinomial result(r, p); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/NormalCopulaFactory.cxx b/lib/src/Uncertainty/Distribution/NormalCopulaFactory.cxx index f5daa1ba36b..516141e655a 100644 --- a/lib/src/Uncertainty/Distribution/NormalCopulaFactory.cxx +++ b/lib/src/Uncertainty/Distribution/NormalCopulaFactory.cxx @@ -80,6 +80,7 @@ NormalCopula NormalCopulaFactory::buildAsNormalCopula(const Sample & sample) con } NormalCopula result(R); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/NormalFactory.cxx b/lib/src/Uncertainty/Distribution/NormalFactory.cxx index 4fec3048cfb..28c1691d0c7 100644 --- a/lib/src/Uncertainty/Distribution/NormalFactory.cxx +++ b/lib/src/Uncertainty/Distribution/NormalFactory.cxx @@ -83,6 +83,7 @@ Normal NormalFactory::buildAsNormal(const Sample & sample) const const CovarianceMatrix covariance(sample.computeCovariance()); Normal result(mean, covariance); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/ParetoFactory.cxx b/lib/src/Uncertainty/Distribution/ParetoFactory.cxx index 47d9f9bd6b0..720e1b1eb07 100644 --- a/lib/src/Uncertainty/Distribution/ParetoFactory.cxx +++ b/lib/src/Uncertainty/Distribution/ParetoFactory.cxx @@ -82,14 +82,14 @@ Pareto ParetoFactory::buildMethodOfMoments(const Sample & sample) const const Scalar gamma = sample.computeMean()[0] - alpha * beta / (alpha - 1.0); Pareto result(beta, alpha, gamma); - result.setDescription(sample.getDescription()); return result; } Pareto ParetoFactory::buildMethodOfLikelihoodMaximization(const Sample & sample) const { const MaximumLikelihoodFactory factory(buildMethodOfMoments(sample)); - return buildAsPareto(factory.build(sample).getParameter()); + Pareto result(buildAsPareto(factory.build(sample).getParameter())); + return buildAsPareto(result.getParameter()); } Pareto ParetoFactory::buildMethodOfLeastSquares(const Sample & sample, const Scalar gamma) const @@ -211,11 +211,15 @@ Pareto ParetoFactory::buildMethodOfLeastSquares(const Sample & sample) const Pareto ParetoFactory::buildAsPareto(const Sample & sample) const { + Pareto result; #if defined(OPENTURNS_HAVE_CERES) || defined(OPENTURNS_HAVE_CMINPACK) - return buildMethodOfLeastSquares(sample); + result = buildAsPareto(buildMethodOfLeastSquares(sample).getParameter()); #else - return buildMethodOfLikelihoodMaximization(sample); + result = buildAsPareto(buildMethodOfLikelihoodMaximization(sample).getParameter()); #endif + result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); + return result; } Pareto ParetoFactory::buildAsPareto(const Point & parameters) const diff --git a/lib/src/Uncertainty/Distribution/PlackettCopulaFactory.cxx b/lib/src/Uncertainty/Distribution/PlackettCopulaFactory.cxx index 220717da19b..f1442187918 100644 --- a/lib/src/Uncertainty/Distribution/PlackettCopulaFactory.cxx +++ b/lib/src/Uncertainty/Distribution/PlackettCopulaFactory.cxx @@ -67,7 +67,11 @@ PlackettCopula PlackettCopulaFactory::buildAsPlackettCopula(const Sample & sampl if (sample.getDimension() != 2) throw InvalidArgumentException(HERE) << "Error: cannot build a PlackettCopula distribution from a sample of dimension not equal to 2"; const Scalar m = sample.computeEmpiricalCDF(sample.computeMedian()); const Scalar ratio = 1.0 / (0.5 / m - 1.0); - return PlackettCopula(ratio * ratio); + + PlackettCopula result(ratio * ratio); + result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); + return result; } PlackettCopula PlackettCopulaFactory::buildAsPlackettCopula(const Point & parameters) const diff --git a/lib/src/Uncertainty/Distribution/PoissonFactory.cxx b/lib/src/Uncertainty/Distribution/PoissonFactory.cxx index 940a4cf18e5..3ccbfbcd971 100644 --- a/lib/src/Uncertainty/Distribution/PoissonFactory.cxx +++ b/lib/src/Uncertainty/Distribution/PoissonFactory.cxx @@ -75,6 +75,7 @@ Poisson PoissonFactory::buildAsPoisson(const Sample & sample) const if (!(lambda > 0.0) || std::isinf(lambda)) throw InvalidArgumentException(HERE) << "Error: can build a poisson distribution only if lambda > 0, here lambda=" << lambda; Poisson result(lambda / size); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/QuantileMatchingFactory.cxx b/lib/src/Uncertainty/Distribution/QuantileMatchingFactory.cxx index 211f1cde44e..f405219428b 100644 --- a/lib/src/Uncertainty/Distribution/QuantileMatchingFactory.cxx +++ b/lib/src/Uncertainty/Distribution/QuantileMatchingFactory.cxx @@ -242,6 +242,14 @@ Distribution QuantileMatchingFactory::buildFromQuantiles(const Point & quantiles if (optimizationBounds_.getDimension() && (optimizationBounds_.getDimension() != probabilities_.getSize())) throw InvalidArgumentException(HERE) << "The bounds dimension must match the probabilities size (" << probabilities_.getSize() << ")"; + // Quick return if all the parameter values are known + if (knownParameterValues_.getSize() == parameterDimension) + { + Distribution result(distribution_); + result.setParameter(knownParameterValues_); + return result; + } + // Define evaluation const QuantileMatchingEvaluation quantileMatchingWrapper(quantiles, distribution_, probabilities_, knownParameterValues_, knownParameterIndices_); Function quantilesObjective(quantileMatchingWrapper.clone()); @@ -329,28 +337,6 @@ Interval QuantileMatchingFactory::getOptimizationBounds() const return optimizationBounds_; } -void QuantileMatchingFactory::setKnownParameter(const Point & values, - const Indices & indices) -{ - if (values.getSize() != indices.getSize()) - throw InvalidArgumentException(HERE) << "Indices and values size must match"; - const UnsignedInteger parameterDimension = distribution_.getParameterDimension(); - if (!indices.check(parameterDimension)) - throw InvalidArgumentException(HERE) << "Error: known indices cannot exceed parameter size"; - knownParameterValues_ = values; - knownParameterIndices_ = indices; -} - -Indices QuantileMatchingFactory::getKnownParameterIndices() const -{ - return knownParameterIndices_; -} - -Point QuantileMatchingFactory::getKnownParameterValues() const -{ - return knownParameterValues_; -} - void QuantileMatchingFactory::setProbabilities(const Point & probabilities) { const UnsignedInteger parameterDimension = distribution_.getParameterDimension(); @@ -375,8 +361,6 @@ void QuantileMatchingFactory::save(Advocate & adv) const DistributionFactoryImplementation::save(adv); adv.saveAttribute("distribution_", distribution_); adv.saveAttribute("probabilities_", probabilities_); - adv.saveAttribute("knownParameterValues_", knownParameterValues_); - adv.saveAttribute("knownParameterIndices_", knownParameterIndices_); adv.saveAttribute("optimizationBounds_", optimizationBounds_); } @@ -386,9 +370,11 @@ void QuantileMatchingFactory::load(Advocate & adv) DistributionFactoryImplementation::load(adv); adv.loadAttribute("distribution_", distribution_); adv.loadAttribute("probabilities_", probabilities_); - adv.loadAttribute("knownParameterValues_", knownParameterValues_); - adv.loadAttribute("knownParameterIndices_", knownParameterIndices_); adv.loadAttribute("optimizationBounds_", optimizationBounds_); + if (adv.hasAttribute("knownParameterValues_")) + adv.loadAttribute("knownParameterValues_", knownParameterValues_); + if (adv.hasAttribute("knownParameterIndices_")) + adv.loadAttribute("knownParameterIndices_", knownParameterIndices_); } END_NAMESPACE_OPENTURNS diff --git a/lib/src/Uncertainty/Distribution/RayleighFactory.cxx b/lib/src/Uncertainty/Distribution/RayleighFactory.cxx index f40ae5d3a39..405c9d2c823 100644 --- a/lib/src/Uncertainty/Distribution/RayleighFactory.cxx +++ b/lib/src/Uncertainty/Distribution/RayleighFactory.cxx @@ -80,6 +80,7 @@ Rayleigh RayleighFactory::buildAsRayleigh(const Sample & sample) const { Rayleigh result(std::sqrt(0.5 * sumSquares / size), gamma); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } catch (const InvalidArgumentException &) diff --git a/lib/src/Uncertainty/Distribution/RiceFactory.cxx b/lib/src/Uncertainty/Distribution/RiceFactory.cxx index f9198d45d25..5c085eb75b3 100644 --- a/lib/src/Uncertainty/Distribution/RiceFactory.cxx +++ b/lib/src/Uncertainty/Distribution/RiceFactory.cxx @@ -137,6 +137,7 @@ Rice RiceFactory::buildAsRice(const Sample & sample) const { Rice result(beta, nu); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } catch (const InvalidArgumentException &) diff --git a/lib/src/Uncertainty/Distribution/SkellamFactory.cxx b/lib/src/Uncertainty/Distribution/SkellamFactory.cxx index 01b71444738..b25040c789d 100644 --- a/lib/src/Uncertainty/Distribution/SkellamFactory.cxx +++ b/lib/src/Uncertainty/Distribution/SkellamFactory.cxx @@ -82,6 +82,7 @@ Skellam SkellamFactory::buildAsSkellam(const Sample & sample) const const Scalar lambda1 = 0.5 * (var + mean); Skellam result(lambda1, lambda2); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/SmoothedUniformFactory.cxx b/lib/src/Uncertainty/Distribution/SmoothedUniformFactory.cxx index 592316c1574..5328d070d1d 100644 --- a/lib/src/Uncertainty/Distribution/SmoothedUniformFactory.cxx +++ b/lib/src/Uncertainty/Distribution/SmoothedUniformFactory.cxx @@ -77,7 +77,8 @@ SmoothedUniform SmoothedUniformFactory::buildAsSmoothedUniform(const Sample & sa const Scalar sigma = std::sqrt(variance - delta * delta / 12.0); const SmoothedUniform initial(a, b, sigma); // finish the job with MLE - const MaximumLikelihoodFactory mleFactory(initial); + MaximumLikelihoodFactory mleFactory(initial); + mleFactory.setKnownParameter(knownParameterValues_, knownParameterIndices_); const Point parameters(mleFactory.buildParameter(sample)); return buildAsSmoothedUniform(parameters); } diff --git a/lib/src/Uncertainty/Distribution/StudentCopulaFactory.cxx b/lib/src/Uncertainty/Distribution/StudentCopulaFactory.cxx index ebcdc7f473d..da4c66e04bc 100644 --- a/lib/src/Uncertainty/Distribution/StudentCopulaFactory.cxx +++ b/lib/src/Uncertainty/Distribution/StudentCopulaFactory.cxx @@ -94,7 +94,10 @@ StudentCopula StudentCopulaFactory::buildAsStudentCopula(const Sample & sample) const Scalar nuMin = ResourceMap::GetAsScalar("StudentCopulaFactory-NuMin"); const Scalar nuMax = ResourceMap::GetAsScalar("StudentCopulaFactory-NuMax"); factory.setOptimizationBounds(Interval(nuMin, nuMax)); - return buildAsStudentCopula(factory.buildParameter(sample)); + model.setParameter(factory.buildParameter(sample)); + model.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &model); + return model; } StudentCopula StudentCopulaFactory::buildAsStudentCopula(const Point & parameters) const diff --git a/lib/src/Uncertainty/Distribution/StudentFactory.cxx b/lib/src/Uncertainty/Distribution/StudentFactory.cxx index d283b4f58c5..1a00d9d6af5 100644 --- a/lib/src/Uncertainty/Distribution/StudentFactory.cxx +++ b/lib/src/Uncertainty/Distribution/StudentFactory.cxx @@ -137,6 +137,7 @@ Student StudentFactory::buildAsStudent(const Sample & sample) const const Point sigma(stdev * std::sqrt(1.0 - 2.0 / nu)); Student result(nu, mu, sigma, R); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/TrapezoidalFactory.cxx b/lib/src/Uncertainty/Distribution/TrapezoidalFactory.cxx index 37dd4976bb3..82c5c443f02 100644 --- a/lib/src/Uncertainty/Distribution/TrapezoidalFactory.cxx +++ b/lib/src/Uncertainty/Distribution/TrapezoidalFactory.cxx @@ -112,6 +112,7 @@ Trapezoidal TrapezoidalFactory::buildAsTrapezoidal(const Sample & sample) const const Point lowerBound(4, xMin + rhoEnd); const Point upperBound(4, xMax - rhoEnd); factory.setOptimizationBounds(Interval(lowerBound, upperBound)); + factory.setKnownParameter(knownParameterValues_, knownParameterIndices_); Trapezoidal result(buildAsTrapezoidal(factory.buildParameter(sample))); result.setDescription(sample.getDescription()); return result; diff --git a/lib/src/Uncertainty/Distribution/TriangularFactory.cxx b/lib/src/Uncertainty/Distribution/TriangularFactory.cxx index 7df44974f00..5ece34717f0 100644 --- a/lib/src/Uncertainty/Distribution/TriangularFactory.cxx +++ b/lib/src/Uncertainty/Distribution/TriangularFactory.cxx @@ -76,6 +76,7 @@ Triangular TriangularFactory::buildAsTriangular(const Sample & sample) const const Scalar m = 3.0 * sample.computeMean()[0] - a - b; Triangular result(a, m, b); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/TruncatedNormalFactory.cxx b/lib/src/Uncertainty/Distribution/TruncatedNormalFactory.cxx index fe75bd186b8..cf7c80f89d5 100644 --- a/lib/src/Uncertainty/Distribution/TruncatedNormalFactory.cxx +++ b/lib/src/Uncertainty/Distribution/TruncatedNormalFactory.cxx @@ -169,6 +169,7 @@ TruncatedNormal TruncatedNormalFactory::buildMethodOfLikelihoodMaximization(cons throw InvalidArgumentException(HERE) << "Likelihood-optimized TruncatedNormal is not valid"; result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/UniformFactory.cxx b/lib/src/Uncertainty/Distribution/UniformFactory.cxx index db2a453c53e..008b2ee4823 100644 --- a/lib/src/Uncertainty/Distribution/UniformFactory.cxx +++ b/lib/src/Uncertainty/Distribution/UniformFactory.cxx @@ -74,6 +74,7 @@ Uniform UniformFactory::buildAsUniform(const Sample & sample) const const Scalar b = xMax + delta / (size + 2); Uniform result(a, b); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/VonMisesFactory.cxx b/lib/src/Uncertainty/Distribution/VonMisesFactory.cxx index e99bc502684..3b96b868b4f 100644 --- a/lib/src/Uncertainty/Distribution/VonMisesFactory.cxx +++ b/lib/src/Uncertainty/Distribution/VonMisesFactory.cxx @@ -176,6 +176,7 @@ VonMises VonMisesFactory::buildAsVonMises(const Sample & sample) const VonMises result(mu, kappa); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/WeibullMaxFactory.cxx b/lib/src/Uncertainty/Distribution/WeibullMaxFactory.cxx index 6ff45a34a2d..1e186ed4c3e 100644 --- a/lib/src/Uncertainty/Distribution/WeibullMaxFactory.cxx +++ b/lib/src/Uncertainty/Distribution/WeibullMaxFactory.cxx @@ -61,7 +61,16 @@ Distribution WeibullMaxFactory::build() const WeibullMax WeibullMaxFactory::buildAsWeibullMax(const Sample & sample) const { - const Distribution weibullMin(WeibullMinFactory().build(-1.0 * sample)); + WeibullMinFactory minFactory; + if (knownParameterValues_.getSize() > 0) + { + Point minParametersValues(knownParameterValues_); + for (UnsignedInteger i = 0; i < knownParameterIndices_.getSize(); ++i) + if (knownParameterIndices_[i] == 2) + minParametersValues[i] *= -1.0; + minFactory.setKnownParameter(minParametersValues, knownParameterIndices_); + } + const Distribution weibullMin(minFactory.build(-1.0 * sample)); Point parameter(weibullMin.getParameter()); parameter[2] *= -1.0;// location parameter (gamma) return buildAsWeibullMax(parameter); diff --git a/lib/src/Uncertainty/Distribution/WeibullMinFactory.cxx b/lib/src/Uncertainty/Distribution/WeibullMinFactory.cxx index 094e1898a0f..c6f672146f1 100644 --- a/lib/src/Uncertainty/Distribution/WeibullMinFactory.cxx +++ b/lib/src/Uncertainty/Distribution/WeibullMinFactory.cxx @@ -75,13 +75,15 @@ WeibullMin WeibullMinFactory::buildMethodOfMoments(const Sample & sample) const const Point parameters = {mean, sigma, gamma}; WeibullMin result(buildAsWeibullMin(WeibullMinMuSigma()(parameters))); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } WeibullMin WeibullMinFactory::buildMethodOfLikelihoodMaximization(const Sample & sample) const { LOGINFO("in WeibullMinFactory, using likelihood maximization"); - const MaximumLikelihoodFactory factory(buildMethodOfMoments(sample)); + MaximumLikelihoodFactory factory(buildMethodOfMoments(sample)); + factory.setKnownParameter(knownParameterValues_, knownParameterIndices_); return buildAsWeibullMin(factory.build(sample).getParameter()); } diff --git a/lib/src/Uncertainty/Distribution/openturns/LeastSquaresDistributionFactory.hxx b/lib/src/Uncertainty/Distribution/openturns/LeastSquaresDistributionFactory.hxx index 1e3d086793b..8913eaad1da 100644 --- a/lib/src/Uncertainty/Distribution/openturns/LeastSquaresDistributionFactory.hxx +++ b/lib/src/Uncertainty/Distribution/openturns/LeastSquaresDistributionFactory.hxx @@ -76,11 +76,6 @@ public: /** Accessor to inequality constraint */ void setOptimizationInequalityConstraint(const Function & optimizationInequalityConstraint); - /** Accessor to known parameter */ - void setKnownParameter(const Point & values, const Indices & positions); - Point getKnownParameterValues() const; - Indices getKnownParameterIndices() const; - /** Method save() stores the object through the StorageManager */ void save(Advocate & adv) const override; @@ -100,10 +95,6 @@ protected: // Inequality constraint used for parameter optimization Function optimizationInequalityConstraint_; - /* Known parameter */ - Point knownParameterValues_; - Indices knownParameterIndices_; - }; /* class LeastSquaresDistributionFactory */ diff --git a/lib/src/Uncertainty/Distribution/openturns/MaximumLikelihoodFactory.hxx b/lib/src/Uncertainty/Distribution/openturns/MaximumLikelihoodFactory.hxx index d22f38e7d0f..3c3e95f73b4 100644 --- a/lib/src/Uncertainty/Distribution/openturns/MaximumLikelihoodFactory.hxx +++ b/lib/src/Uncertainty/Distribution/openturns/MaximumLikelihoodFactory.hxx @@ -76,11 +76,6 @@ public: /** Accessor to inequality constraint */ void setOptimizationInequalityConstraint(const Function & optimizationInequalityConstraint); - /** Accessor to known parameter */ - void setKnownParameter(const Point & values, const Indices & positions); - Point getKnownParameterValues() const; - Indices getKnownParameterIndices() const; - /** Method save() stores the object through the StorageManager */ void save(Advocate & adv) const override; @@ -106,10 +101,6 @@ protected: // Inequality constraint used for parameter optimization Function optimizationInequalityConstraint_; - /* Known parameter */ - Point knownParameterValues_; - Indices knownParameterIndices_; - }; /* class MaximumLikelihoodFactory */ diff --git a/lib/src/Uncertainty/Distribution/openturns/MethodOfMomentsFactory.hxx b/lib/src/Uncertainty/Distribution/openturns/MethodOfMomentsFactory.hxx index 10bbe095875..f2608dd36c5 100644 --- a/lib/src/Uncertainty/Distribution/openturns/MethodOfMomentsFactory.hxx +++ b/lib/src/Uncertainty/Distribution/openturns/MethodOfMomentsFactory.hxx @@ -76,11 +76,6 @@ public: void setOptimizationBounds(const Interval & optimizationBounds); Interval getOptimizationBounds() const; - /** Accessor to known parameter */ - void setKnownParameter(const Point & values, const Indices & positions); - Point getKnownParameterValues() const; - Indices getKnownParameterIndices() const; - /** Moments orders accessor */ void setMomentOrders(const Indices & momentsOrders); Indices getMomentOrders() const; @@ -104,10 +99,6 @@ protected: /* Bounds used for parameter optimization */ Interval optimizationBounds_; - /* Known parameter */ - Point knownParameterValues_; - Indices knownParameterIndices_; - }; /* class MethodOfMomentsFactory */ diff --git a/lib/src/Uncertainty/Distribution/openturns/QuantileMatchingFactory.hxx b/lib/src/Uncertainty/Distribution/openturns/QuantileMatchingFactory.hxx index 4dad033f7bc..294efc0b67b 100644 --- a/lib/src/Uncertainty/Distribution/openturns/QuantileMatchingFactory.hxx +++ b/lib/src/Uncertainty/Distribution/openturns/QuantileMatchingFactory.hxx @@ -76,11 +76,6 @@ public: void setOptimizationBounds(const Interval & optimizationBounds); Interval getOptimizationBounds() const; - /** Accessor to known parameter */ - void setKnownParameter(const Point & values, const Indices & positions); - Point getKnownParameterValues() const; - Indices getKnownParameterIndices() const; - /** Accessor to fractiles */ void setProbabilities(const Point & probabilities); Point getProbabilities() const; @@ -103,10 +98,6 @@ protected: /* Bounds used for parameter optimization */ Interval optimizationBounds_; - /* Known parameter */ - Point knownParameterValues_; - Indices knownParameterIndices_; - }; /* class QuantileMatchingFactory */ diff --git a/lib/src/Uncertainty/Model/DistributionFactory.cxx b/lib/src/Uncertainty/Model/DistributionFactory.cxx index becfa17e844..3a430e4d7a5 100644 --- a/lib/src/Uncertainty/Model/DistributionFactory.cxx +++ b/lib/src/Uncertainty/Model/DistributionFactory.cxx @@ -243,4 +243,22 @@ DistributionFactoryResult DistributionFactory::buildEstimator(const Sample & sam return getImplementation()->buildEstimator(sample, parameters); } +void DistributionFactory::setKnownParameter(const Point & values, + const Indices & indices) +{ + copyOnWrite(); + getImplementation()->setKnownParameter(values, indices); +} + +Indices DistributionFactory::getKnownParameterIndices() const +{ + return getImplementation()->getKnownParameterIndices(); +} + +Point DistributionFactory::getKnownParameterValues() const +{ + return getImplementation()->getKnownParameterValues(); +} + + END_NAMESPACE_OPENTURNS diff --git a/lib/src/Uncertainty/Model/DistributionFactoryImplementation.cxx b/lib/src/Uncertainty/Model/DistributionFactoryImplementation.cxx index e162d425102..dc60201d870 100644 --- a/lib/src/Uncertainty/Model/DistributionFactoryImplementation.cxx +++ b/lib/src/Uncertainty/Model/DistributionFactoryImplementation.cxx @@ -22,6 +22,7 @@ #include "openturns/DistributionFactoryImplementation.hxx" #include "openturns/Exception.hxx" #include "openturns/BootstrapExperiment.hxx" +#include "openturns/MaximumLikelihoodFactory.hxx" #include "openturns/NormalFactory.hxx" #include "openturns/KernelSmoothing.hxx" #include "openturns/Normal.hxx" @@ -199,11 +200,42 @@ void DistributionFactoryImplementation::setBootstrapSize(const UnsignedInteger b } +void DistributionFactoryImplementation::setKnownParameter(const Point & values, + const Indices & indices) +{ + if (values.getSize() != indices.getSize()) + throw InvalidArgumentException(HERE) << "Known parameters values and indices must have the same size"; + knownParameterValues_ = values; + knownParameterIndices_ = indices; +} + +Indices DistributionFactoryImplementation::getKnownParameterIndices() const +{ + return knownParameterIndices_; +} + +Point DistributionFactoryImplementation::getKnownParameterValues() const +{ + return knownParameterValues_; +} + +void DistributionFactoryImplementation::adaptToKnownParameter(const Sample & sample, DistributionImplementation * distribution) const +{ + if (knownParameterValues_.getSize() > 0) + { + MaximumLikelihoodFactory factory(*distribution); + factory.setKnownParameter(knownParameterValues_, knownParameterIndices_); + distribution->setParameter(factory.build(sample).getParameter()); + } +} + /* Method save() stores the object through the StorageManager */ void DistributionFactoryImplementation::save(Advocate & adv) const { PersistentObject::save(adv); adv.saveAttribute("bootstrapSize_", bootstrapSize_); + adv.saveAttribute("knownParameterValues_", knownParameterValues_); + adv.saveAttribute("knownParameterIndices_", knownParameterIndices_); } /* Method load() reloads the object from the StorageManager */ @@ -211,6 +243,10 @@ void DistributionFactoryImplementation::load(Advocate & adv) { PersistentObject::load(adv); adv.loadAttribute("bootstrapSize_", bootstrapSize_); + if (adv.hasAttribute("knownParameterValues_")) + adv.loadAttribute("knownParameterValues_", knownParameterValues_); + if (adv.hasAttribute("knownParameterIndices_")) + adv.loadAttribute("knownParameterIndices_", knownParameterIndices_); } END_NAMESPACE_OPENTURNS diff --git a/lib/src/Uncertainty/Model/openturns/DistributionFactory.hxx b/lib/src/Uncertainty/Model/openturns/DistributionFactory.hxx index 6afa01bd776..e548f972ae2 100644 --- a/lib/src/Uncertainty/Model/openturns/DistributionFactory.hxx +++ b/lib/src/Uncertainty/Model/openturns/DistributionFactory.hxx @@ -73,6 +73,11 @@ public: virtual DistributionFactoryResult buildEstimator(const Sample & sample, const DistributionParameters & parameters) const; + /** Accessor to known parameter */ + void setKnownParameter(const Point & values, const Indices & positions); + Point getKnownParameterValues() const; + Indices getKnownParameterIndices() const; + /** Catalog of factories */ static DistributionFactoryCollection GetContinuousUniVariateFactories(); static DistributionFactoryCollection GetContinuousMultiVariateFactories(); diff --git a/lib/src/Uncertainty/Model/openturns/DistributionFactoryImplementation.hxx b/lib/src/Uncertainty/Model/openturns/DistributionFactoryImplementation.hxx index 4148f175a4c..189f428f509 100644 --- a/lib/src/Uncertainty/Model/openturns/DistributionFactoryImplementation.hxx +++ b/lib/src/Uncertainty/Model/openturns/DistributionFactoryImplementation.hxx @@ -74,6 +74,11 @@ public: UnsignedInteger getBootstrapSize() const; void setBootstrapSize(const UnsignedInteger bootstrapSize); + /** Accessor to known parameter */ + void setKnownParameter(const Point & values, const Indices & positions); + Point getKnownParameterValues() const; + Indices getKnownParameterIndices() const; + /** Method save() stores the object through the StorageManager */ void save(Advocate & adv) const override; @@ -84,9 +89,15 @@ protected: /* Bootstrap estimator */ virtual DistributionFactoryResult buildBootStrapEstimator(const Sample & sample, const Bool isGaussian = false) const; + /* Fit parameters taking into account known ones */ + void adaptToKnownParameter(const Sample & sample, DistributionImplementation * p_distribution) const; + /* Number of bootstrap resampling for covariance estimation */ UnsignedInteger bootstrapSize_; + /* Known parameter */ + Point knownParameterValues_; + Indices knownParameterIndices_; }; /* class DistributionFactoryImplementation */ diff --git a/python/src/DistributionFactoryImplementation_doc.i.in b/python/src/DistributionFactoryImplementation_doc.i.in index 84ee506215f..dc664abe095 100644 --- a/python/src/DistributionFactoryImplementation_doc.i.in +++ b/python/src/DistributionFactoryImplementation_doc.i.in @@ -102,3 +102,64 @@ size : int %feature("docstring") OT::DistributionFactoryImplementation::setBootstrapSize OT_DistributionFactory_setBootstrapSize_doc +// --------------------------------------------------------------------- + +%define OT_DistributionFactory_setKnownParameter_doc +"Accessor to the known parameters. + +Parameters +---------- +values : sequence of float + Values of known parameters. +positions : sequence of int + Indices of known parameters. + +Examples +-------- +When a subset of the parameter vector is known, the other parameters only have to be estimated +from data. + +In the following example, we consider a sample and want to fit +a :class:`~openturns.Beta` distribution. +We assume that the :math:`a` and :math:`b` parameters are known beforehand. +In this case, we set the third parameter (at index 2) to -1 +and the fourth parameter (at index 3) to 1. + +>>> import openturns as ot +>>> ot.RandomGenerator.SetSeed(0) +>>> distribution = ot.Beta(2.3, 2.2, -1.0, 1.0) +>>> sample = distribution.getSample(10) +>>> factory = ot.BetaFactory() +>>> # set (a,b) out of (r, t, a, b) +>>> factory.setKnownParameter([-1.0, 1.0], [2, 3]) +>>> inf_distribution = factory.build(sample)" +%enddef +%feature("docstring") OT::DistributionFactoryImplementation::setKnownParameter +OT_DistributionFactory_setKnownParameter_doc + +// --------------------------------------------------------------------- + +%define OT_DistributionFactory_getKnownParameterValues_doc +"Accessor to the known parameters values. + +Returns +------- +values : :class:`~openturns.Point` + Values of known parameters." +%enddef +%feature("docstring") OT::DistributionFactoryImplementation::getKnownParameterValues +OT_DistributionFactory_getKnownParameterValues_doc + +// --------------------------------------------------------------------- + +%define OT_DistributionFactory_getKnownParameterIndices_doc +"Accessor to the known parameters indices. + +Returns +------- +indices : :class:`~openturns.Indices` + Indices of the known parameters." +%enddef +%feature("docstring") OT::DistributionFactoryImplementation::getKnownParameterIndices +OT_DistributionFactory_getKnownParameterIndices_doc + diff --git a/python/src/DistributionFactory_doc.i.in b/python/src/DistributionFactory_doc.i.in index b4c435f6350..3ef246a9ff2 100644 --- a/python/src/DistributionFactory_doc.i.in +++ b/python/src/DistributionFactory_doc.i.in @@ -10,6 +10,12 @@ OT_DistributionFactory_buildEstimator_doc OT_DistributionFactory_getBootstrapSize_doc %feature("docstring") OT::DistributionFactory::setBootstrapSize OT_DistributionFactory_setBootstrapSize_doc +%feature("docstring") OT::DistributionFactory::setKnownParameter +OT_DistributionFactory_setKnownParameter_doc +%feature("docstring") OT::DistributionFactory::getKnownParameterValues +OT_DistributionFactory_getKnownParameterValues_doc +%feature("docstring") OT::DistributionFactory::getKnownParameterIndices +OT_DistributionFactory_getKnownParameterIndices_doc // --------------------------------------------------------------------- diff --git a/python/src/LeastSquaresDistributionFactory_doc.i.in b/python/src/LeastSquaresDistributionFactory_doc.i.in index cfd82b45679..0feb3cf37fc 100644 --- a/python/src/LeastSquaresDistributionFactory_doc.i.in +++ b/python/src/LeastSquaresDistributionFactory_doc.i.in @@ -87,45 +87,3 @@ Parameters inequalityConstraint : :class:`~openturns.Function` The inequality constraint used for numerical optimization of the likelihood." -// --------------------------------------------------------------------- - -%feature("docstring") OT::LeastSquaresDistributionFactory::setKnownParameter -"Accessor to the known parameters. - -Parameters ----------- -values : sequence of float - Values of fixed parameters. -indices : sequence of int - Indices of fixed parameters. - -Examples --------- ->>> import openturns as ot ->>> ot.RandomGenerator.SetSeed(0) ->>> distribution = ot.Beta(2.3, 4.5, -1.0, 1.0) ->>> sample = distribution.getSample(10) ->>> factory = ot.LeastSquaresDistributionFactory(ot.Beta()) ->>> # set (a,b) out of (r, t, a, b) ->>> factory.setKnownParameter([-1.0, 1.0], [2, 3]) ->>> inf_distribution = factory.build(sample)" - -// --------------------------------------------------------------------- - -%feature("docstring") OT::LeastSquaresDistributionFactory::getKnownParameterValues -"Accessor to the known parameters indices. - -Returns -------- -values : :class:`~openturns.Point` - Values of fixed parameters." - -// --------------------------------------------------------------------- - -%feature("docstring") OT::LeastSquaresDistributionFactory::getKnownParameterIndices -"Accessor to the known parameters indices. - -Returns -------- -indices : :class:`~openturns.Indices` - Indices of fixed parameters." diff --git a/python/src/MaximumLikelihoodFactory_doc.i.in b/python/src/MaximumLikelihoodFactory_doc.i.in index 0c8fa98f198..ba256ac09e3 100644 --- a/python/src/MaximumLikelihoodFactory_doc.i.in +++ b/python/src/MaximumLikelihoodFactory_doc.i.in @@ -103,58 +103,6 @@ inequalityConstraint : :class:`~openturns.Function` // --------------------------------------------------------------------- -%feature("docstring") OT::MaximumLikelihoodFactory::setKnownParameter -"Accessor to the known parameters. - -Parameters ----------- -values : sequence of float - Values of known parameters. -positions : sequence of int - Indices of known parameters. - -Examples --------- -When a subset of the parameter vector is known, the other parameters only have to be estimated -from data. - -In the following example, we consider a sample and want to fit -a :class:`~openturns.Beta` distribution. -We assume that the :math:`a` and :math:`b` parameters are known beforehand. -In this case, we set the third parameter (at index 2) to -1 -and the fourth parameter (at index 3) to 1. - ->>> import openturns as ot ->>> ot.RandomGenerator.SetSeed(0) ->>> distribution = ot.Beta(2.3, 2.2, -1.0, 1.0) ->>> sample = distribution.getSample(10) ->>> factory = ot.MaximumLikelihoodFactory(ot.Beta()) ->>> # set (a,b) out of (r, t, a, b) ->>> factory.setKnownParameter([-1.0, 1.0], [2, 3]) ->>> inf_distribution = factory.build(sample)" - -// --------------------------------------------------------------------- - -%feature("docstring") OT::MaximumLikelihoodFactory::getKnownParameterValues -"Accessor to the known parameters indices. - -Returns -------- -values : :class:`~openturns.Point` - Values of known parameters." - -// --------------------------------------------------------------------- - -%feature("docstring") OT::MaximumLikelihoodFactory::getKnownParameterIndices -"Accessor to the known parameters indices. - -Returns -------- -indices : :class:`~openturns.Indices` - Indices of the known parameters." - -// --------------------------------------------------------------------- - %feature("docstring") OT::MaximumLikelihoodFactory::BuildGaussianEstimator "Compute the asymptotic distribution of the parameters. diff --git a/python/src/MethodOfMomentsFactory_doc.i.in b/python/src/MethodOfMomentsFactory_doc.i.in index 9d2fc2d02c4..8d279dc5f4e 100644 --- a/python/src/MethodOfMomentsFactory_doc.i.in +++ b/python/src/MethodOfMomentsFactory_doc.i.in @@ -124,50 +124,6 @@ bounds : :class:`~openturns.Interval` // --------------------------------------------------------------------- -%feature("docstring") OT::MethodOfMomentsFactory::setKnownParameter -"Accessor to the known parameters. - -Parameters ----------- -values : sequence of float - Values of fixed parameters. -indices : sequence of int - Indices of fixed parameters. - -Examples --------- ->>> import openturns as ot ->>> ot.RandomGenerator.SetSeed(0) ->>> distribution = ot.Beta(2.3, 2.2, -1.0, 1.0) ->>> sample = distribution.getSample(10) ->>> orders = [3, 4] # skewness, kurtosis ->>> factory = ot.MethodOfMomentsFactory(ot.Beta(), orders) ->>> # set (a,b) out of (r, t, a, b) ->>> factory.setKnownParameter([-1.0, 1.0], [2, 3]) ->>> inf_distribution = factory.build(sample)" - -// --------------------------------------------------------------------- - -%feature("docstring") OT::MethodOfMomentsFactory::getKnownParameterValues -"Accessor to the known parameters indices. - -Returns -------- -values : :class:`~openturns.Point` - Values of fixed parameters." - -// --------------------------------------------------------------------- - -%feature("docstring") OT::MethodOfMomentsFactory::getKnownParameterIndices -"Accessor to the known parameters indices. - -Returns -------- -indices : :class:`~openturns.Indices` - Indices of fixed parameters." - -// --------------------------------------------------------------------- - %feature("docstring") OT::MethodOfMomentsFactory::buildFromMoments "Build from moments. diff --git a/python/src/QuantileMatchingFactory_doc.i.in b/python/src/QuantileMatchingFactory_doc.i.in index d3ff263f62d..85796b2f6ab 100644 --- a/python/src/QuantileMatchingFactory_doc.i.in +++ b/python/src/QuantileMatchingFactory_doc.i.in @@ -159,26 +159,6 @@ Examples // --------------------------------------------------------------------- -%feature("docstring") OT::QuantileMatchingFactory::getKnownParameterValues -"Accessor to the known parameters indices. - -Returns -------- -values : :class:`~openturns.Point` - The values of the fixed parameters." - -// --------------------------------------------------------------------- - -%feature("docstring") OT::QuantileMatchingFactory::getKnownParameterIndices -"Accessor to the known parameters indices. - -Returns -------- -indices : :class:`~openturns.Indices` - The indices of the fixed parameters." - -// --------------------------------------------------------------------- - %feature("docstring") OT::QuantileMatchingFactory::buildFromQuantiles "Build from given quantiles. diff --git a/python/test/t_DistributionFactory_std.py b/python/test/t_DistributionFactory_std.py index 7414948ce8b..7465ee54b6e 100755 --- a/python/test/t_DistributionFactory_std.py +++ b/python/test/t_DistributionFactory_std.py @@ -1,6 +1,7 @@ #! /usr/bin/env python import openturns as ot +import openturns.testing as ott print( "Continuous univariate factories=", @@ -34,8 +35,8 @@ dist = factory.build(sample) except Exception: ok = True - print("constant:", "ok" if ok else "fail") - assert ok, str(factory) + " vs const" + print("constant:", "ok" if ok else "fail") + assert ok, str(factory) + " vs const" # check if raises on sample with nan/inf for weird in ["nan", "inf"]: @@ -46,9 +47,56 @@ dist = factory.build(sample) except Exception: ok = True - print(weird + ":", "ok" if ok else "fail") - assert ok, str(factory) + " vs " + weird + print(weird + ":", "ok" if ok else "fail") + assert ok, str(factory) + " vs " + weird factory = ot.DistributionFactory.GetByName("PoissonFactory") print(factory) assert factory.getImplementation().__class__.__name__ == "PoissonFactory", "wrong name" + +# Now, test each factory for the partial estimation of any subset of its parameters + +params = { + "BetaFactory": 0.05, + "FisherSnedecorFactory": 0.25, + "LogisticFactory": 0.025, + "LogNormalFactory": 0.02, + "ParetoFactory": 0.15, + "RiceFactory": 0.3, + "StudentFactory": 0.15, + "StudentFactory": 0.15, + "TrapezoidalFactory": 1.0, + "TriangularFactory": 0.025, + "VonMisesFactory": 0.02, + "NegativeBinomialFactory": 0.05, +} + +for factory in factories: + print("factory=", factory) + try: + factoryName = factory.getImplementation().getClassName() + if factoryName in params: + eps = params[factoryName] + else: + eps = 0.01e100 + # Skip HistogramFactory because it is nonparametric, so the rebuilt distribution has a number of parameters different from the reference distribution + # Skip the MeixnerDistributionFactory because it takes ages to compute the parameters + if factoryName not in ["HistogramFactory", "MeixnerDistributionFactory"]: + # Reference distribution + refDistribution = factory.build() + sample = refDistribution.getSample(10000) + # Get the ref parameter + refParameter = refDistribution.getParameter() + n = len(refParameter) + for k in range(n): + # Generate all the combinations of known parameter + combinations = ot.Combinations(k, n).generate() + for combination in combinations: + indices = [int(x) for x in combination] + factory.setKnownParameter([refParameter[i] for i in indices], indices) + res = factory.build(sample) + resParameter = res.getParameter() + ott.assert_almost_equal(resParameter, refParameter, eps, eps) + except Exception: + print("Skip", factory, "no getClassName()") + pass