Skip to content

Add final_log_prob return value to AdamOptimization.optimize method#229

Merged
kazewong merged 14 commits into
kazewong:mainfrom
thomasckng:opt-bugfix
May 15, 2025
Merged

Add final_log_prob return value to AdamOptimization.optimize method#229
kazewong merged 14 commits into
kazewong:mainfrom
thomasckng:opt-bugfix

Conversation

@thomasckng

@thomasckng thomasckng commented May 14, 2025

Copy link
Copy Markdown

Summary by CodeRabbit

  • New Features
    • The optimization process now supports bounded parameter constraints.
    • Final log-probabilities of optimized positions are returned alongside results.
  • Bug Fixes
    • Improved gradient computation by incorporating additional data for more accurate optimization.

@coderabbitai

coderabbitai Bot commented May 14, 2025

Copy link
Copy Markdown

"""

Walkthrough

The changes add a bounds parameter to the AdamOptimization class to enforce box constraints during optimization. The gradient function is updated to receive a data argument. The optimize method now returns final log-probabilities along with optimized positions. Corresponding updates are made to the __call__ method and related tests to handle the extended return signature.

Changes

File(s) Change Summary
src/flowMC/strategy/optimization.py Added bounds parameter for box constraints; updated gradient call to include data; modified optimize to return final log-probabilities; adjusted __call__ to unpack new return value; improved type annotation spacing.
test/unit/test_strategies.py Updated test to unpack three return values from optimize; added assertions for shape and finiteness of final log-probabilities.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AdamOptimization
    participant ObjectiveFunction

    User->>AdamOptimization: call optimize(rng_key, objective, initial_position, data)
    AdamOptimization->>ObjectiveFunction: compute gradients (params, data)
    AdamOptimization->>AdamOptimization: project params within bounds
    AdamOptimization-->>User: return (rng_key, optimized_positions, final_log_prob)
    User->>AdamOptimization: call __call__()
    AdamOptimization->>User: unpack (rng_key, optimized_positions, _)
Loading

Poem

In the warren of code, a tweak or two,
Type hints spaced out, now clear and true.
Gradients corrected, data in tow,
Log-probs returned, optimization’s glow.
Bounds keep parameters safe and sound—
Hopping forward, improvements abound! 🐇✨
"""


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d768b01 and 15e103e.

