Skip to content

Added complex and covariance matrix quantity math - #11

Draft
HassanAkbar wants to merge 6 commits into
mainfrom
feat/complex-matrix-quantity-math
Draft

Added complex and covariance matrix quantity math#11
HassanAkbar wants to merge 6 commits into
mainfrom
feat/complex-matrix-quantity-math

Conversation

@HassanAkbar

@HassanAkbar HassanAkbar commented Jul 31, 2026

Copy link
Copy Markdown
Member

Adds Cartesian complex arithmetic and multivariate covariance propagation to Dcc::QuantityMath.

Complex is built on a two-element Matrix, so the propagation formula lives in one
place. An earlier version kept the two parts independent, which gave wrong answers once
you chained operations. (z1 * z2) * z3 came out 0.2625 instead of 0.3897.

Known and accepted:

  • compose_unit / inverse_unit are duplicated from real.rb. Two copies, not three.
    Extracting them means editing a file outside this PR.
  • Unit strings grow without simplifying (\ohm\cdot\ohm). That is what Real already does.
  • No == / hash on the new classes. A real gap, but that is its own feature.
  • x.div(ONE, n) is BigDecimal's way of rounding to n digits, not a stray division.
  • BigDecimal.limit is changed inside a block, but save_limit restores it even on raise.
  • SQRT_PRECISION and DERIVATIVE_PRECISION are both 30 and mean different things. Kept
    separate on purpose so changing one does not drag the other.

@HassanAkbar
HassanAkbar force-pushed the feat/complex-matrix-quantity-math branch from 2e5d14c to a85cfb3 Compare July 31, 2026 07:52

Copilot AI 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.

Pull request overview

This PR extends Dcc::QuantityMath with multivariate uncertainty propagation via covariance matrices and introduces a Cartesian complex quantity built on that multivariate model, ensuring correlations are preserved across chained operations.

Changes:

  • Add Dcc::QuantityMath::Matrix with covariance validation (symmetry/PSD) and Jacobian-based propagation (C_y = J C J^T).
  • Add Dcc::QuantityMath::Complex backed by a 2-element Matrix, with full 2×2 covariance propagation through + - * /.
  • Add Dcc::QuantityMath.exact_covariance and SQRT_PRECISION to ensure covariance math is performed at unlimited BigDecimal precision, plus comprehensive specs for the new functionality.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
lib/dcc/quantity_math.rb Adds SQRT_PRECISION, autoloads Matrix/Complex, and introduces exact_covariance to run covariance math with BigDecimal.limit(0).
lib/dcc/quantity_math/matrix.rb Implements multivariate quantity representation with covariance validation and Jacobian-based propagation.
lib/dcc/quantity_math/complex.rb Implements complex arithmetic and covariance propagation using a 2-element Matrix, including bounded derivative precision for division.
spec/dcc/quantity_math/matrix_spec.rb Adds unit, shape, symmetry/PSD validation, propagation, and BigDecimal.limit restoration tests for Matrix.
spec/dcc/quantity_math/complex_spec.rb Adds arithmetic, covariance propagation (including chaining), division edge cases, and reduced-limit stability tests for Complex.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/dcc/quantity_math/complex.rb Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Suppressed comments (2)

lib/dcc/quantity_math/matrix.rb:40

  • Matrix#[] always returns a Real with a non-nil uncertainty (computed via sqrt), even when the variance is exactly zero. In this codebase Real#uncertain? is based on uncertainty.nil?, so a zero-variance element currently becomes "uncertain" and will print ± 0/propagate as uncertain when used in further Real arithmetic (e.g., Complex#real for an exact complex). Consider treating a zero variance as exact and returning uncertainty: nil in that case.
      def [](index)
        ensure_index!(index)
        Real.new(value: values[index], unit: units[index],
                 uncertainty: covariance[index][index].sqrt(SQRT_PRECISION))
      end

lib/dcc/quantity_math/complex.rb:156

  • Complex#to_s always renders ± <uncertainty> for both components. For an exact complex (covariance diagonal entries are zero), this produces output like ± 0, which is inconsistent with Quantity#to_s / Real#to_s (they omit the uncertainty entirely when exact) and can be misleading to users reading formatted quantities. Consider omitting the ± … part per component when its uncertainty is zero.
      def to_s
        re, im = matrix.values
        u_re, u_im = matrix.uncertainties
        sign = im.negative? ? "-" : "+"
        suffix = unit ? " #{unit}" : ""
        "(#{re} ± #{u_re}) #{sign} (#{im.abs} ± #{u_im})i#{suffix}"
      end

Copilot AI 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.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Suppressed comments (1)

lib/dcc/quantity_math/matrix.rb:40

  • Matrix#[] always constructs a Real with a non-nil uncertainty (it uses sqrt(variance) even when the variance is exactly 0). In this codebase, Quantity#uncertain? is defined as !uncertainty.nil?, so a zero-variance element currently becomes "uncertain" and renders as ± 0.0, which contradicts the intended semantics for exact values (and Complex's own rendering logic for zero variance).
      def [](index)
        ensure_index!(index)
        Real.new(value: values[index], unit: units[index],
                 uncertainty: covariance[index][index].sqrt(SQRT_PRECISION))
      end

@HassanAkbar
HassanAkbar marked this pull request as ready for review August 11, 2026 15:30
@HassanAkbar
HassanAkbar marked this pull request as draft August 11, 2026 15:34
@HassanAkbar
HassanAkbar requested a lite review from Copilot August 11, 2026 15:39

Copilot AI 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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread lib/dcc/quantity_math.rb

Copilot AI 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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Suppressed comments (1)

TODO.complete/29-uncertainty-propagation.md:15

  • This says Complex and Matrix take exact BigDecimal square roots, but BigDecimal#sqrt(SQRT_PRECISION) is still a rounded approximation (just much higher precision than Float). Reword to avoid implying the result is mathematically exact.
- `Real` propagates uncertainty through `Math.sqrt(x.to_f)`
  (`lib/dcc/quantity_math/real.rb:79`, `:90`), so RSS and fractional results
  are capped at double precision rather than honouring the BigDecimal
  precision the design notes describe. `Complex` and `Matrix` do take exact
  BigDecimal square roots.

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