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
13 changes: 13 additions & 0 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,19 @@ carried it once combined: a second derivative of `1/sqrt(x^2 + 13)` stated `not
| `"(a provided b > 0) + (c provided b > 0)".ToEntity().InnerSimplified` | `a + c provided b > 0 and b > 0` | `a + c provided b > 0` |
| `MathS.Equations("sqrt(y) - x", "y - a").Solve("x", "y")` | `[[sqrt(a), (sqrt(a)) ^ 2], [-sqrt(a), (-sqrt(a)) ^ 2]]` | `[[sqrt(a) provided C(sqrt(a)), (sqrt(a)) ^ 2 provided C(sqrt(a))], [-sqrt(a) provided C(-sqrt(a)), (-sqrt(a)) ^ 2 provided C(-sqrt(a))]]`, `C(v)` being `v = 0 or -1/2 * pi < arg(v) and arg(v) <= 1/2 * pi` |

### A limit of a logarithm that is not decided is left unevaluated

**Not silent: what overflowed the stack now returns.** A limit of a logarithm whose argument has no limit, as
`ln(2 + sin(x))` at `+oo`, overflowed the stack and took the process down. A limit node simplifies its expression evaluated,
where `ln(f)` is `log(2.718..., f)`, and that base was not read as `e`: the quotient `ln(f) / ln(2.718...)` it was rewritten
as asked the limit of `ln(f)` again, through a limit node of its own
([#2273](https://github.com/asc-community/AngouriMath/issues/2273)).

| Input | Was (2.6.0) | Now |
|---|---|---|
| `"limit(ln(2 + sin(x)), x, +oo)".ToEntity().Simplify()` | stack overflow | `limit(ln(2 + sin(x)), x, +oo)` |
| `"limitright(ln(sin(1/x) + 2), x, 0)".ToEntity().Simplify()` | stack overflow | `limitright(ln(2 + sin(1 / x)), x, 0)` |

### Primality is decided by Miller–Rabin and Lucas–Lehmer, and finishes

**Silent: a membership in `PP` left open past the machine word is decided where a test proves it, and one that did
Expand Down
3 changes: 3 additions & 0 deletions Sources/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed
[Tests/UnitTests/Calculus/LimitsTheIssueListedTest.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/Calculus/UndecidedLogarithmLimitTest.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/Calculus/PowerSubstitutionIntegralTest.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
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,21 @@ internal static partial class LimitFunctional

[System.ThreadStatic] private static int bothSidesDepth;

/// <summary>
/// A logarithm to a base other than e as a quotient of natural logarithms.
/// </summary>
/// <remarks>
/// A base that is e evaluated is e. The limit of a limit node's evaluation is taken of its
/// expression evaluated, in which ln(f) is log(2.718..., f), and as a quotient that is
/// ln(f) / ln(2.718...), whose first remarkable limit asks the limit of ln(f) through a
/// limit node of its own -- which is evaluated, and so asks the same question again. Where
/// the limit of ln(f) is not decided, that did not end, and the stack overflowed.
/// <a href="https://github.com/asc-community/AngouriMath/issues/2273">#2273</a>
/// </remarks>
private static Entity ExpandLogarithm(Entity expr)
=> expr switch
{
Logf(var @base, var antilog) when @base == MathS.e.Evaled => MathS.Ln(antilog),
Logf(var @base, var antilog) when @base != MathS.e => MathS.Ln(antilog) / MathS.Ln(@base),
_ => expr
};
Expand Down
43 changes: 43 additions & 0 deletions Sources/Tests/UnitTests/Calculus/UndecidedLogarithmLimitTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// Copyright (c) 2019-2026 Angouri.
// AngouriMath is licensed under MIT.
// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.
// Website: https://am.angouri.org.
//

using AngouriMath.Extensions;
using Xunit;

namespace AngouriMath.Tests.Calculus
{
/// <summary>
/// A limit of a logarithm that is not decided is left unevaluated, where it overflowed the stack. A limit node simplifies
/// its expression evaluated, in which ln(f) is log(2.718..., f), the base was not read as e, and the quotient
/// ln(f) / ln(2.718...) it was rewritten as asked the limit of ln(f) again through a limit node of its own. None of these
/// has a limit, as the argument oscillates, so NaN would be right as well.
/// <a href="https://github.com/asc-community/AngouriMath/issues/2273">#2273</a>
/// </summary>
[Trait("Area", "Calculus")]
public sealed class UndecidedLogarithmLimitTest
{
[Theory]
[InlineData("limitright(ln(sin(1/x) + 2), x, 0)")]
[InlineData("limit(ln(sin(1/x) + 2), x, 0)")]
[InlineData("limitleft(ln(2 + cos(1/x)), x, 0)")]
[InlineData("limit(ln(2 + sin(x)), x, +oo)")]
[InlineData("limit(sqrt(x) * ln(2 + sin(1/x)), x, 0)")]
public void ItIsLeftUnevaluated(string limit)
{
var answer = limit.ToEntity().Simplify();
Assert.True(answer is Entity.Limitf || answer == MathS.NaN, $"{limit} is {answer}");
}

/// <summary>A logarithm whose limit is decided is answered as before.</summary>
[Theory]
[InlineData("limit(ln(x) / ln(2), x, 4)", "2")]
[InlineData("limit(ln(1 + x) / x, x, 0)", "1")]
[InlineData("limitright(ln(x) * x, x, 0)", "0")]
public void ADecidedOneIsAnswered(string limit, string value)
=> Assert.Equal(value.ToEntity(), limit.ToEntity().Simplify());
}
}
Loading