diff --git a/lib/src/Uncertainty/Distribution/AliMikhailHaqCopulaFactory.cxx b/lib/src/Uncertainty/Distribution/AliMikhailHaqCopulaFactory.cxx index 21af267a76..ab3b6449a7 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 61127592ea..e72ee20521 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 0161607169..dd4889e529 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 a1d1e0b3aa..8e53517e55 100644 --- a/lib/src/Uncertainty/Distribution/BetaFactory.cxx +++ b/lib/src/Uncertainty/Distribution/BetaFactory.cxx @@ -75,7 +75,9 @@ 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())); + 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 916624dbb0..409d26fb8f 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 fe8916cc47..f4460e5228 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 9b699afec9..2ebf9a65d7 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 2609b0ad38..c6707a6ae3 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 c79384dcff..50b3f06b48 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 b478a97e27..80aa376850 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 01f4cd1ae1..ba10657eec 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 81e8dabcfa..79dffffdad 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 a7eb5d238c..dcd7c0d183 100644 --- a/lib/src/Uncertainty/Distribution/FisherSnedecorFactory.cxx +++ b/lib/src/Uncertainty/Distribution/FisherSnedecorFactory.cxx @@ -105,6 +105,7 @@ FisherSnedecor FisherSnedecorFactory::buildMethodOfLikelihoodMaximization(const // Configure bounds Interval bounds(parametersLowerBound, Point(dimension, SpecFunc::MaxScalar), Interval::BoolCollection(dimension, true), Interval::BoolCollection(dimension, false)); factory.setOptimizationBounds(bounds); + 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 31c66c87b4..ad7f0ce4b5 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 ba322ff4bc..c29b6f5ee0 100644 --- a/lib/src/Uncertainty/Distribution/FrechetFactory.cxx +++ b/lib/src/Uncertainty/Distribution/FrechetFactory.cxx @@ -95,6 +95,7 @@ Frechet FrechetFactory::buildAsFrechet(const Sample & sample) const 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)); + 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 ba9da999d2..2a2c7d179b 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 61715124e1..91da9acb7a 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 ba801bfe1a..5ef73c8a3c 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 b1d4795475..0c010f03ce 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 d7791800a8..4f327cc02e 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 f17b4a7421..2b0b361aa9 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 149ebff94f..32e03b9fd3 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,28 +297,6 @@ 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 { diff --git a/lib/src/Uncertainty/Distribution/LogNormalFactory.cxx b/lib/src/Uncertainty/Distribution/LogNormalFactory.cxx index c68d4ebc3b..be40c0229a 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 772cf2b89e..2386cae606 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 b0ce952c8a..15e911c503 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 d5c2633a01..2ae243c279 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()); @@ -395,31 +398,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_); } @@ -428,8 +410,6 @@ 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_); } diff --git a/lib/src/Uncertainty/Distribution/MeixnerDistributionFactory.cxx b/lib/src/Uncertainty/Distribution/MeixnerDistributionFactory.cxx index 5e6056710b..656cb101d8 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 4cdbcc70eb..6884842098 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,8 +390,6 @@ void MethodOfMomentsFactory::save(Advocate & adv) const DistributionFactoryImplementation::save(adv); adv.saveAttribute("distribution_", distribution_); adv.saveAttribute("momentOrders_", momentOrders_); - adv.saveAttribute("knownParameterValues_", knownParameterValues_); - adv.saveAttribute("knownParameterIndices_", knownParameterIndices_); adv.saveAttribute("optimizationBounds_", optimizationBounds_); } @@ -412,8 +399,6 @@ 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_); } diff --git a/lib/src/Uncertainty/Distribution/MultinomialFactory.cxx b/lib/src/Uncertainty/Distribution/MultinomialFactory.cxx index 765cd5043f..87a2e1232c 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 0d394bf0aa..971318ac46 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 f5daa1ba36..516141e655 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 4fec3048cf..28c1691d0c 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 47d9f9bd6b..72606d2267 100644 --- a/lib/src/Uncertainty/Distribution/ParetoFactory.cxx +++ b/lib/src/Uncertainty/Distribution/ParetoFactory.cxx @@ -83,6 +83,7 @@ Pareto ParetoFactory::buildMethodOfMoments(const Sample & sample) const Pareto result(beta, alpha, gamma); result.setDescription(sample.getDescription()); + adaptToKnownParameter(sample, &result); return result; } diff --git a/lib/src/Uncertainty/Distribution/PlackettCopulaFactory.cxx b/lib/src/Uncertainty/Distribution/PlackettCopulaFactory.cxx index acaa7be8d4..8d2c97121c 100644 --- a/lib/src/Uncertainty/Distribution/PlackettCopulaFactory.cxx +++ b/lib/src/Uncertainty/Distribution/PlackettCopulaFactory.cxx @@ -70,7 +70,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 940a4cf18e..3ccbfbcd97 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 211f1cde44..1fd53e1f4d 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,8 +370,6 @@ 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_); } diff --git a/lib/src/Uncertainty/Distribution/RayleighFactory.cxx b/lib/src/Uncertainty/Distribution/RayleighFactory.cxx index f40ae5d3a3..405c9d2c82 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 f9198d45d2..5c085eb75b 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 01b7144473..b25040c789 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 592316c157..5328d070d1 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 ebcdc7f473..da4c66e04b 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 d283b4f58c..1a00d9d6af 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 3e6b354de0..9dabe55c72 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, min + rhoEnd); const Point upperBound(4, max - 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 7df44974f0..5ece34717f 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 5d158a90da..792cb15827 100644 --- a/lib/src/Uncertainty/Distribution/TruncatedNormalFactory.cxx +++ b/lib/src/Uncertainty/Distribution/TruncatedNormalFactory.cxx @@ -162,6 +162,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 db2a453c53..008b2ee482 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 576cc41e79..2582e3d469 100644 --- a/lib/src/Uncertainty/Distribution/VonMisesFactory.cxx +++ b/lib/src/Uncertainty/Distribution/VonMisesFactory.cxx @@ -178,6 +178,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 6ff45a34a2..1e186ed4c3 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 094e1898a0..c6f672146f 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 1e3d086793..8913eaad1d 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 d22f38e7d0..3c3e95f73b 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 10bbe09587..f2608dd36c 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 4dad033f7b..294efc0b67 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 becfa17e84..3a430e4d7a 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 e162d42510..ad82b8e911 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,8 @@ void DistributionFactoryImplementation::load(Advocate & adv) { PersistentObject::load(adv); adv.loadAttribute("bootstrapSize_", bootstrapSize_); + adv.loadAttribute("knownParameterValues_", knownParameterValues_); + 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 6afa01bd77..e548f972ae 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 4148f175a4..189f428f50 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 84ee506215..dc664abe09 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 d5d17c6850..5e96e35e66 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 cfd82b4567..0feb3cf37f 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 0c8fa98f19..ba256ac09e 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 9d2fc2d02c..8d279dc5f4 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 d3ff263f62..85796b2f6a 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.