Skip to content

Add RIA, PMA, SORA based on https://github.com/l-brevault/RBDO_OT#48

Open
regislebrun wants to merge 1 commit into
openturns:masterfrom
regislebrun:RBDO
Open

Add RIA, PMA, SORA based on https://github.com/l-brevault/RBDO_OT#48
regislebrun wants to merge 1 commit into
openturns:masterfrom
regislebrun:RBDO

Conversation

@regislebrun

@regislebrun regislebrun commented Jul 8, 2026

Copy link
Copy Markdown
Member

https://github.com/l-brevault/RBDO_OT

Core classes:

  • RBDOProblem: define RBDO problems with objective, probabilistic constraint g(d,X,Z), distributions for X and Z, target reliability index, constraint operator (Less/Greater), and design/parameter dimension management
  • RIAAlgorithm: Reliability Index Approach using FORM to compute reliability indices; outer optimization minimizes f(d,p) subject to beta(d) >= beta_target
  • PMAAlgorithm: Performance Measure Approach using inverse FORM to compute performance measures for probabilistic constraints
  • SORAAlgorithm: Sequential Optimization and Reliability Analysis iterating between deterministic optimization with shifted constraints and inverse FORM

Thanks to Loic Brevault and Mathieu Balesdent for the RBDO_OT prototype and examples.

Summary by CodeRabbit

  • New Features

    • Added reliability-based design optimization support through RBDO problems and RIA, PMA, and SORA algorithms.
    • Added Python bindings for the new RBDO capabilities.
    • Added examples demonstrating analytical, structural, and mechanical RBDO applications.
  • Documentation

    • Added API documentation and user manual entries for RBDO features.
  • Bug Fixes

    • Improved internal function evaluation consistency across reliability and robustness measures.
    • Corrected uncertainty-dimension handling in sequential optimization utilities.
  • Tests

    • Added comprehensive C++ and Python coverage for RBDO problems and algorithms.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@regislebrun, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 52 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d05ba246-6c09-4add-a80d-6a29445ab469

📥 Commits

Reviewing files that changed from the base of the PR and between e0846ac and 3544e42.

📒 Files selected for processing (47)
  • .gitignore
  • lib/include/otrobopt/OTRobOpt.hxx
  • lib/src/CMakeLists.txt
  • lib/src/IndividualChanceMeasure.cxx
  • lib/src/JointChanceMeasure.cxx
  • lib/src/MeanMeasure.cxx
  • lib/src/MeanStandardDeviationTradeoffMeasure.cxx
  • lib/src/PMAAlgorithm.cxx
  • lib/src/QuantileMeasure.cxx
  • lib/src/RBDOProblem.cxx
  • lib/src/RIAAlgorithm.cxx
  • lib/src/SORAAlgorithm.cxx
  • lib/src/VarianceMeasure.cxx
  • lib/src/WorstCaseMeasure.cxx
  • lib/src/otrobopt/PMAAlgorithm.hxx
  • lib/src/otrobopt/RBDOProblem.hxx
  • lib/src/otrobopt/RIAAlgorithm.hxx
  • lib/src/otrobopt/SORAAlgorithm.hxx
  • lib/test/CMakeLists.txt
  • lib/test/t_MeasureFunction_std.cxx
  • lib/test/t_PMAAlgorithm_std.cxx
  • lib/test/t_RBDOProblem_std.cxx
  • lib/test/t_RIAAlgorithm_std.cxx
  • lib/test/t_RobustOptimizationAlgorithm_std.cxx
  • lib/test/t_RobustOptimizationProblem_std.cxx
  • lib/test/t_SORAAlgorithm_std.cxx
  • python/doc/examples/plot_example2.py
  • python/doc/examples/plot_rbdo_analytical_case1.py
  • python/doc/examples/plot_rbdo_comparison.py
  • python/doc/examples/plot_rbdo_short_column.py
  • python/doc/examples/plot_rbdo_spur_speed_reducer.py
  • python/doc/user_manual/user_manual.rst
  • python/src/PMAAlgorithm.i
  • python/src/PMAAlgorithm_doc.i
  • python/src/RBDOProblem.i
  • python/src/RBDOProblem_doc.i
  • python/src/RIAAlgorithm.i
  • python/src/RIAAlgorithm_doc.i
  • python/src/SORAAlgorithm.i
  • python/src/SORAAlgorithm_doc.i
  • python/src/otrobopt_module.i
  • python/test/CMakeLists.txt
  • python/test/sequential_mc.py
  • python/test/t_RBDOProblemAsOptimizationProblem_std.py
  • python/test/t_RBDOWithCobyla_std.py
  • python/test/t_SubsetInverseSampling_R-S.py
  • python/test/t_SubsetInverseSampling_Waarts_system_series.py
📝 Walkthrough

Walkthrough

Adds RBDOProblem and RIA, PMA, and SORA implementations, exposes them through C++ and Python interfaces, integrates their sources and headers into builds, and adds tests, examples, documentation, and supporting cleanup.

Changes

RBDO Problem and Algorithms

