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
22 changes: 13 additions & 9 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,19 +263,23 @@ 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` and `arg` are refused by name
### `conjugate`, `conj` and `arg` are functions

**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. `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)).
**Not silent: these names followed by a bracket are now the complex conjugate and the principal argument, where they
were read as products or refused.** 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(z)` and `conj(z)` are
`Entity.Conjugatef`, carried through sums, differences, products, quotients and whole powers and not through a root or
a logarithm; `arg(z)` is `Entity.Argf`, in `(-pi, pi]`, with no value at `0`
([#2136](https://github.com/asc-community/AngouriMath/issues/2136),
[#2145](https://github.com/asc-community/AngouriMath/issues/2145)). `re` and `im` are still read as products.

| Input | Was (2.6.0) | Now |
|---|---|---|
| `"arg(z)".ToEntity()` | `arg * z` | throws `UnrecognizedFunctionParseException` |
| `"conj(z)".ToEntity()` | `conj * z` | throws `UnrecognizedFunctionParseException` |

| `"conjugate(z)".ToEntity()` | throws `UnrecognizedFunctionParseException` | `conjugate(z)` |
| `"conj(z)".ToEntity()` | `conj * z` | `conjugate(z)` |
| `"conj(3 + 4i)".ToEntity().Simplify()` | `(3 + 4i) * conj` | `3 - 4i` |
| `"arg(z)".ToEntity()` | `arg * z` | `arg(z)` |
| `"arg(-1)".ToEntity().Simplify()` | `-arg` | `pi` |
### Over the reals, a modulus of a polynomial is split at the polynomial's real roots

**Silent: an answer with entries that solve nothing is exact.** With the real codomain an equation in moduli was
Expand Down
5 changes: 5 additions & 0 deletions Sources/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed
[Tests/UnitTests/Convenience/BinomialTest.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/ConjugateAndArgumentTest.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/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

Expand Down Expand Up @@ -398,6 +401,8 @@ file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed

[AngouriMath/Core/Entity/Continuous/Entity.Continuous.Iverson.Classes.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
[AngouriMath/Core/Entity/Continuous/Entity.Continuous.ComplexParts.Classes.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
[AngouriMath/Core/Entity/Continuous/Entity.Continuous.Aleph.Classes.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
48 changes: 48 additions & 0 deletions Sources/AngouriMath/Convenience/MathS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1394,6 +1394,54 @@ public static Entity VectorLength(Matrix v)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Entity Iverson(Entity statement) => new Iversonf(statement);

/// <summary>The complex conjugate <c>conjugate(z)</c>: <c>a - b i</c> for <c>z = a + b i</c></summary>
/// <param name="z">The argument, any complex number</param>
/// <returns>The <see cref="Entity.Conjugatef"/> node</returns>
/// <remarks>
/// It is carried through sums, products, quotients and whole powers, and fixes what is known to
/// be real: a number, and a node whose codomain is real, such as a modulus or <c>domain(x, RR)</c>.
/// https://github.com/asc-community/AngouriMath/issues/2145
/// </remarks>
/// <example>
/// <code>
/// using System;
/// using static AngouriMath.MathS;
///
/// Console.WriteLine(Conjugate("3 + 4i").Simplify());
/// Console.WriteLine(Conjugate("a * b + i").Simplify());
/// </code>
/// Prints
/// <code>
/// 3 - 4i
/// -i + conjugate(a) * conjugate(b)
/// </code>
/// </example>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Entity Conjugate(Entity z) => new Conjugatef(z);

/// <summary>The principal argument <c>arg(z)</c>, in <c>(-pi, pi]</c>, so that <c>z = |z| e^(i arg(z))</c></summary>
/// <param name="z">The argument, any complex number but 0, where it has no value</param>
/// <returns>The <see cref="Entity.Argf"/> node</returns>
/// <remarks>https://github.com/asc-community/AngouriMath/issues/2145</remarks>
/// <example>
/// <code>
/// using System;
/// using static AngouriMath.MathS;
///
/// Console.WriteLine(Arg("-1").Simplify());
/// Console.WriteLine(Arg("1 + i").Simplify());
/// Console.WriteLine(Arg("-1 - i").Simplify());
/// </code>
/// Prints
/// <code>
/// pi
/// pi / 4
/// -3/4 * pi
/// </code>
/// </example>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Entity Arg(Entity z) => new Argf(z);

/// <summary>The aleph number <c>aleph(k)</c>, the size of an infinite set</summary>
/// <param name="index">The index, a whole number from zero</param>
/// <returns>The <see cref="Entity.Alephf"/> node</returns>
Expand Down
12 changes: 6 additions & 6 deletions Sources/AngouriMath/Core/Antlr/AngouriMath.g
Original file line number Diff line number Diff line change
Expand Up @@ -635,19 +635,19 @@ atom returns[Entity value]
| '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]); }
/* The complex conjugate, by its name and by the shorter one other systems use.
https://github.com/asc-community/AngouriMath/issues/2145 */
| 'conjugate(' args = function_arguments ')' { Assert("conjugate", 1, $args.list.Count); $value = MathS.Conjugate($args.list[0]); }
| 'conj(' args = function_arguments ')' { Assert("conj", 1, $args.list.Count); $value = MathS.Conjugate($args.list[0]); }
/* The principal argument, in (-pi, pi]. https://github.com/asc-community/AngouriMath/issues/2145 */
| 'arg(' args = function_arguments ')' { Assert("arg", 1, $args.list.Count); $value = MathS.Arg($args.list[0]); }

/* 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 --
see NotImplementedFunction above. Refusing is not the feature; it is the difference
between a missing function and a wrong answer. */

| '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. 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"); }
| 'domain(' args = function_arguments ')'
{
Assert("domain", 2, $args.list.Count);
Expand Down
2 changes: 1 addition & 1 deletion Sources/AngouriMath/Core/Antlr/AngouriMath.interp
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,10 @@ null
'dot('
'cross('
'resultant('
'trunc('
'conjugate('
'conj('
'arg('
'trunc('
'domain('
'piecewise('
'apply('
Expand Down
8 changes: 4 additions & 4 deletions Sources/AngouriMath/Core/Antlr/AngouriMath.tokens
Original file line number Diff line number Diff line change
Expand Up @@ -382,10 +382,10 @@ WS=200
'dot('=182
'cross('=183
'resultant('=184
'trunc('=185
'conjugate('=186
'conj('=187
'arg('=188
'conjugate('=185
'conj('=186
'arg('=187
'trunc('=188
'domain('=189
'piecewise('=190
'apply('=191
Expand Down
Loading
Loading