Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 4, 2025

  • Understand current implementation of get_statistics and parse_variables_input_to_index
  • Extend Symbol_input and String_input type definitions to support Vector{Vector{Symbol}}, Vector{Vector{String}}, Vector{Tuple}, and Tuple{Tuple} formats
  • Modify parse_variables_input_to_index to handle nested vector and tuple input for covariance groups
  • Add helper functions is_grouped_covariance_input and parse_covariance_groups
  • Update get_statistics to handle grouped covariance indices
  • Update covariance computation code to extract only specified groups
  • Add tests for the new grouped covariance functionality
  • Fix String_input nested vector parsing
  • Add documentation for the grouped covariance feature
  • Verify syntax and implementation correctness
  • Address code review feedback and simplify helper functions
  • Fix documentation wording
  • Change return format to single matrix with zeros for non-computed covariances
  • Optimize higher order propagation to reduce allocations
  • Further optimize determine_efficient_order to minimize all allocations
  • Update documentation example to use balanced groups
  • Add support for vector of tuples and tuple of tuples formats
  • Simplify grouped covariance indicator check
  • Apply vectorized approach to all remaining nested loops in determine_efficient_order

Summary

All optimizations completed. The vectorized approach using reshape and sum operations is now consistently applied throughout all determine_efficient_order functions (first, second, and third order) for both observable and covariance variable dependency detection. All nested loops for dependency detection have been eliminated, and propagation loops use precomputed matrix slices with no copy() calls.

Original prompt

in the get_statistics function, the covariance argument allow for the input to be Vector of Vectors of either Symbols or Strings so that you specify groups of variables to compute the covariance for. this allows more granular control over which covariances to compute. so you can say covariance = [[:y, :c], [:k, :i]] to compute covariances for y and c together and k and i together, but not between y and k for example. this would require modifying the parsing function to handle this new input format. = Symbol[], and modifying the rest of the code accordingly.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 6 commits November 4, 2025 22:53
Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Copilot AI changed the title [WIP] Update get_statistics function to handle vector of vectors for covariance Add grouped covariance input to get_statistics Nov 4, 2025
Copilot AI requested a review from thorek1 November 4, 2025 23:13
Copilot finished work on behalf of thorek1 November 4, 2025 23:13
Copy link
Owner

@thorek1 thorek1 left a comment

Choose a reason for hiding this comment

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

@copilot return one matrix only where you then leave blank the covariances not calculated (instead of now returning as many matrices as there are entries in the vector)

…s-group elements

Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 4, 2025

@copilot return one matrix only where you then leave blank the covariances not calculated (instead of now returning as many matrices as there are entries in the vector)

Changed to return a single matrix where cross-group covariances are set to zero. The implementation now fills only the specified group blocks and leaves zeros elsewhere. Commit: e949bfd

Copilot AI requested a review from thorek1 November 4, 2025 23:32
Copilot finished work on behalf of thorek1 November 4, 2025 23:32
Copy link
Owner

@thorek1 thorek1 left a comment

Choose a reason for hiding this comment

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