Layer / File(s) Summary
RBDOProblem contract and implementation
lib/src/otrobopt/RBDOProblem.hxx, lib/src/RBDOProblem.cxx
Defines reliability-based optimization problem data, distribution handling, constraint construction, accessors, cloning, and persistence.
RIA, PMA, and SORA solvers
lib/src/otrobopt/*Algorithm.hxx, lib/src/*Algorithm.cxx
Adds FORM-based RIA, inverse-FORM PMA, and iterative SORA optimization flows with solver configuration, results, and persistence.
Build and public API integration
lib/include/..., lib/src/CMakeLists.txt, python/src/*, python/src/otrobopt_module.i
Installs and compiles the new C++ sources and headers, includes them in the umbrella header, and generates Python bindings with documentation.
Validation and examples
lib/test/*, python/test/*, python/doc/examples/*, python/doc/user_manual/user_manual.rst
Adds C++ and Python tests plus analytical and engineering RBDO examples and user-manual entries.
Supporting cleanup
lib/src/*Measure.cxx, python/test/sequential_mc.py, python/test/t_SubsetInverseSampling_*.py, .gitignore
Renames local function variables consistently, fixes distribution dimension lookup, removes unused test values, and adds ignore patterns.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant RBDOProblem
  participant RIAAlgorithm
  participant PMAAlgorithm
  participant SORAAlgorithm
  participant OptimizationSolver
  Client->>RBDOProblem: configure objective, constraint, distributions, beta
  Client->>RIAAlgorithm: run()
  RIAAlgorithm->>OptimizationSolver: solve with FORM reliability constraint
  OptimizationSolver-->>RIAAlgorithm: OptimizationResult
  Client->>PMAAlgorithm: run()
  PMAAlgorithm->>OptimizationSolver: solve with inverse-FORM constraint
  OptimizationSolver-->>PMAAlgorithm: OptimizationResult
  Client->>SORAAlgorithm: run()
  SORAAlgorithm->>OptimizationSolver: solve deterministic shifted problem
  SORAAlgorithm->>SORAAlgorithm: update most probable target points
  OptimizationSolver-->>SORAAlgorithm: OptimizationResult
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.01% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main change: adding RIA, PMA, and SORA RBDO algorithms.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

♻️ Duplicate comments (1)
lib/src/SORAAlgorithm.cxx (1)

346-356: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

No error handling for inverse FORM convergence failures.

Same issue as in PMAAlgorithm.cxx (lines 258-268): the NLopt inverse FORM result is used without checking convergence. If the inner optimization fails, the MPTP and shifting vector will be garbage, causing the SORA iteration to diverge silently.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/src/SORAAlgorithm.cxx` around lines 346 - 356, The inverse FORM solve in
SORAAlgorithm::... uses NLopt::run() without checking whether the optimization
converged. After invAlgo.run(), inspect the result/status from the inverse
problem (as done in PMAAlgorithm::...) and only use the MPTP and shifting vector
when convergence succeeds; otherwise stop the SORA iteration or propagate an
explicit failure so bad values do not silently drive divergence.
🧹 Nitpick comments (3)
lib/src/SORAAlgorithm.cxx (1)

260-344: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Significant code duplication between PMA and SORA inverse FORM logic.

The PMAObjective (lines 260-302) and NormConstraint (lines 309-344) classes are nearly identical to InverseFormObjective (PMAAlgorithm.cxx lines 170-213) and SphereConstraint (PMAAlgorithm.cxx lines 220-255). The inverse FORM setup code (NLopt, bounds, starting point, iteration limit) is also duplicated.

Consider extracting a shared inverse FORM solver utility (e.g., solveInverseFORM(gParam, inverseTransform, op, targetBeta, dimXZ)) that both algorithms can call. This would reduce maintenance burden and ensure consistent error handling.

♻️ Proposed extraction
// In a shared header, e.g., InverseFORMSolver.hxx
struct InverseFORMResult
{
  Point uMPTP;
  Point xzMPTP;
  Scalar gMPTP;
  bool converged;
};

InverseFORMResult solveInverseFORM(
    const Function & gParam,
    const Function & inverseTransform,
    const ComparisonOperator & op,
    Scalar targetBeta,
    UnsignedInteger dimXZ);

Both PMAAlgorithm::run() and SORAAlgorithm::run() would call this utility instead of defining their own local classes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/src/SORAAlgorithm.cxx` around lines 260 - 344, Refactor the duplicated
inverse FORM setup in SORAAlgorithm by extracting a shared solver utility that
both SORA and PMA can reuse. The local helper classes PMAObjective and
NormConstraint should be moved into a common implementation alongside the
equivalent InverseFormObjective and SphereConstraint logic, and the repeated
NLopt configuration, bounds, starting point, and iteration-limit code should be
centralized into a reusable solveInverseFORM helper. Ensure SORAAlgorithm::run()
calls the shared utility instead of defining its own near-identical
objective/constraint classes.
python/src/SORAAlgorithm_doc.i (1)

1-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the RBDOProblem constructor in the class docstring.

The class-level docstring only documents the RobustOptimizationProblem constructor, but the C++ header declares a second constructor taking RBDOProblem. Both test files construct SORAAlgorithm exclusively with RBDOProblem, making it the primary use case. Users relying on the docstring won't know this constructor exists.

📝 Suggested docstring update
 Parameters
 ----------
-problem : :class:`~otrobopt.RobustOptimizationProblem`
-    Robust optimization problem
+problem : :class:`~otrobopt.RBDOProblem` or :class:`~otrobopt.RobustOptimizationProblem`
+    RBDO problem or robust optimization problem
 solver : :py:class:`openturns.OptimizationAlgorithm`
     Optimization solver
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/src/SORAAlgorithm_doc.i` around lines 1 - 17, The SORAAlgorithm class
docstring only describes the RobustOptimizationProblem constructor, but it also
supports an RBDOProblem constructor. Update the %feature("docstring")
OTROBOPT::SORAAlgorithm text to document the RBDOProblem initialization path
alongside the existing one, using the class name and constructor parameter names
so users can see both supported ways to instantiate SORAAlgorithm.
lib/test/t_RIAAlgorithm_std.cxx (1)

84-92: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add assertions to validate the optimization result.

The comment at lines 87-88 states the expected result (d1 + d2 ≈ 2*beta/sqrt(2) ≈ 4.24), but no assertion checks this. The test only prints the value, so it will pass even if the algorithm returns a grossly incorrect result. Adding a simple tolerance-based check would catch regressions without being overly brittle.

💡 Suggested assertion
   if (xStar.getDimension() == 2)
   {
-    std::cout << "d1+d2=" << xStar[0] + xStar[1] << std::endl;
+    const Scalar sum = xStar[0] + xStar[1];
+    std::cout << "d1+d2=" << sum << std::endl;
+    if (std::abs(sum - 4.24) > 1.0)
+    {
+      throw Exception(HERE) << "RIA result d1+d2=" << sum << " is too far from expected ~4.24";
+    }
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/test/t_RIAAlgorithm_std.cxx` around lines 84 - 92, The RIA test currently
only prints the computed optimum and does not verify it, so add a
tolerance-based assertion in the xStar check path to validate the expected d1+d2
value against the commented target. Use the existing
ria.getResult().getOptimalPoint() and xStar.getDimension() logic to locate the
spot, and assert that xStar[0] + xStar[1] is close to the expected
2*beta/sqrt(2) value with a reasonable tolerance so the test fails on grossly
incorrect results without being brittle.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/src/PMAAlgorithm.cxx`:
- Around line 257-281: The inverse FORM solve in PMAAlgorithm::run uses NLopt
results immediately after algo.run() without checking whether the optimizer
actually converged, so add explicit convergence/error handling around the NLopt
optimization before reading getResult(). Verify the solver status from
NLopt/OptimizationProblem after run, and if it did not succeed, fail fast or
propagate a clear error instead of computing uMPTP, xzMPTP, and gMPTP from
invalid results. Apply the same safeguard to the matching inverse FORM flow in
SORAAlgorithm so both algorithms handle NLopt failures consistently.

In `@lib/src/RBDOProblem.cxx`:
- Around line 127-132: buildJointDistribution currently ignores the designPoint
argument and always returns a static distribution, so either make the result
depend on the provided [d, p] or remove the parameter everywhere if
design-dependent X is not supported. Update RBDOProblem::buildJointDistribution
and any related contract/doc/callers so the signature and implementation match,
and use designPoint when constructing distributionX_ and the joint
BlockIndependentDistribution.
- Around line 48-119: The parameterized constructor of RBDOProblem copies
distributionZ_ but never marks the problem as having Z, so hasZ_ remains false
and later logic like hasDistributionZ(), buildJointDistribution(), and the
reliability measure path behave as X-only. Fix this by explicitly setting the
Z-present state in the constructor, either by routing the input through
setDistributionZ() or by adding a constructor/flag that updates hasZ_ when
distributionZ is provided. Make sure the change is applied in RBDOProblem and
keeps the existing X/Z joint distribution and constraint setup consistent.

In `@lib/src/RIAAlgorithm.cxx`:
- Around line 136-171: The RIAAlgorithm::operator() currently assumes FORM
always converges and immediately uses FORM::getResult(), which can propagate
invalid reliability values into the outer optimizer. Add failure handling around
the form.run() / form.getResult() sequence by checking the FORMResult
convergence/status (or catching FORM exceptions) and, on failure, return a safe
penalty Point instead of beta - rbdoProblem_.getTargetBeta(). Use the existing
symbols FORM, FORMResult, and RIAAlgorithm::operator() to locate the change.

In `@lib/src/SORAAlgorithm.cxx`:
- Around line 158-232: The shifting vector computed in SORAAlgorithm is
currently dead state because ShiftedConstraintEvaluation only uses xMPTP_ and
zMPTP_ directly and never applies the stored shift. Update the constraint path
so the evaluation uses the shifting vector consistently (for example in
ShiftedConstraintEvaluation::operator() and the constraint setup that feeds
problem.setInequalityConstraint), or remove the shiftingVectors_ computation and
getShiftingVectors() storage if the algorithm is meant to use only MPTP points.
Use the unique symbols ShiftedConstraintEvaluation, shiftingVectors_, and
getShiftingVectors() to keep the behavior consistent.
- Around line 362-367: The shifting vector build in
SORAAlgorithm::compute/update logic is using xzMPTP as if it always matched the
design dimension, which can read past the end and mixes design-space values with
X/Z components. Fix the loop that fills newShift by validating that
activeDesignIndices.getSize() does not exceed the X portion of xzMPTP, and use
only the X components when computing the shift; if the formulation requires lenD
to equal dimX, add an assertion or dimension check near
shiftingVectors_.add(newShift) to enforce that invariant.

In `@python/doc/examples/plot_rbdo_comparison.py`:
- Around line 34-39: The limit-state definition in the plot example uses the
wrong sign in the SymbolicFunction for g, which makes RIA/PMA/SORA enforce the
opposite failure event. Update the constraint expression in the example’s g
definition so it matches the stated form P(Z - d1 - 2d0 ≤ 0), and keep the
ot.Less() convention aligned with that sign. Use the nearby plot_rbdo_comparison
example setup and the SymbolicFunction construction to locate and correct the
expression.

In `@python/doc/examples/plot_rbdo_spur_speed_reducer.py`:
- Around line 28-29: The bounds documentation in the spur speed reducer example
is inconsistent with the implementation in the module’s constraint setup. Update
the source of truth between the LaTeX comment and the bounds used in the example
so they match for d6 and d7; if keeping the literature values, adjust the bounds
in the example code that defines the design variables/constraints, otherwise
revise the LaTeX comment to reflect the current values. Reference the
`plot_rbdo_spur_speed_reducer.py` example and the bounds definition block used
for `d`.

In `@python/src/PMAAlgorithm_doc.i`:
- Around line 10-11: The class docstring for PMAAlgorithm uses the wrong
parameter type for problem; update the documentation in PMAAlgorithm_doc.i so
the problem entry matches the constructor and the setRBDOProblem/getRBDOProblem
APIs, using RBDOProblem instead of RobustOptimizationProblem. Keep the rest of
the docstring consistent with the existing PMAAlgorithm and RBDOProblem
references.

In `@python/src/RBDOProblem_doc.i`:
- Around line 13-26: The RBDOProblem docstring is documenting a non-existent
constructor argument, so update the class documentation to remove
distributionUpdater from the parameter list and delete the misleading note on
distributionX in RBDOProblem_doc.i. Keep the docstring aligned with the actual
RBDOProblem constructor signature and ensure only the real parameters
(distributionX, distributionZ, targetBeta, constraintOperator,
activeDesignIndices, activeParameterIndices, etc.) are described.

In `@python/src/RIAAlgorithm_doc.i`:
- Around line 10-11: The class-level docstring for the RIAAlgorithm parameter
description uses the wrong type name for problem, so update the docstring in
RIAAlgorithm_doc.i to match the actual constructor and accessor signatures.
Replace the RobustOptimizationProblem reference with RBDOProblem in the problem
parameter description, keeping it consistent with the setRBDOProblem and
getRBDOProblem docstrings and the RIAAlgorithm.hxx constructor.

---

Duplicate comments:
In `@lib/src/SORAAlgorithm.cxx`:
- Around line 346-356: The inverse FORM solve in SORAAlgorithm::... uses
NLopt::run() without checking whether the optimization converged. After
invAlgo.run(), inspect the result/status from the inverse problem (as done in
PMAAlgorithm::...) and only use the MPTP and shifting vector when convergence
succeeds; otherwise stop the SORA iteration or propagate an explicit failure so
bad values do not silently drive divergence.

---

Nitpick comments:
In `@lib/src/SORAAlgorithm.cxx`:
- Around line 260-344: Refactor the duplicated inverse FORM setup in
SORAAlgorithm by extracting a shared solver utility that both SORA and PMA can
reuse. The local helper classes PMAObjective and NormConstraint should be moved
into a common implementation alongside the equivalent InverseFormObjective and
SphereConstraint logic, and the repeated NLopt configuration, bounds, starting
point, and iteration-limit code should be centralized into a reusable
solveInverseFORM helper. Ensure SORAAlgorithm::run() calls the shared utility
instead of defining its own near-identical objective/constraint classes.

In `@lib/test/t_RIAAlgorithm_std.cxx`:
- Around line 84-92: The RIA test currently only prints the computed optimum and
does not verify it, so add a tolerance-based assertion in the xStar check path
to validate the expected d1+d2 value against the commented target. Use the
existing ria.getResult().getOptimalPoint() and xStar.getDimension() logic to
locate the spot, and assert that xStar[0] + xStar[1] is close to the expected
2*beta/sqrt(2) value with a reasonable tolerance so the test fails on grossly
incorrect results without being brittle.

In `@python/src/SORAAlgorithm_doc.i`:
- Around line 1-17: The SORAAlgorithm class docstring only describes the
RobustOptimizationProblem constructor, but it also supports an RBDOProblem
constructor. Update the %feature("docstring") OTROBOPT::SORAAlgorithm text to
document the RBDOProblem initialization path alongside the existing one, using
the class name and constructor parameter names so users can see both supported
ways to instantiate SORAAlgorithm.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d2ce209f-b515-461e-b9b7-ecbee9899984

📥 Commits

Reviewing files that changed from the base of the PR and between 62e5731 and 05a7293.

📒 Files selected for processing (35)
  • lib/include/otrobopt/OTRobOpt.hxx
  • lib/src/CMakeLists.txt
  • lib/src/PMAAlgorithm.cxx
  • lib/src/RBDOProblem.cxx
  • lib/src/RIAAlgorithm.cxx
  • lib/src/SORAAlgorithm.cxx
  • lib/src/otrobopt/PMAAlgorithm.hxx
  • lib/src/otrobopt/RBDOProblem.hxx
  • lib/src/otrobopt/RIAAlgorithm.hxx
  • lib/src/otrobopt/SORAAlgorithm.hxx
  • lib/test/CMakeLists.txt
  • lib/test/t_MeasureFunction_std.cxx
  • lib/test/t_PMAAlgorithm_std.cxx
  • lib/test/t_RBDOProblem_std.cxx
  • lib/test/t_RIAAlgorithm_std.cxx
  • lib/test/t_RobustOptimizationAlgorithm_std.cxx
  • lib/test/t_RobustOptimizationProblem_std.cxx
  • lib/test/t_SORAAlgorithm_std.cxx
  • python/doc/examples/plot_rbdo_analytical_case1.py
  • python/doc/examples/plot_rbdo_comparison.py
  • python/doc/examples/plot_rbdo_short_column.py
  • python/doc/examples/plot_rbdo_spur_speed_reducer.py
  • python/src/CMakeLists.txt
  • python/src/PMAAlgorithm.i
  • python/src/PMAAlgorithm_doc.i
  • python/src/RBDOProblem.i
  • python/src/RBDOProblem_doc.i
  • python/src/RIAAlgorithm.i
  • python/src/RIAAlgorithm_doc.i
  • python/src/SORAAlgorithm.i
  • python/src/SORAAlgorithm_doc.i
  • python/src/otrobopt_module.i
  • python/test/CMakeLists.txt
  • python/test/t_RBDOProblemAsOptimizationProblem_std.py
  • python/test/t_RBDOWithCobyla_std.py

Comment thread lib/src/PMAAlgorithm.cxx Outdated
Comment thread lib/src/RBDOProblem.cxx
Comment thread lib/src/RBDOProblem.cxx Outdated
Comment thread lib/src/RIAAlgorithm.cxx
Comment thread lib/src/SORAAlgorithm.cxx
Comment thread python/doc/examples/plot_rbdo_comparison.py
Comment thread python/doc/examples/plot_rbdo_spur_speed_reducer.py Outdated
Comment thread python/src/PMAAlgorithm_doc.i Outdated
Comment thread python/src/RBDOProblem_doc.i Outdated
Comment thread python/src/RIAAlgorithm_doc.i Outdated
@regislebrun
regislebrun force-pushed the RBDO branch 2 times, most recently from a7ed3eb to 01e15bb Compare July 9, 2026 09:14

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (1)
lib/src/SORAAlgorithm.cxx (1)

344-346: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Inverse FORM starting point and bounds are not aligned with beta_target.

The starting point Point(dimXZ, 1.0) has norm sqrt(dimXZ), far from the target sphere ||u|| = beta_target. For dimXZ=2 and beta_target=3, this is 1.41 vs 3.0. The hardcoded bounds [-7, 7] may also clip the solution for larger beta_target values.

A starting point on the beta-sphere and bounds scaled to beta_target would improve convergence reliability.

♻️ Proposed fix
-    invFormProb.setBounds(Interval(Point(dimXZ, -7.0), Point(dimXZ, 7.0)));
+    const Scalar boundMargin = 3.0;
+    invFormProb.setBounds(Interval(Point(dimXZ, -(targetBeta + boundMargin)), Point(dimXZ, targetBeta + boundMargin)));
     invAlgo.setProblem(invFormProb);
-    invAlgo.setStartingPoint(Point(dimXZ, 1.0));
+    invAlgo.setStartingPoint(Point(dimXZ, targetBeta / std::sqrt(static_cast<Scalar>(dimXZ))));
     invAlgo.setMaximumIterationNumber(100);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/src/SORAAlgorithm.cxx` around lines 344 - 346, The inverse FORM setup
uses a hardcoded starting point and bounds that are not tied to beta_target, so
update the invAlgo initialization in SORAAlgorithm to place the starting point
on the beta-sphere and derive the invFormProb bounds from beta_target instead of
fixed [-7, 7]. Use the existing invFormProb and invAlgo symbols in this block so
the initial guess and search region scale with the target reliability level and
remain valid for larger beta_target values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/src/PMAAlgorithm.cxx`:
- Around line 141-146: The parametric reduction in PMA is only fixing active
design variables in gParam, leaving active parameters free and causing a
dimension mismatch when lenP > 0. Update the logic in
PMAAlgorithm::compute/where ParametricFunction is built to combine
rbdoProblem_.getActiveDesignIndices() with
rbdoProblem_.getActiveParameterIndices() before constructing the
ParametricFunction, matching the reduction pattern used in RIAAlgorithm so
inverseTransform’s x+z inputs align with the reduced limit-state.

In `@lib/src/SORAAlgorithm.cxx`:
- Around line 408-425: The SORAAlgorithm persistence logic is missing
startingPoint_, so a save/load cycle loses the user-defined starting point and
run() falls back to the default. Update SORAAlgorithm::save and
SORAAlgorithm::load to serialize and restore startingPoint_ alongside
rbdoProblem_, maxSORAIteration_, soraTolerance_, and mostProbableTargetPoints_,
using the existing Advocate attribute pattern.
- Around line 186-193: The parameter binding in
SORAAlgorithm::computeDesignPoint only fixes the active design variables, so
ParametricFunction still leaves active parameters exposed and later evaluation
can mismatch dimensions. Update the ParametricFunction setup to also bind the
active parameter indices, or explicitly reject non-empty activeParameterIndices
before building gParam. Use the existing symbols activeDesignIndices,
activeParameterIndices, and gParam in SORAAlgorithm to locate and fix the
binding logic.
- Around line 49-57: The SORAAlgorithm constructor that takes a
RobustOptimizationProblem and solver leaves rbdoProblem_ unset, but run() reads
rbdoProblem_ directly, so either initialize rbdoProblem_ in this constructor or
make the precondition explicit by documenting that setRBDOProblem() must be
called before run(); if SORAAlgorithm is intended to be created only from
RBDOProblem, remove or replace this overload to prevent misuse.

In `@python/src/CMakeLists.txt`:
- Line 146: The Sphinx build flags have been weakened by removing the
warning-to-error behavior, which can let documentation issues slip through
unnoticed. Update the SPHINX_FLAGS setting in the CMakeLists logic to preserve
the warning enforcement used by Sphinx, and if a temporary exception is truly
needed for the RBDO docs, fix the underlying warnings in the affected doc
sources or clearly document why the flag change is intentional. Use the
SPHINX_FLAGS configuration block as the anchor for the change.
- Line 38: The warning-suppression flags on `${module_target}` are too broad and
affect all compiled sources, not just SWIG-generated code. Update the CMake
logic in `target_compile_options` for `${module_target}` so the
`-Wno-error=shadow`, `-Wno-error=unused-variable`, and
`-Wno-error=unused-function` settings apply only to SWIG-generated sources,
preferably via `SWIG_COMPILE_FLAGS` or a generator expression tied to those
files. If broad suppression is intentionally kept, add a clear comment near the
`${module_target}` configuration explaining why it is safe.

---

Nitpick comments:
In `@lib/src/SORAAlgorithm.cxx`:
- Around line 344-346: The inverse FORM setup uses a hardcoded starting point
and bounds that are not tied to beta_target, so update the invAlgo
initialization in SORAAlgorithm to place the starting point on the beta-sphere
and derive the invFormProb bounds from beta_target instead of fixed [-7, 7]. Use
the existing invFormProb and invAlgo symbols in this block so the initial guess
and search region scale with the target reliability level and remain valid for
larger beta_target values.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a0077c2c-8f42-4846-b950-6eb4ad29e1c4

📥 Commits

Reviewing files that changed from the base of the PR and between 05a7293 and 01e15bb.

📒 Files selected for processing (49)
  • .gitignore
  • lib/include/otrobopt/OTRobOpt.hxx
  • lib/src/CMakeLists.txt
  • lib/src/IndividualChanceMeasure.cxx
  • lib/src/JointChanceMeasure.cxx
  • lib/src/MeanMeasure.cxx
  • lib/src/MeanStandardDeviationTradeoffMeasure.cxx
  • lib/src/PMAAlgorithm.cxx
  • lib/src/QuantileMeasure.cxx
  • lib/src/RBDOProblem.cxx
  • lib/src/RIAAlgorithm.cxx
  • lib/src/SORAAlgorithm.cxx
  • lib/src/VarianceMeasure.cxx
  • lib/src/WorstCaseMeasure.cxx
  • lib/src/otrobopt/PMAAlgorithm.hxx
  • lib/src/otrobopt/RBDOProblem.hxx
  • lib/src/otrobopt/RIAAlgorithm.hxx
  • lib/src/otrobopt/SORAAlgorithm.hxx
  • lib/test/CMakeLists.txt
  • lib/test/t_MeasureFunction_std.cxx
  • lib/test/t_PMAAlgorithm_std.cxx
  • lib/test/t_RBDOProblem_std.cxx
  • lib/test/t_RIAAlgorithm_std.cxx
  • lib/test/t_RobustOptimizationAlgorithm_std.cxx
  • lib/test/t_RobustOptimizationProblem_std.cxx
  • lib/test/t_SORAAlgorithm_std.cxx
  • python/doc/conf.py.in
  • python/doc/examples/plot_example2.py
  • python/doc/examples/plot_rbdo_analytical_case1.py
  • python/doc/examples/plot_rbdo_comparison.py
  • python/doc/examples/plot_rbdo_short_column.py
  • python/doc/examples/plot_rbdo_spur_speed_reducer.py
  • python/doc/user_manual/user_manual.rst
  • python/src/CMakeLists.txt
  • python/src/PMAAlgorithm.i
  • python/src/PMAAlgorithm_doc.i
  • python/src/RBDOProblem.i
  • python/src/RBDOProblem_doc.i
  • python/src/RIAAlgorithm.i
  • python/src/RIAAlgorithm_doc.i
  • python/src/SORAAlgorithm.i
  • python/src/SORAAlgorithm_doc.i
  • python/src/otrobopt_module.i
  • python/test/CMakeLists.txt
  • python/test/sequential_mc.py
  • python/test/t_RBDOProblemAsOptimizationProblem_std.py
  • python/test/t_RBDOWithCobyla_std.py
  • python/test/t_SubsetInverseSampling_R-S.py
  • python/test/t_SubsetInverseSampling_Waarts_system_series.py
💤 Files with no reviewable changes (2)
  • python/doc/examples/plot_example2.py
  • python/test/t_SubsetInverseSampling_R-S.py
✅ Files skipped from review due to trivial changes (13)
  • lib/test/t_MeasureFunction_std.cxx
  • python/src/RIAAlgorithm_doc.i
  • python/src/PMAAlgorithm_doc.i
  • lib/include/otrobopt/OTRobOpt.hxx
  • .gitignore
  • python/src/SORAAlgorithm_doc.i
  • python/doc/examples/plot_rbdo_comparison.py
  • python/doc/user_manual/user_manual.rst
  • python/src/RBDOProblem_doc.i
  • python/test/t_SubsetInverseSampling_Waarts_system_series.py
  • lib/src/WorstCaseMeasure.cxx
  • lib/src/JointChanceMeasure.cxx
  • lib/src/MeanStandardDeviationTradeoffMeasure.cxx
🚧 Files skipped from review as they are similar to previous changes (22)
  • lib/test/t_RIAAlgorithm_std.cxx
  • python/src/otrobopt_module.i
  • lib/test/t_PMAAlgorithm_std.cxx
  • python/test/CMakeLists.txt
  • python/src/PMAAlgorithm.i
  • lib/test/t_RobustOptimizationAlgorithm_std.cxx
  • lib/src/otrobopt/RIAAlgorithm.hxx
  • python/src/RBDOProblem.i
  • python/src/SORAAlgorithm.i
  • python/src/RIAAlgorithm.i
  • lib/test/t_RobustOptimizationProblem_std.cxx
  • lib/src/otrobopt/PMAAlgorithm.hxx
  • lib/test/t_RBDOProblem_std.cxx
  • python/doc/examples/plot_rbdo_analytical_case1.py
  • python/doc/examples/plot_rbdo_spur_speed_reducer.py
  • lib/test/CMakeLists.txt
  • lib/src/CMakeLists.txt
  • python/test/t_RBDOWithCobyla_std.py
  • lib/src/otrobopt/RBDOProblem.hxx
  • lib/test/t_SORAAlgorithm_std.cxx
  • python/doc/examples/plot_rbdo_short_column.py
  • python/test/t_RBDOProblemAsOptimizationProblem_std.py

Comment thread lib/src/PMAAlgorithm.cxx Outdated
Comment thread lib/src/SORAAlgorithm.cxx Outdated
Comment thread lib/src/SORAAlgorithm.cxx Outdated
Comment thread lib/src/SORAAlgorithm.cxx
Comment thread python/src/CMakeLists.txt Outdated
Comment thread python/src/CMakeLists.txt Outdated
@regislebrun
regislebrun force-pushed the RBDO branch 2 times, most recently from 0985d7d to db3a79f Compare July 9, 2026 10:19

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/src/PMAAlgorithm.cxx`:
- Around line 305-316: PMAAlgorithm::save and PMAAlgorithm::load are missing
persistence for startingPoint_, so a round-trip drops the user-configured
initial point and run() reverts to the solver default. Update both methods to
serialize and restore startingPoint_ alongside rbdoProblem_, following the same
pattern used in SORAAlgorithm. Make sure the member name startingPoint_ is
handled consistently with the existing Advocate saveAttribute/loadAttribute
calls in PMAAlgorithm.

In `@lib/src/RIAAlgorithm.cxx`:
- Line 110: The output description in RIAAlgorithm::setOutputDescription is
inverted relative to the value produced by operator(); update the description
text so it matches the actual returned expression from RIAAlgorithm::operator()
(beta - rbdoProblem_.getTargetBeta()) and keep the naming consistent with the
beta target/output semantics.
- Around line 202-213: The save/load path in RIAAlgorithm is missing persistence
for startingPoint_, so restore it alongside rbdoProblem_ in RIAAlgorithm::save
and RIAAlgorithm::load. Update the serialization in these methods to store and
reload startingPoint_ using the existing Advocate API, keeping the field name
consistent with the class member so the loaded algorithm preserves the
configured initial point instead of falling back to the default.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d660a04b-8f08-40d0-8014-ec876f3ddf61

📥 Commits

Reviewing files that changed from the base of the PR and between 01e15bb and db3a79f.

📒 Files selected for processing (49)
  • .gitignore
  • lib/include/otrobopt/OTRobOpt.hxx
  • lib/src/CMakeLists.txt
  • lib/src/IndividualChanceMeasure.cxx
  • lib/src/JointChanceMeasure.cxx
  • lib/src/MeanMeasure.cxx
  • lib/src/MeanStandardDeviationTradeoffMeasure.cxx
  • lib/src/PMAAlgorithm.cxx
  • lib/src/QuantileMeasure.cxx
  • lib/src/RBDOProblem.cxx
  • lib/src/RIAAlgorithm.cxx
  • lib/src/SORAAlgorithm.cxx
  • lib/src/VarianceMeasure.cxx
  • lib/src/WorstCaseMeasure.cxx
  • lib/src/otrobopt/PMAAlgorithm.hxx
  • lib/src/otrobopt/RBDOProblem.hxx
  • lib/src/otrobopt/RIAAlgorithm.hxx
  • lib/src/otrobopt/SORAAlgorithm.hxx
  • lib/test/CMakeLists.txt
  • lib/test/t_MeasureFunction_std.cxx
  • lib/test/t_PMAAlgorithm_std.cxx
  • lib/test/t_RBDOProblem_std.cxx
  • lib/test/t_RIAAlgorithm_std.cxx
  • lib/test/t_RobustOptimizationAlgorithm_std.cxx
  • lib/test/t_RobustOptimizationProblem_std.cxx
  • lib/test/t_SORAAlgorithm_std.cxx
  • python/doc/conf.py.in
  • python/doc/examples/plot_example2.py
  • python/doc/examples/plot_rbdo_analytical_case1.py
  • python/doc/examples/plot_rbdo_comparison.py
  • python/doc/examples/plot_rbdo_short_column.py
  • python/doc/examples/plot_rbdo_spur_speed_reducer.py
  • python/doc/user_manual/user_manual.rst
  • python/src/CMakeLists.txt
  • python/src/PMAAlgorithm.i
  • python/src/PMAAlgorithm_doc.i
  • python/src/RBDOProblem.i
  • python/src/RBDOProblem_doc.i
  • python/src/RIAAlgorithm.i
  • python/src/RIAAlgorithm_doc.i
  • python/src/SORAAlgorithm.i
  • python/src/SORAAlgorithm_doc.i
  • python/src/otrobopt_module.i
  • python/test/CMakeLists.txt
  • python/test/sequential_mc.py
  • python/test/t_RBDOProblemAsOptimizationProblem_std.py
  • python/test/t_RBDOWithCobyla_std.py
  • python/test/t_SubsetInverseSampling_R-S.py
  • python/test/t_SubsetInverseSampling_Waarts_system_series.py
💤 Files with no reviewable changes (2)
  • python/test/t_SubsetInverseSampling_R-S.py
  • python/doc/examples/plot_example2.py
✅ Files skipped from review due to trivial changes (11)
  • python/src/RIAAlgorithm_doc.i
  • lib/include/otrobopt/OTRobOpt.hxx
  • python/doc/user_manual/user_manual.rst
  • .gitignore
  • python/src/RBDOProblem.i
  • lib/src/MeanStandardDeviationTradeoffMeasure.cxx
  • python/src/SORAAlgorithm_doc.i
  • lib/src/WorstCaseMeasure.cxx
  • lib/src/VarianceMeasure.cxx
  • python/test/sequential_mc.py
  • python/src/PMAAlgorithm_doc.i
🚧 Files skipped from review as they are similar to previous changes (26)
  • python/test/CMakeLists.txt
  • lib/test/t_MeasureFunction_std.cxx
  • python/src/otrobopt_module.i
  • python/src/RIAAlgorithm.i
  • python/src/PMAAlgorithm.i
  • lib/test/t_PMAAlgorithm_std.cxx
  • python/doc/conf.py.in
  • lib/test/t_RobustOptimizationAlgorithm_std.cxx
  • lib/src/CMakeLists.txt
  • python/test/t_SubsetInverseSampling_Waarts_system_series.py
  • python/src/SORAAlgorithm.i
  • lib/test/t_RBDOProblem_std.cxx
  • lib/test/t_RobustOptimizationProblem_std.cxx
  • lib/test/t_SORAAlgorithm_std.cxx
  • lib/src/IndividualChanceMeasure.cxx
  • python/test/t_RBDOWithCobyla_std.py
  • python/src/RBDOProblem_doc.i
  • lib/src/otrobopt/RBDOProblem.hxx
  • lib/src/JointChanceMeasure.cxx
  • lib/src/otrobopt/SORAAlgorithm.hxx
  • lib/src/QuantileMeasure.cxx
  • lib/test/CMakeLists.txt
  • python/src/CMakeLists.txt
  • python/doc/examples/plot_rbdo_short_column.py
  • lib/test/t_RIAAlgorithm_std.cxx
  • lib/src/MeanMeasure.cxx

Comment thread lib/src/PMAAlgorithm.cxx
Comment thread lib/src/RIAAlgorithm.cxx Outdated
Comment thread lib/src/RIAAlgorithm.cxx
Comment thread .gitignore Outdated
Comment thread python/doc/conf.py.in Outdated
Comment thread python/src/CMakeLists.txt Outdated
Comment thread lib/src/PMAAlgorithm.cxx Outdated
Comment thread lib/src/PMAAlgorithm.cxx Outdated
Comment thread python/src/RBDOProblem_doc.i

@drblobfish drblobfish left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello.
I'm really excited to see all this new work on otrobopt.
I'm not sure if I'm allowed to comment here, but I had some thoughts while reading through this PR and I allowed myself to write them here hoping you might find them useful.

Comment thread lib/src/PMAAlgorithm.cxx Outdated
Comment thread lib/src/PMAAlgorithm.cxx Outdated
Core classes:
- RBDOProblem: define RBDO problems with objective, probabilistic constraint
  g(d,X,Z), distributions for X and Z, target reliability index, constraint
  operator (Less/Greater), and design/parameter dimension management
- RIAAlgorithm: Reliability Index Approach using FORM to compute reliability
  indices; outer optimization minimizes f(d,p) subject to beta(d) >= beta_target
- PMAAlgorithm: Performance Measure Approach using inverse FORM to compute
  performance measures for probabilistic constraints
- SORAAlgorithm: Sequential Optimization and Reliability Analysis iterating
  between deterministic optimization with shifted constraints and inverse FORM

Thanks to Loic Brevault and Mathieu Balesdent for the RBDO_OT prototype and examples.

- sequential_mc.py:140: use self.distributionXi_ instead of global distributionXi (BUG)
- plot_example2.py: remove unused import openturns.testing
- t_SubsetInverseSampling*.py: remove unused variables (start, CVMC, etc.)
- PMAAlgorithm.cxx: remove dead evalLimitState() function
- All measure .cxx: rename shadowed Function function() -> func() in operator() methods
- RobustOptimizationProblem.hxx: restore needed MeasureEvaluationImplementation.hxx include
- SORAAlgorithm.cxx: rename inner xMPTP/zMPTP to xMPTPNew/zMPTPNew to avoid shadow
- CMakeLists.txt: enable -Werror=shadow/unused-variable/unused-function for lib; suppress for SWIG wrapper
- SPHINX_FLAGS: remove -W to allow pre-existing cross-ref warnings
@regislebrun

Copy link
Copy Markdown
Member Author

Hello. I'm really excited to see all this new work on otrobopt. I'm not sure if I'm allowed to comment here, but I had some thoughts while reading through this PR and I allowed myself to write them here hoping you might find them useful.

Hi,
Your comments are welcomed and particularly useful, thanks! Could you describe your use of this module, and what should be added to fit your needs if any?

Cheers

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
lib/src/SORAAlgorithm.cxx (1)

347-348: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Aborting the whole SORA loop on a single inverse-FORM failure.

A non-convergence in one iteration throws and discards all prior iterations' progress. Consider breaking out and returning the best point found so far (as the RIA path does with a penalty), so a transient inner-solve failure doesn't lose the outer result.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/src/SORAAlgorithm.cxx` around lines 347 - 348, The inverse-FORM failure
handling in the SORA loop should not throw and abort the entire algorithm.
Update the check on invAlgo.getResult().getStatus() to exit the current SORA
iteration path and return the best point accumulated so far, following the
existing RIA penalty/fallback behavior while preserving prior iterations’
progress.
lib/src/PMAAlgorithm.cxx (1)

150-165: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Invariant construction rebuilt on every call.

jointDist, dimXZ, g, activeDesignIndices/activeParameterIndices, and paramIndices depend only on rbdoProblem_, which is fixed for the lifetime of PMAAlgorithm_ConstraintEvaluation. Rebuilding them on every operator() call (invoked at least once per outer-optimization iteration, more often with finite-difference gradients) is wasted work; only paramValues/gParam genuinely depend on the current designPoint.

♻️ Suggested refactor
   PMAAlgorithm_ConstraintEvaluation(const RBDOProblem & rbdoProblem)
     : EvaluationImplementation()
     , rbdoProblem_(rbdoProblem)
   {
     const UnsignedInteger dim = rbdoProblem.getObjective().getInputDimension();
     setInputDescription(Description(dim));
     setOutputDescription(Description(1, "-performance_measure"));
+    jointDist_ = rbdoProblem_.buildJointDistribution();
+    g_ = rbdoProblem_.getConstraintFunction();
+    activeDesignIndices_ = rbdoProblem_.getActiveDesignIndices();
+    activeParameterIndices_ = rbdoProblem_.getActiveParameterIndices();
+    paramIndices_ = activeDesignIndices_;
+    paramIndices_.add(activeParameterIndices_);
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/src/PMAAlgorithm.cxx` around lines 150 - 165, Cache the invariant objects
currently constructed at the start of
PMAAlgorithm_ConstraintEvaluation::operator(), including the joint distribution,
dimension, constraint function, active index sets, and combined paramIndices,
during PMAAlgorithm_ConstraintEvaluation initialization. Update operator() to
reuse those cached members and rebuild only paramValues and gParam from the
current designPoint.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/src/PMAAlgorithm.cxx`:
- Around line 174-184: Update the sphere minimization setup in the PMA algorithm
to derive the coordinate bounds from targetBeta_ (or the corresponding target
reliability value), ensuring the feasible ||u|| == targetBeta_ sphere is not
excluded for large targets; remove the fixed ±7.0 bounds. Replace the hardcoded
100-iteration cap with the algorithm’s configurable or appropriately scaled
iteration limit, preserving the existing starting-point and optimization flow.

---

Nitpick comments:
In `@lib/src/PMAAlgorithm.cxx`:
- Around line 150-165: Cache the invariant objects currently constructed at the
start of PMAAlgorithm_ConstraintEvaluation::operator(), including the joint
distribution, dimension, constraint function, active index sets, and combined
paramIndices, during PMAAlgorithm_ConstraintEvaluation initialization. Update
operator() to reuse those cached members and rebuild only paramValues and gParam
from the current designPoint.

In `@lib/src/SORAAlgorithm.cxx`:
- Around line 347-348: The inverse-FORM failure handling in the SORA loop should
not throw and abort the entire algorithm. Update the check on
invAlgo.getResult().getStatus() to exit the current SORA iteration path and
return the best point accumulated so far, following the existing RIA
penalty/fallback behavior while preserving prior iterations’ progress.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5acccd3f-58fa-4236-83ff-0df5dbead249

📥 Commits

Reviewing files that changed from the base of the PR and between db3a79f and e0846ac.

📒 Files selected for processing (47)
  • .gitignore
  • lib/include/otrobopt/OTRobOpt.hxx
  • lib/src/CMakeLists.txt
  • lib/src/IndividualChanceMeasure.cxx
  • lib/src/JointChanceMeasure.cxx
  • lib/src/MeanMeasure.cxx
  • lib/src/MeanStandardDeviationTradeoffMeasure.cxx
  • lib/src/PMAAlgorithm.cxx
  • lib/src/QuantileMeasure.cxx
  • lib/src/RBDOProblem.cxx
  • lib/src/RIAAlgorithm.cxx
  • lib/src/SORAAlgorithm.cxx
  • lib/src/VarianceMeasure.cxx
  • lib/src/WorstCaseMeasure.cxx
  • lib/src/otrobopt/PMAAlgorithm.hxx
  • lib/src/otrobopt/RBDOProblem.hxx
  • lib/src/otrobopt/RIAAlgorithm.hxx
  • lib/src/otrobopt/SORAAlgorithm.hxx
  • lib/test/CMakeLists.txt
  • lib/test/t_MeasureFunction_std.cxx
  • lib/test/t_PMAAlgorithm_std.cxx
  • lib/test/t_RBDOProblem_std.cxx
  • lib/test/t_RIAAlgorithm_std.cxx
  • lib/test/t_RobustOptimizationAlgorithm_std.cxx
  • lib/test/t_RobustOptimizationProblem_std.cxx
  • lib/test/t_SORAAlgorithm_std.cxx
  • python/doc/examples/plot_example2.py
  • python/doc/examples/plot_rbdo_analytical_case1.py
  • python/doc/examples/plot_rbdo_comparison.py
  • python/doc/examples/plot_rbdo_short_column.py
  • python/doc/examples/plot_rbdo_spur_speed_reducer.py
  • python/doc/user_manual/user_manual.rst
  • python/src/PMAAlgorithm.i
  • python/src/PMAAlgorithm_doc.i
  • python/src/RBDOProblem.i
  • python/src/RBDOProblem_doc.i
  • python/src/RIAAlgorithm.i
  • python/src/RIAAlgorithm_doc.i
  • python/src/SORAAlgorithm.i
  • python/src/SORAAlgorithm_doc.i
  • python/src/otrobopt_module.i
  • python/test/CMakeLists.txt
  • python/test/sequential_mc.py
  • python/test/t_RBDOProblemAsOptimizationProblem_std.py
  • python/test/t_RBDOWithCobyla_std.py
  • python/test/t_SubsetInverseSampling_R-S.py
  • python/test/t_SubsetInverseSampling_Waarts_system_series.py
💤 Files with no reviewable changes (3)
  • python/doc/examples/plot_example2.py
  • .gitignore
  • python/test/t_SubsetInverseSampling_R-S.py
🚧 Files skipped from review as they are similar to previous changes (36)
  • python/src/RIAAlgorithm_doc.i
  • lib/test/t_RBDOProblem_std.cxx
  • python/doc/user_manual/user_manual.rst
  • python/src/SORAAlgorithm_doc.i
  • python/src/RIAAlgorithm.i
  • lib/include/otrobopt/OTRobOpt.hxx
  • python/test/sequential_mc.py
  • python/src/PMAAlgorithm.i
  • python/src/RBDOProblem.i
  • python/test/CMakeLists.txt
  • python/src/SORAAlgorithm.i
  • lib/test/t_PMAAlgorithm_std.cxx
  • lib/test/t_RobustOptimizationAlgorithm_std.cxx
  • lib/src/otrobopt/PMAAlgorithm.hxx
  • python/src/RBDOProblem_doc.i
  • python/src/PMAAlgorithm_doc.i
  • lib/src/VarianceMeasure.cxx
  • lib/src/otrobopt/SORAAlgorithm.hxx
  • lib/src/QuantileMeasure.cxx
  • lib/src/otrobopt/RBDOProblem.hxx
  • lib/src/MeanStandardDeviationTradeoffMeasure.cxx
  • lib/src/MeanMeasure.cxx
  • python/test/t_SubsetInverseSampling_Waarts_system_series.py
  • lib/src/IndividualChanceMeasure.cxx
  • lib/test/t_RobustOptimizationProblem_std.cxx
  • lib/test/t_SORAAlgorithm_std.cxx
  • lib/src/WorstCaseMeasure.cxx
  • python/test/t_RBDOWithCobyla_std.py
  • lib/src/JointChanceMeasure.cxx
  • lib/test/CMakeLists.txt
  • lib/test/t_RIAAlgorithm_std.cxx
  • python/doc/examples/plot_rbdo_analytical_case1.py
  • python/doc/examples/plot_rbdo_comparison.py
  • python/doc/examples/plot_rbdo_short_column.py
  • python/test/t_RBDOProblemAsOptimizationProblem_std.py
  • python/doc/examples/plot_rbdo_spur_speed_reducer.py

Comment thread lib/src/PMAAlgorithm.cxx
Comment on lines +174 to +184
OptimizationProblem sphereMinimizationProblem(objFunc);
sphereMinimizationProblem.setMinimization(true);
const Function sphereFunc(PMAAlgorithm_SphereConstraint(dimXZ, targetBeta));
sphereMinimizationProblem.setEqualityConstraint(sphereFunc);
sphereMinimizationProblem.setBounds(Interval(Point(dimXZ, -7.0), Point(dimXZ, 7.0)));
OptimizationAlgorithm algo(OptimizationAlgorithm::Build(sphereMinimizationProblem));
if (uStart_.getDimension() != dimXZ)
uStart_ = Point(dimXZ, 1.0);
algo.setStartingPoint(uStart_);
algo.setMaximumIterationNumber(100);
algo.run();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Hardcoded sphere-search bounds (±7.0) and iteration cap can silently break the constraint for large targetBeta.

setBounds fixes each coordinate of the reduced u-space to [-7, 7] regardless of targetBeta_. The equality constraint requires ||u|| == targetBeta_; if a user sets a target reliability index above ~7 (not unusual for very safety-critical designs), the feasible sphere lies partly or fully outside this box, and the inner sphere minimization (and hence PMA itself) becomes infeasible/silently wrong. The setMaximumIterationNumber(100) on line 183 is the same kind of hardcoded value, though less risky.

🐛 Proposed fix
-    sphereMinimizationProblem.setBounds(Interval(Point(dimXZ, -7.0), Point(dimXZ, 7.0)));
+    const Scalar boundMargin = targetBeta + 3.0;
+    sphereMinimizationProblem.setBounds(Interval(Point(dimXZ, -boundMargin), Point(dimXZ, boundMargin)));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
OptimizationProblem sphereMinimizationProblem(objFunc);
sphereMinimizationProblem.setMinimization(true);
const Function sphereFunc(PMAAlgorithm_SphereConstraint(dimXZ, targetBeta));
sphereMinimizationProblem.setEqualityConstraint(sphereFunc);
sphereMinimizationProblem.setBounds(Interval(Point(dimXZ, -7.0), Point(dimXZ, 7.0)));
OptimizationAlgorithm algo(OptimizationAlgorithm::Build(sphereMinimizationProblem));
if (uStart_.getDimension() != dimXZ)
uStart_ = Point(dimXZ, 1.0);
algo.setStartingPoint(uStart_);
algo.setMaximumIterationNumber(100);
algo.run();
OptimizationProblem sphereMinimizationProblem(objFunc);
sphereMinimizationProblem.setMinimization(true);
const Function sphereFunc(PMAAlgorithm_SphereConstraint(dimXZ, targetBeta));
sphereMinimizationProblem.setEqualityConstraint(sphereFunc);
const Scalar boundMargin = targetBeta + 3.0;
sphereMinimizationProblem.setBounds(Interval(Point(dimXZ, -boundMargin), Point(dimXZ, boundMargin)));
OptimizationAlgorithm algo(OptimizationAlgorithm::Build(sphereMinimizationProblem));
if (uStart_.getDimension() != dimXZ)
uStart_ = Point(dimXZ, 1.0);
algo.setStartingPoint(uStart_);
algo.setMaximumIterationNumber(100);
algo.run();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/src/PMAAlgorithm.cxx` around lines 174 - 184, Update the sphere
minimization setup in the PMA algorithm to derive the coordinate bounds from
targetBeta_ (or the corresponding target reliability value), ensuring the
feasible ||u|| == targetBeta_ sphere is not excluded for large targets; remove
the fixed ±7.0 bounds. Replace the hardcoded 100-iteration cap with the
algorithm’s configurable or appropriately scaled iteration limit, preserving the
existing starting-point and optimization flow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants