Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 35 additions & 4 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,20 +263,18 @@ the expression's own domain as its condition ([#2142](https://github.com/asc-com
| `"(1 - cos(a))/(1 + cos(a))/tan(a/2)^2".Simplify()` | `(1 - cos(a)) / ((cos(a) + 1) * tan(a / 2) ^ 2)` | `1 provided not cos(a) + 1 = 0 and not tan(a / 2) = 0 and not cos(a / 2) = 0` |
| `"(cos(2*x) - 1)^2 + sin(2*x)^2 - 4*sin(x)^2".Simplify()` ([#2133](https://github.com/asc-community/AngouriMath/issues/2133)) | `2 + (-2) * cos(2 * x) + (-4) * sin(x) ^ 2` | `0` |

### `conj`, `arg` and `det` are refused by name
### `conj` and `arg` are refused by name

**Not silent: these now throw `UnrecognizedFunctionParseException` where they parsed.** A name the parser does not
know, followed by a bracket, is read as a product, so `arg(z)` was the variable `arg` times `z`, and `arg(z) = 1`
solved to `{ 1 / arg }`. `conjugate` was already refused by name; `conj` and `arg` are the conjugate and the argument
as other systems spell them, and `det` is the determinant, which a `Matrix` has as the property `Determinant` but an
expression cannot call. `re` and `im` are still read as products, as before: two letters is short enough to be a
as other systems spell them. `re` and `im` are still read as products, as before: two letters is short enough to be a
variable's name ([#2136](https://github.com/asc-community/AngouriMath/issues/2136)).

| Input | Was (2.6.0) | Now |
|---|---|---|
| `"arg(z)".ToEntity()` | `arg * z` | throws `UnrecognizedFunctionParseException` |
| `"conj(z)".ToEntity()` | `conj * z` | throws `UnrecognizedFunctionParseException` |
| `"det([[1, 2], [3, 4]])".ToEntity()` | `det * [[1, 2], [3, 4]]` | throws `UnrecognizedFunctionParseException` |

### Over the reals, a modulus of a polynomial is split at the polynomial's real roots

Expand Down Expand Up @@ -357,6 +355,26 @@ is rated no shorter ([#2135](https://github.com/asc-community/AngouriMath/issues
| `"cos(a + b)".Expand()` | `cos(a + b)` | `cos(a) * cos(b) + -sin(a) * sin(b)` |
| `"cos(a - b)".Expand()` | `cos(a - b)` | `cos(a) * cos(b) + sin(a) * sin(b)` |

### `det`, `transpose`, `dot`, `cross` and `resultant` are functions in an expression

**Not silent: these names followed by a bracket are now computed, or refused, where they were read as products or
did not parse.** `det(M)` is the determinant, `transpose(M)` the transpose, `dot(a, b)` the sum of the products of the
components, `cross(a, b)` the vector product in three dimensions and `cross(a)` a vector of the plane turned through a
right angle anticlockwise, as Mathematica's `Cross` of one vector is; `resultant(p, q, x)` eliminates `x`. There is
no node for any of them, so each is computed when it is parsed, and left as unsimplified as what it stands for would
be written out: `dot([1, 2], [3, 4])` is `1 * 3 + 2 * 4`. An argument that is not a matrix or a vector of
the right shape, written out or once its operations are carried out, throws `InvalidArgumentParseException`
([#2147](https://github.com/asc-community/AngouriMath/issues/2147)).

| Input | Was (2.6.0) | Now |
|---|---|---|
| `"det([[1, 2], [3, 4]])".ToEntity()` | `det * [[1, 2], [3, 4]]` | `-2` |
| `"transpose([1, 2])".ToEntity()` | `transpose * [1, 2]` | `[[1, 2]]`, the row |
| `"transpose(x)".ToEntity()` | `transpose * x` | throws `InvalidArgumentParseException` |
| `"cross([a, b])".ToEntity()` | `cross * [a, b]` | `[-b, a]` |
| `"dot([1, 2], [3, 4])".ToEntity()` | throws `UnhandledParseException` | `1 * 3 + 2 * 4` |
| `"resultant(x^2 - 1, x - a, x)".ToEntity()` | throws `UnhandledParseException` | `a ^ 2 - 1` |

### A subscript may have a subscript

**Not silent: what was a parse error is a name.** A name took at most one `_`, so `x_1_2` and `X_a_beta` were lexer
Expand All @@ -370,6 +388,19 @@ in LaTeX as `X_{a_{\beta}}`. `_` still neither begins nor ends a name, and two d
| `MathS.Var("X_a_beta").Latexize()` | an `UnhandledParseException` | `X_{a_{\beta}}` |
| `"x__1".ToEntity()` | an `UnhandledParseException` | an `UnhandledParseException` |

### A determinant of entries that are not polynomials is expanded by the library itself

**Silent: the same value, printed differently.** Where the fraction-free elimination cannot read the entries as
polynomials, `Matrix.Determinant` expanded along the first row with GenericTensor's Laplace expansion. That expansion
compiles an expression tree, which a native build cannot publish, and `det(M)` in an expression made it reachable from
every one. It is now written over the entries, with the same expansion along the first row and the cofactors'
alternating signs as subtractions ([#2147](https://github.com/asc-community/AngouriMath/issues/2147)).

| Input | Was (2.6.0) | Now |
|---|---|---|
| `"[[sin(x), cos(x)], [-cos(x), sin(x)]]".ToEntity()` as a `Matrix`, `.Determinant` | `sin(x) ^ 2 + -cos(x) * -cos(x)` | `sin(x) ^ 2 - cos(x) * -cos(x)` |
| `.Determinant.Simplify()` of `[[sqrt(a), b, 1], [c, sin(d), 2], [3, e_1, ln(f)]]` | `e_1 * ((-2) * sqrt(a) + c) + sin(d) * (sqrt(a) * ln(f) - 3) + 6 * b - b * c * ln(f)` | `sqrt(a) * (sin(d) * ln(f) - 2 * e_1) - b * (c * ln(f) - 6) + c * e_1 - 3 * sin(d)` |

### A numerical definite integral is Gauss–Legendre, with the digits it knows

**Silent: wrong answers, and values where there was NaN.** `Entity.DefiniteIntegral(x, a, b, steps)` was the mean of
Expand Down
3 changes: 3 additions & 0 deletions Sources/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed
[Tests/UnitTests/Convenience/IversonTest.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n

[Tests/UnitTests/Convenience/MatrixFunctionsInAnExpressionTest.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n

[Tests/UnitTests/Common/ExponentialOfALogarithmTest.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n

Expand Down
17 changes: 12 additions & 5 deletions Sources/AngouriMath/Core/Antlr/AngouriMath.g
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,15 @@ atom returns[Entity value]
| 'Ci(' args = function_arguments ')' { Assert("Ci", 1, $args.list.Count); $value = MathS.Ci($args.list[0]); }
| 'Shi(' args = function_arguments ')' { Assert("Shi", 1, $args.list.Count); $value = MathS.Shi($args.list[0]); }
| 'Chi(' args = function_arguments ')' { Assert("Chi", 1, $args.list.Count); $value = MathS.Chi($args.list[0]); }
/* The determinant, the transpose, the scalar and the vector product, and the resultant, each
computed from what it is applied to: there is no node for any of them, so a matrix or a
vector has to be written out, or be one once its operations are carried out.
https://github.com/asc-community/AngouriMath/issues/2147 */
| 'det(' args = function_arguments ')' { Assert("det", 1, $args.list.Count); $value = ParsingHelpers.Determinant($args.list[0]); }
| 'transpose(' args = function_arguments ')' { Assert("transpose", 1, $args.list.Count); $value = ParsingHelpers.Transposed($args.list[0]); }
| 'dot(' args = function_arguments ')' { Assert("dot", 2, $args.list.Count); $value = ParsingHelpers.Dot($args.list[0], $args.list[1]); }
| 'cross(' args = function_arguments ')' { Assert("cross", (1, 2), $args.list.Count); $value = ParsingHelpers.Cross($args.list); }
| 'resultant(' args = function_arguments ')' { Assert("resultant", 3, $args.list.Count); $value = ParsingHelpers.Resultant($args.list[0], $args.list[1], $args.list[2]); }

/* Names the library does not have. Each is a function every other CAS spells this way, so
a caller reaches for it, and without these rules each is silently read as a product --
Expand All @@ -634,13 +643,11 @@ atom returns[Entity value]

| 'trunc(' args = function_arguments ')' { $value = NotImplementedFunction("trunc", "rounding functions"); }
| 'conjugate(' args = function_arguments ')' { $value = NotImplementedFunction("conjugate", "complex conjugate as a symbolic function"); }
/* conj and arg are the conjugate and the argument as other systems spell them, and det the
determinant, which exists on a matrix but not in an expression. Each was read as a product:
arg(z) was arg * z. re and im are left as products, as MissingFunctionNamesRefusedTest
records. https://github.com/asc-community/AngouriMath/issues/2136 */
/* conj and arg are the conjugate and the argument as other systems spell them. Each was read
as a product: arg(z) was arg * z. re and im are left as products, as
MissingFunctionNamesRefusedTest records. https://github.com/asc-community/AngouriMath/issues/2136 */
| 'conj(' args = function_arguments ')' { $value = NotImplementedFunction("conj", "complex conjugate as a symbolic function"); }
| 'arg(' args = function_arguments ')' { $value = NotImplementedFunction("arg", "complex argument as a symbolic function"); }
| 'det(' args = function_arguments ')' { $value = NotImplementedFunction("det", "determinant in an expression; a Matrix has the property Determinant"); }
| 'domain(' args = function_arguments ')'
{
Assert("domain", 2, $args.list.Count);
Expand Down
12 changes: 10 additions & 2 deletions Sources/AngouriMath/Core/Antlr/AngouriMath.interp

Large diffs are not rendered by default.

44 changes: 26 additions & 18 deletions Sources/AngouriMath/Core/Antlr/AngouriMath.tokens
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,18 @@ T__184=185
T__185=186
T__186=187
T__187=188
NEWLINE=189
NUMBER=190
SPECIALSET=191
BOOLEAN=192
NAN=193
VARIABLE=194
COMMENT=195
WS=196
T__188=189
T__189=190
T__190=191
T__191=192
NEWLINE=193
NUMBER=194
SPECIALSET=195
BOOLEAN=196
NAN=197
VARIABLE=198
COMMENT=199
WS=200
'!'=1
'^'=2
'-'=3
Expand Down Expand Up @@ -373,13 +377,17 @@ WS=196
'Ci('=177
'Shi('=178
'Chi('=179
'trunc('=180
'conjugate('=181
'conj('=182
'arg('=183
'det('=184
'domain('=185
'piecewise('=186
'apply('=187
'lambda('=188
'NaN'=193
'det('=180
'transpose('=181
'dot('=182
'cross('=183
'resultant('=184
'trunc('=185
'conjugate('=186
'conj('=187
'arg('=188
'domain('=189
'piecewise('=190
'apply('=191
'lambda('=192
'NaN'=197
Loading
Loading