📒 Files selected for processing (1)
  • src/flowMC/strategy/optimization.py (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/flowMC/strategy/optimization.py
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@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

🔭 Outside diff range comments (1)
src/flowMC/strategy/optimization.py (1)

79-88: 🛠️ Refactor suggestion

Update docstring to reflect new return value.

The docstring for the optimize method should be updated to describe the new return value (final_log_prob).

     def optimize(
         self,
         rng_key: PRNGKeyArray,
         objective: Callable,
         initial_position: Float[Array, " n_chain n_dim"],
         data: dict,
     ):
         """Optimization kernel. This can be used independently of the __call__ method.
 
         Args:
             rng_key: PRNGKeyArray
                 Random key for the optimization.
             objective: Callable
                 Objective function to optimize.
             initial_position: Float[Array, " n_chain n_dim"]
                 Initial positions for the optimization.
+            data: dict
+                Data dictionary to be passed to objective function.
+
+        Returns:
+            rng_key: PRNGKeyArray
+                Updated random key.
+            optimized_positions: Float[Array, " n_chain n_dim"]
+                Optimized positions after optimization.
+            final_log_prob: Float[Array, " n_chains"]
+                Final log probabilities of the optimized positions.
         """
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 134e1d0 and 99b6fa7.

📒 Files selected for processing (1)
  • src/flowMC/strategy/optimization.py (5 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/flowMC/strategy/optimization.py (2)
test/unit/test_strategies.py (1)
  • loss_fn (64-65)
test/unit/test_bundle.py (1)
  • logpdf (6-7)
🪛 GitHub Actions: pre-commit
src/flowMC/strategy/optimization.py

[error] 92-94: Prettier formatting check failed. File was reformatted by black. Run 'black src/flowMC/strategy/optimization.py' to fix code style issues.

🔇 Additional comments (6)
src/flowMC/strategy/optimization.py (6)

29-29: Type annotation formatting updated.

The type annotation for bounds has been properly updated to include a leading space inside the dimension specifier, enhancing consistency with other annotations in the codebase.


40-40: Type annotation formatting updated.

The type annotation for the bounds parameter in the constructor has been properly updated to match the class member annotation.


61-61: Type annotation formatting updated.

The return type annotation has been consistently updated with the space inside dimension specifier.


66-66: Updated return value handling to match signature.

The code now correctly unpacks the third return value (final log probabilities) from optimize using an underscore to indicate it's being ignored in this context.


131-131: Added final log probability to optimize method return value.

The method now returns a tuple that includes the final log probabilities of the optimized positions, which is the main objective of this PR. This additional return value will be useful for external callers that need to evaluate the quality of the optimization.


92-94:

Details

❓ Verification inconclusive

Fix formatting according to pipeline failure.

There's a pre-commit check failure related to formatting. Please run black src/flowMC/strategy/optimization.py to fix the code style issues.


🏁 Script executed:

#!/bin/bash
# Show the exact formatting issues
black --diff src/flowMC/strategy/optimization.py

Length of output: 146


Formatting error in CI – please format with Black
It looks like the pipeline failed on code style for src/flowMC/strategy/optimization.py. Ensure Black is installed locally and run:

black src/flowMC/strategy/optimization.py

or, if you’re using pre-commit:

pre-commit run --all-files

Then commit the updated file and re-run the CI checks.

🧰 Tools
🪛 GitHub Actions: pre-commit

[error] 92-94: Prettier formatting check failed. File was reformatted by black. Run 'black src/flowMC/strategy/optimization.py' to fix code style issues.

Comment thread src/flowMC/strategy/optimization.py Outdated

@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: 0

🧹 Nitpick comments (1)
test/unit/test_strategies.py (1)

67-69: Consider adding test assertions for the new return value

While correctly handling the return values, this test doesn't verify the validity of the newly added final_log_prob return value. Consider adding assertions to validate that the log probabilities are calculated correctly.

-        rng_key, optimized_position, _ = self.strategy.optimize(
+        rng_key, optimized_position, final_log_prob = self.strategy.optimize(
             key, loss_fn, initial_position, {"data": jnp.arange(self.n_dim)}
         )
+
+        # Assert final_log_prob shape matches expectation
+        assert final_log_prob.shape == (self.n_chains,)
+        # Assert log probabilities are finite (not NaN or Inf)
+        assert jnp.all(jnp.isfinite(final_log_prob))
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6f15b5e and f593ed0.

📒 Files selected for processing (1)
  • test/unit/test_strategies.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
test/unit/test_strategies.py (1)
src/flowMC/strategy/optimization.py (1)
  • optimize (72-133)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: build (3.12)
  • GitHub Check: pre-commit (3.12)
  • GitHub Check: build (3.11)
🔇 Additional comments (1)
test/unit/test_strategies.py (1)

67-67:

Details

✅ Verification successful

Properly handles the new return signature

The change correctly unpacks the three values now returned by optimize: rng_key, optimized_position, and the new final_log_prob (ignored with _). This matches the update to the optimize method in src/flowMC/strategy/optimization.py.


🏁 Script executed:

#!/bin/bash
# Check if the optimize method is now consistently used with three return values throughout the codebase
grep -n "optimize(" --include="*.py" -r . | grep -v "def optimize"

Length of output: 411


Optimize return signature is handled consistently

All occurrences of optimize( now unpack three return values (rng_key, optimized_position(s), and the ignored final_log_prob), both in

  • src/flowMC/strategy/optimization.py:66
  • test/unit/test_strategies.py:67

No further changes needed.

@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: 2

🧹 Nitpick comments (2)
src/flowMC/strategy/optimization.py (2)

60-64: Inconsistent dimension labels in jaxtyping annotations

You use n_chain elsewhere but return Float[Array, " n_chains n_dim"] here (extra “s”).
Although jaxtyping ignores the string content at runtime, keeping labels consistent greatly improves readability and static checking.

Consider renaming to n_chain (singular) everywhere or adopting n_chains consistently.


23-24: Default bounds shape may surprise users

The default jnp.array([[-jnp.inf, jnp.inf]]) has shape (1, 2) which broadcasts, but it silently applies the same bound to every dimension.
If a user passes n_dim > 1 without realising this broadcast they may get unintended behaviour.

Suggestions:

  1. Document this broadcasting explicitly in the docstring.
  2. Validate the provided bounds against initial_position.shape[-1] and raise if the shapes are incompatible.

Also applies to: 31-32, 42-42

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5651d24 and d0cb0ee.

📒 Files selected for processing (1)
  • src/flowMC/strategy/optimization.py (5 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/flowMC/strategy/optimization.py (3)
test/unit/test_bundle.py (1)
  • logpdf (6-7)
test/unit/test_strategies.py (1)
  • loss_fn (64-65)
src/flowMC/resource/nf_model/base.py (1)
  • loss_fn (99-100)

Comment thread src/flowMC/strategy/optimization.py Outdated
Comment thread src/flowMC/strategy/optimization.py

@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

♻️ Duplicate comments (3)
src/flowMC/strategy/optimization.py (3)

74-75: Fixed loss_fn signature

The loss function now correctly accepts the data parameter, addressing a previous issue noted in the past review comments.


120-120: Fixed parameter naming to prevent shadowing

Changing the scan body parameter from data to _step removes the potential for shadowing the outer data variable, addressing a bug noted in previous reviews.


124-126: Correct gradient function usage with data parameter

The gradient function now correctly passes the data parameter, fixing the issue identified in previous reviews.

🧹 Nitpick comments (2)
src/flowMC/strategy/optimization.py (2)

77-79: Consider exposing final log probabilities

The __call__ method discards the final log probabilities returned by optimize. Consider whether this information should be exposed to callers of __call__ for consistency with the updated optimize method.

-        rng_key, optimized_positions, _ = self.optimize(
+        rng_key, optimized_positions, final_log_prob = self.optimize(
            rng_key, loss_fn, initial_position, data
        )

-        return rng_key, resources, optimized_positions
+        return rng_key, resources, optimized_positions, final_log_prob

This would require updating the return type annotation as well.


148-148: Consider using a logging system instead of print

Using a print statement for indicating the optimization method could be disruptive in some contexts (e.g., notebooks, UIs). Consider using a proper logging system that can be configured by the user.

-        print("Using Adam optimization")
+        import logging
+        logging.info("Using Adam optimization")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fbe05fb and d768b01.

📒 Files selected for processing (1)
  • src/flowMC/strategy/optimization.py (6 hunks)
🧰 Additional context used
🪛 GitHub Actions: pre-commit
src/flowMC/strategy/optimization.py

[error] 52-54: Black formatting check failed. The file was reformatted by the black hook. Run 'black src/flowMC/strategy/optimization.py' to apply formatting locally.

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build (3.12)
  • GitHub Check: build (3.11)
🔇 Additional comments (10)
src/flowMC/strategy/optimization.py (10)

23-27: Well-documented bounds parameter

The docstring clearly explains the purpose and expected format of the bounds parameter, including how different shapes are handled for broadcasting or per-dimension constraints. This is helpful for users who need to enforce box constraints during optimization.


34-34: Good default for backward compatibility

Setting the default bounds to [-jnp.inf, jnp.inf] maintains backward compatibility with code that doesn't specify bounds, ensuring unbounded optimization remains the default behavior.


45-45: Proper parameter addition in constructor signature

The bounds parameter is correctly added to the constructor with the same default value as the class attribute.


53-58: Early validation prevents subtle errors

Good practice to validate the bounds shape early in the constructor. This prevents cryptic errors that might occur later during optimization.


90-96: Robust validation at runtime

The additional validation in optimize is important as it ensures that the bounds are compatible with the actual dimension of the initial positions. This serves as a safeguard against potential shape mismatches.


107-117: Clear and comprehensive docstring update

The docstring for optimize has been appropriately updated to document the new data parameter and the final_log_prob return value. This ensures developers understand the updated function signature.


129-131: Good implementation of bounds projection

Using optax.projections.projection_box is an appropriate way to enforce the box constraints during optimization. This ensures parameters stay within bounds after each update step.


155-161: Good validation of optimization results

Computing and checking the final log probabilities for NaN or infinity values is a helpful diagnostic feature that can alert users to potential issues with their optimization.


162-162: Updated return signature to include final log probabilities

The method now correctly returns the final log probabilities, which provides valuable information to users about the quality of the optimization results.


1-163: Formatting issue flagged by CI

The Black formatter has detected formatting issues. Please run the suggested command to fix them:

black src/flowMC/strategy/optimization.py
🧰 Tools
🪛 GitHub Actions: pre-commit

[error] 52-54: Black formatting check failed. The file was reformatted by the black hook. Run 'black src/flowMC/strategy/optimization.py' to apply formatting locally.

Comment thread src/flowMC/strategy/optimization.py
Float[Array, " n_chain n_dim"],
]:
def loss_fn(params: Float[Array, " n_dim"]) -> Float:
def loss_fn(params: Float[Array, " n_dim"], data: dict) -> Float:

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@kazewong This may affect performance, but removing it will cause an issue when calling below.

@thomasckng

Copy link
Copy Markdown
Author

@kazewong Ready for review. The tests fails with something related to the GH token, probably just because I am running it on my own fork.

@thomasckng

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 14, 2025

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@kazewong kazewong self-requested a review May 15, 2025 07:38
@kazewong kazewong merged commit e259442 into kazewong:main May 15, 2025
3 of 5 checks passed
@thomasckng thomasckng deleted the opt-bugfix branch May 16, 2025 01:06
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.

2 participants