Skip to content

fix(emulator): vectorize calcSpatialCov.matrix, removing O(n^3) redundant loop#3988

Closed
anshul23102 wants to merge 1 commit into
PecanProject:developfrom
anshul23102:fix/calcSpatialCov-redundant-loop
Closed

fix(emulator): vectorize calcSpatialCov.matrix, removing O(n^3) redundant loop#3988
anshul23102 wants to merge 1 commit into
PecanProject:developfrom
anshul23102:fix/calcSpatialCov-redundant-loop

Conversation

@anshul23102
Copy link
Copy Markdown
Contributor

Summary

Fixes #3964.

calcSpatialCov.matrix() contained a nested loop that was doing far more work than needed:

# Before
for (i in seq_len(nl)) {
  for (j in seq_len(nl)) {
    H[i, ] <- tau * exp(-psi * d[i, ])
  }
}

The inner j loop was completely redundant: on every iteration it overwrote H[i, ] with the same value, repeating the same assignment nl times. The outer i loop was also unnecessary since R applies arithmetic operations to entire matrices at once.

The fix replaces both loops with a single vectorized expression:

# After
tau * exp(-psi * d)

This produces identical output in O(n^2) instead of O(n^3). The already-vectorized calcSpatialCov.list sibling method was the model for this approach.

Regarding the second bug mentioned in #3964 (brittle unnamed run.id in do.call in sensitivity.R): both do.call calls at lines 309 and 470 already pass run.id = run.id as a named argument, so no change is needed there.

Changes

  • modules/emulator/R/calcSpatialCov.matrix.R: replace nested loops with one vectorized expression
  • modules/emulator/tests/testthat/test-calcSpatialCov.R: new test file covering correctness, output dimensions, diagonal values, symmetry, and agreement with calcSpatialCov.list
  • modules/emulator/NEWS.md: changelog entry

Test plan

  • New tests in test-calcSpatialCov.R pass
  • Output of calcSpatialCov.matrix() matches calcSpatialCov.list() for a single-component distance matrix

The inner `for (j in seq_len(nl))` loop was entirely redundant: it
overwrote `H[i, ]` with the same vector on every iteration, doing
nl times more work than necessary. The outer loop over rows was also
unnecessary because R's matrix arithmetic applies the operation to
all elements at once.

Replace both loops with a single vectorized expression:

    tau * exp(-psi * d)

This gives identical results in O(n^2) instead of O(n^3). Add tests
covering correctness, dimensions, symmetry, and agreement with the
already-vectorized calcSpatialCov.list implementation.

Fixes PecanProject#3964.
@infotroph
Copy link
Copy Markdown
Member

Is this a duplicate of #3969?

@anshul23102
Copy link
Copy Markdown
Contributor Author

Yes, this is a duplicate of #3969 - I missed that PR when I opened this. Closing in favor of that one.

@anshul23102 anshul23102 deleted the fix/calcSpatialCov-redundant-loop branch May 16, 2026 08:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix inefficient spatial covariance calculation and parameter mapping in uncertainty SA

2 participants