镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Compile a matrix argument as an array, with its inverse and whole powers - #2429

Open
Rafael-SOWNet wants to merge 1 commit into
masterfrom
feature/compiled-matrix-operations
Open

Rafael-SOWNet wants to merge 1 commit into
masterfrom
feature/compiled-matrix-operations

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

Closes #2422.

A matrix compiles under the LINQ compiler since #1425. This adds what was missing around it: matrices as T[,] arguments and results, the inverse, a whole-exponent check on matrix powers, written shapes checked when compiling, and #425's simplify-first in FastExpression.

Coverage, by work/compilecheck's matrix section. 33 expressions in x and y are compared entry by entry with Substitute → Evaled → EvalNumerical, at real and non-real points.

master 6d5f1755a this branch
FastExpression (a number only) 2 of 33 5 of 33
LINQ Complex / double 27 / 28 of 33 27 / 28 of 33; the shape rows are now refused at Compile
[[x, 1], [0, y]] ^ x over double wrong: the identity at 0.7 throws InvalidMatrixOperationException when called
matrix arguments as GenTensor<double> / <Complex> (17 rows) A ^ (-1) throws NotSupportedException when called; 1 / A and A / B are refused every row agrees with evaluation; a singular A gives NaN
matrix arguments as double[,] refused, or KeyNotFoundException every row agrees with evaluation

Behaviour changes (2.6.0 → now). The 2.6.0 values were measured on the 2.6.0 package; the entries are in BREAKING-CHANGES.md.

Input 2.6.0 Now
x / A at A = [[1, 2], [3, 4]], x = 2 [[2, 1], [0.667, 0.5]] [[-4, 2], [3, -1]]
A ^ (-1) at [[1, 2], [3, 4]] throws NotSupportedException when called [[-2, 1], [1.5, -0.5]]
A / B UncompilableNodeException A times the inverse of B
[[x, 1], [0, y]] ^ x over double at (0.7, -1.3) [[0.779, 1], [0, NaN]], each entry to the power throws InvalidMatrixOperationException
the same over Complex UncompilableNodeException the matrix power at a whole x
[[x, 1, y]] ^ 2 over Complex at (1, 2) [[1, 1, 4]] InvalidMatrixOperationException when compiling
A * B over double[,] UncompilableNodeException the matrix product
FastExpression [1, 0]T * [[a, b], [c, d]] * [0, 1] UncompilableNodeException b
[[1, 0]] * A * [[0], [1]] to double, at A = [[1, 2], [3, -4]] 0, for every A 2
A + [[1, 2], [3, 4]] over GenTensor<double> UncompilableNodeException [[2, 4], [6, 0]]
[[1, 0]] * A over GenTensor<double> KeyNotFoundException [[1, 2]]

[[1, 0]] * A * [[0], [1]] was a wrong answer on 2.6.0. Simplification before compiling read the argument A as a number. Now only the parts that mention no matrix argument are simplified first. A result known to be 1×1 compiles as a number, and written constants compile over the arguments' element type.

Out of scope

Checked on this branch

  • Tests: UnitTests 19400 passed, plus the MCP, Terminal, InteractiveWrapper and F# wrapper suites, and the AOT smoke test. A quotient and a power over Complex[,] were added to the smoke test.
  • Public API: the seven new TensorCompilation helpers are recorded in PublicApi.txt. The compiled expression trees call them, as they call the existing Add, Multiply and Power.
  • Harnesses: BoundCheck, RootCheck, CasBench, PropCheck, SimpSweep, RuleCheck, CanonCheck and Confluence all pass. limitcheck is not run, since nothing here touches limits.

🤖 Generated with Claude Code

A matrix compiles under the LINQ compiler since #1425, to a GenTensor, with the sum,
difference, product, scalar operations and whole power as loops over the element wrapper.
work/compilecheck's matrix section found what is wrong around that:

- A matrix power's exponent was cast to int, which truncates. On master
  [[x, 1], [0, y]] ^ x over double at 0.7 was the identity; on 2.6.0 simplification raised
  each entry to the power instead, [[0.779, 1], [0, NaN]]. Evaluation leaves a matrix to a
  power that is not whole unevaluated. The exponent is now checked to be whole when the
  delegate is called, and InvalidMatrixOperationException is thrown where it is not. An
  exponent of type Complex compiles, where it was refused for want of a conversion to int.