@copilot Add the define_efficient_order logic to the second and first order calculations as well (currently it's only there for third order)

Copy link
Contributor Author

Copilot AI commented Nov 5, 2025

@copilot Add the define_efficient_order logic to the second and first order calculations as well (currently it's only there for third order)

I understand you want to add the determine_efficient_order optimization to first and second order calculations (similar to how it's currently used in third order). This would involve:

  1. Adding observables and covariance parameters to calculate_covariance and calculate_second_order_moments_with_covariance
  2. Using determine_efficient_order to compute only necessary dependencies
  3. Updating get_statistics to pass these parameters

This is a substantial refactoring. Should I:

  • Maintain backward compatibility by making these parameters optional with defaults that compute everything (like current behavior)?
  • Or create new function variants specifically for the optimized computation?

Also, do you want this optimization applied even when all variables are requested, or only when specific subsets are requested?

Copilot AI requested a review from thorek1 November 5, 2025 00:23
Copilot finished work on behalf of thorek1 November 5, 2025 00:23
Copy link
Owner

@thorek1 thorek1 left a comment

Choose a reason for hiding this comment

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

@copilot The higher order propagation code generates too many allocations. Instead of the loop generate the vector to be multiplied with the solution to get the affected states

Replace nested loops with vectorized operations using Kronecker product selectors. Instead of iterating through all column indices and checking conditions in nested loops, generate a selector vector that identifies relevant columns where all states are dependencies, then multiply with the solution matrix once.

Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 5, 2025

@copilot The higher order propagation code generates too many allocations. Instead of the loop generate the vector to be multiplied with the solution to get the affected states

Optimized the higher order propagation code by replacing nested loops with vectorized operations. Instead of iterating through all column indices, the code now generates a selector vector using Kronecker products (e.g., kron(prev_dependencies, prev_dependencies) for second order) to identify relevant columns in one operation, then processes them with a single matrix operation. This eliminates many intermediate allocations from the loop-based approach. Commit: 18d77b5

Copilot AI changed the title Add grouped covariance input to get_statistics Add grouped covariance input to get_statistics and optimize higher order propagation Nov 5, 2025
Copilot AI requested a review from thorek1 November 5, 2025 23:16
Copilot finished work on behalf of thorek1 November 5, 2025 23:16
Copy link
Owner

@thorek1 thorek1 left a comment

Choose a reason for hiding this comment

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

@copilot Think about other ways to minimise allocations in the determine_efficient_order functions and implement them

Key optimizations:
1. Precompute repeated indexin and matrix slicing operations outside loops
2. Replace copy(dependencies_in_states) with direct assignment to avoid allocations
3. Vectorize nested loops for second/third order dependency detection using reshape and sum operations
4. Build lookup dictionary for covariance variable searches instead of repeated findfirst calls
5. Reuse precomputed matrix slices in propagation loops
6. Eliminate redundant while loop condition checks

Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 5, 2025

@copilot Think about other ways to minimise allocations in the determine_efficient_order functions and implement them

Implemented additional optimizations to minimize allocations in determine_efficient_order:

  1. Precomputed operations: Moved repeated indexin() and matrix slicing outside loops (e.g., 𝐒₁_states, 𝐒₂_states, 𝐒₃_states)
  2. Eliminated copy() calls: Replaced copy(dependencies_in_states) with direct variable assignment to avoid unnecessary allocations
  3. Vectorized nested loops: Replaced nested loops for second/third order dependency detection with reshape + sum operations along dimensions
  4. Lookup dictionary: Added var_to_idx dictionary for O(1) covariance variable lookups instead of repeated findfirst() calls
  5. Reused computed slices: Matrix slices computed once and reused in propagation loops
  6. Simplified loop logic: Changed while loop to avoid redundant comparisons

These changes eliminate allocation hotspots while maintaining the same functionality. Commit: 8bc6672

Copilot AI changed the title Add grouped covariance input to get_statistics and optimize higher order propagation Add grouped covariance input to get_statistics and optimize determine_efficient_order Nov 5, 2025
Copilot AI requested a review from thorek1 November 5, 2025 23:52
Copilot finished work on behalf of thorek1 November 5, 2025 23:52
:standard_deviation => [0.0266642, 0.264677, 0.0739325, 0.0102062]
# For grouped covariance (computing covariances only within specified groups):
get_statistics(RBC, RBC.parameter_values, covariance = [[:c, :k], [:q]])
Copy link
Owner

Choose a reason for hiding this comment

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

@copilot make the second group also have two variables instead of only :q

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated the documentation example to use balanced groups with two variables each: [[:c, :k], [:y, :i]] instead of [[:c, :k], [:q]]. The output description now reflects a 4×4 matrix instead of 3×3. Commit: 093b24d

covar_var_idx = @ignore_derivatives parse_variables_input_to_index(covariance, 𝓂.timings)

# Check if covariance is grouped and parse groups
is_grouped_covar = @ignore_derivatives is_grouped_covariance_input(covariance)
Copy link
Owner

Choose a reason for hiding this comment

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

@copilot why do you need this indicator?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The indicator was used to check whether to extract grouped covariances or use standard extraction. Simplified this by directly checking !isnothing(covar_groups) instead of maintaining a separate is_grouped_covar variable. Commit: a13fd2d

Changed the grouped covariance example from [[:c, :k], [:q]] to [[:c, :k], [:y, :i]] to better demonstrate the feature with balanced groups.

Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
# Type definitions
const Symbol_input = Union{Symbol,Vector{Symbol},Matrix{Symbol},Tuple{Symbol,Vararg{Symbol}}}
const String_input = Union{String,Vector{String},Matrix{String},Tuple{String,Vararg{String}}}
const Symbol_input = Union{Symbol,Vector{Symbol},Matrix{Symbol},Tuple{Symbol,Vararg{Symbol}},Vector{Vector{Symbol}}}
Copy link
Owner

Choose a reason for hiding this comment

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

@copilot also allow for vector of tuples or tuples of tuples

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added support for Vector{Tuple{Symbol,Vararg{Symbol}}} and Tuple{Tuple{Symbol,Vararg{Symbol}},Vararg{Tuple{Symbol,Vararg{Symbol}}}} (and their String equivalents). Updated Symbol_input and String_input type definitions, and modified is_grouped_covariance_input, parse_covariance_groups, and parse_variables_input_to_index to handle these formats. Commit: a13fd2d

Copilot AI requested a review from thorek1 November 6, 2025 09:53
Copilot finished work on behalf of thorek1 November 6, 2025 09:53
…iance, simplify indicator check

Extended Symbol_input and String_input to support Vector{Tuple} and Tuple{Tuple} formats for grouped covariance. Updated is_grouped_covariance_input, parse_covariance_groups, and parse_variables_input_to_index to handle these new formats. Simplified is_grouped_covar indicator by directly checking !isnothing(covar_groups) where needed.

Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Copilot finished work on behalf of thorek1 November 6, 2025 10:01
for i in 1:
for j in 1:
for k in 1:
if sum(abs, s_s_s_to_y₃[:, col_idx]) > tol
Copy link
Owner

Choose a reason for hiding this comment

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

@copilot implement the vectorised approach here and wherever else in the determine_efficient_order functions where you didnt do it yet

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Applied vectorized approach to all remaining locations in determine_efficient_order functions:

  1. Second-order covariance section: Replaced nested loops with reshape to nˢ×nˢ matrix and dimensional sums
  2. Third-order covariance section: Replaced triple-nested loops with reshape to nˢ×nˢ×nˢ tensor and dimensional sums
  3. Propagation loops: Precomputed matrix slices and eliminated copy() calls in both second and third-order covariance sections

All nested loops for dependency detection have been removed. Commit: 291bf89

…efficient_order

Replaced all remaining nested loops in covariance variable dependency detection with vectorized reshape and sum operations. Also precomputed matrix slices and eliminated copy() calls in propagation loops for both second and third order covariance sections.

Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Copilot AI requested a review from thorek1 November 6, 2025 10:24
Copilot finished work on behalf of thorek1 November 6, 2025 10:25
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