Repository navigation
Make det, transpose, trace and an entry nodes that apply to a matrix argument - #2436
Open
Rafael-SOWNet wants to merge 1 commit into
Open
Rafael-SOWNet wants to merge 1 commit into
Rafael-SOWNet wants to merge 1 commit into
Conversation
…argument det(A) of a symbol was refused at parsing, transpose(x) too, trace(A) was the product trace * A, and A[i, j] did not parse. Each of the four is now a node over what it is applied to, carried out once that is a matrix: by Substitute, Simplify, Evaled and a compiled delegate taking T[,]. Of a matrix written out each is still computed as it is parsed, as det and transpose were, so nothing #2180 answered moves but transpose(x). - Determinantf, Transposef, Tracef and MatrixEntryf, with printing that parses back, LaTeX (\det, ^{\mathrm{T}}, \operatorname{tr}, a subscript), SymPy, substitution, sorting, serialization, and MathS.Matrices.Determinant, Transpose, Trace and Entry. - An entry counts its row and column from 1, as a_ij does: [[1, 2], [3, 4]][2, 1] is 3. The brackets follow an atom directly, which did not parse before. - A non-square matrix has no determinant and no trace, and an index out of range or not whole names no entry: the node is left as it is, never a number. Written out, each is refused at parsing, as det of a non-square matrix was. A number, a statement or a set is no matrix and is refused. - det(transpose(A)) is det(A), trace(transpose(A)) is trace(A), transpose(transpose(A)) is A and transpose(A)[k, l] is A[l, k]. - The transpose, the trace and an entry are differentiated through the matrix; the determinant keeps its derivative node, Jacobi's formula needing the adjugate. - Compiled: the transpose, Bareiss' fraction-free determinant with the largest pivot where the elements have a size (exact over long and int), the trace, and the entry with its indices checked whole and in range when called. Shapes written into the expression are checked at Compile. - A product with a transpose in it is a product of matrices, and Simplify read it as commutative: transpose(A) * A - A * transpose(A) simplified to 0, and transpose(A) * B printed as B * transpose(A). Such a product is set aside as a name of its own while the rest is simplified, and put back with each factor simplified in place; the canonical sort and the print order leave it as written. - A name beside a written matrix may stand for a matrix, and simplification reads it as a number: det(A [[2, 0], [0, 3]]) was 6 A^2 at parsing, and a compiled delegate computed that. Such an argument is not carried out, at parsing, in evaluation or by Simplify, until the name is a matrix; det([[x, 1], [2, x]]), whose names are entries, is x^2 - 2 as before. Measured: the new MatrixOperationNodesTest compares every value with one computed from the entries, at real, negative and non-real matrices, 2x2 and 3x3, and every compiled value with evaluation, including a matrix argument beside a written matrix, which the base commit's SimplifiedAroundMatrixArguments leaves to these nodes. The 2.6.0 values in BREAKING-CHANGES.md are measured on the 2.6.0 package. Closes #2427. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rafael-SOWNet
force-pushed
the
feature/matrix-operation-nodes
branch
from
November 13, 2026 20:41
e11037a to
2a3eef8
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2427.
det,transpose,traceand an entryA[k, l]are now nodes. They can be written of a name, such asdet(A),transpose(A) * B,trace(A * B)orA[1, 2], and are carried out once the name is a matrix: by substitution, simplification, evaluation, and compilation overT[,](#2429).Parsing:
det,transposeandtraceof a name were read as products on 2.6.0, sodet(A)wasdet * A.det([[1, 2], [3, 4]])is-2.traceandM[k, l]are new. A bracket straight after an atom did not parse before, so that syntax adds rather than changes.det(5)throws.Indices count from 1, as
a_ijdoes, and as in Mathematica, Maple, Maxima, MATLAB and Julia. The C#Matrixindexer still counts from 0, as C# does, soM[k, l]in an expression ismatrix[k - 1, l - 1]in code. The syntax page says so.No value is invented: a non-square matrix has no determinant or trace, and an index out of range or not whole names no entry. Each stays unevaluated.
Rewrites:
transpose(transpose(A)) → A,det(transpose(A)) → det(A),trace(transpose(A)) → trace(A)andtranspose(A)[k, l] → A[l, k].Derivatives are taken through the matrix for transpose, trace and an entry. The determinant keeps its
derivativenode, since Jacobi's formula needs an adjugate.Compiled:
long;Known shapes are checked at
Compile.API:
MathS.Matrices.Determinant,Transpose,TraceandEntry. They are recorded inPublicApi.txtwith the four node records and the compiled helpers.Two wrong answers that these nodes would have made easy to reach are fixed. Both come from a name having no type yet (#1237):
transpose(A) * A - A * transpose(A)simplified to0, andtranspose(A) * BtoB * transpose(A).transpose(A)*B + transpose(A)*Cis no longer factored.A*B - B*Astill gives0, since nothing yet saysAis a matrix. That waits for Typed variables #1237.det(A * [[2, 0], [0, 3]])came out as6 * A^2.det([[x, 1], [2, x]])is stillx^2 - 2."det(A)"det * Adet(A), aDeterminantf"det(A)"withA = [[1, 2], [3, 4]], evaluated[[det, det * 2], [det * 3, det * 4]]-2"transpose(A) * B"transpose * A * Btranspose(A) * B"trace([[1, 2], [3, 4]])"trace * [[1, 2], [3, 4]]1 + 4"A[1, 2]","[[1, 2], [3, 4]][2, 1]"UnhandledParseExceptionA[1, 2];3"det(5)"det * 5InvalidArgumentParseException"det(x * [[1, 2], [3, 4]])"det * x * [[1, 2], [3, 4]]xmay stand for a matrixThe rows are in BREAKING-CHANGES.md, measured on the 2.6.0 package. #2180's unshipped
transpose(x)row, which no longer throws, is updated. The parser was regenerated with the vendored ANTLR; regenerating the unmodified grammar first gave an empty diff.Checked on this branch:
🤖 Generated with Claude Code