- The inverse was not compiled: A ^ (-1) of an argument threw NotSupportedException when
  called, and 1 / A and A / B were refused, where evaluation answers each with the inverse.
  It is Gauss-Jordan elimination with partial pivoting over double, float and Complex; a
  zero pivot gives NaN in every entry, as a compiled division by zero has no value. A
  matrix of whole numbers is not inverted, its inverse not being one.
- Written matrices whose shapes do not fit, which simplification leaves as written, are
  refused by Compile with InvalidMatrixOperationException naming the shapes. On master such
  a delegate threw at every call; on 2.6.0 [[x, 1, y]] ^ 2 compiled to the entrywise square.
  A matrix argument's shape is checked when the delegate is called.
- double[,], Complex[,] and the other element types' arrays were refused, or leaked
  KeyNotFoundException. They are matrices as arguments and as the result, converted to and
  from the tensor at the delegate's boundary, so a caller need not know GenericTensor.
- FastExpression simplifies an expression with a matrix in it first, as the LINQ compiler
  does since #425, so a number built out of matrices compiles there too.
- That simplification reads a variable as a number, so with a matrix argument beside written
  matrices [[1, 0]] * A * [[0], [1]] was multiplied out to 0, which the LINQ delegate returned
  whatever A was, on 2.6.0 as on master. Only the parts that do not mention a matrix argument
  are simplified now, a written matrix beside a matrix argument is over the argument's element
  type, and a matrix known when compiling to be 1 x 1 compiles as a number, its entry.

Measured: compilecheck's matrix section on master, FastExpression 2 of 33, LINQ Complex 27,
LINQ double 28, two disagreements; on the branch FastExpression 5, every matrix-argument row
agrees with evaluation, and the one disagreement left is abs([x, y]) at a complex point,
which is in simplification. Each new test compares a compiled matrix with Substitute then
Evaled, entry by entry, at negative and non-real points, and the 1 x 1 regression against
Substitute then Evaled at real and complex A, over double and Complex. Compile, matrix and
tensor tests: 1264 passed. FSharpWrapperUnitTests: 134 passed. The NativeAOT smoke test,
published with a quotient and a power over Complex[,] added: 74 of 74. The 2.6.0 values in
BREAKING-CHANGES.md are measured on the 2.6.0 package.

Closes #2422.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.71038% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.85%. Comparing base (2eea2e9) to head (2a59224).

Files with missing lines Patch % Lines
...unctions/Compilation/IntoLinq/TensorCompilation.cs 89.87% 5 Missing and 11 partials ⚠️
...Functions/Compilation/IntoLinq/IntoLinqCompiler.cs 94.11% 0 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2429      +/-   ##
==========================================
+ Coverage   86.81%   86.85%   +0.03%     
==========================================
  Files         312      312              
  Lines       69551    69709     +158     
  Branches    20316    20378      +62     
==========================================
+ Hits        60383    60546     +163     
+ Misses       4932     4918      -14     
- Partials     4236     4245       +9     
Flag Coverage Δ
cpp 37.77% <ø> (ø)
csharp 87.39% <90.71%> (+0.03%) ⬆️
fsharp 32.97% <ø> (ø)
interactive 39.81% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...gouriMath/Functions/Compilation/IntoFE/Compiler.cs 85.86% <100.00%> (+0.40%) ⬆️
...ctions/Compilation/IntoLinq/CompilationProtocol.cs 93.97% <100.00%> (+0.02%) ⬆️
...Functions/Compilation/IntoLinq/IntoLinqCompiler.cs 96.73% <94.11%> (-0.70%) ⬇️
...unctions/Compilation/IntoLinq/TensorCompilation.cs 72.88% <89.87%> (+21.49%) ⬆️

... and 7 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This branch has not been deployed

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

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

Compiled matrices: arrays at the boundary, the inverse, whole exponents, shapes checked when compiling

1 participant