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
47 changes: 40 additions & 7 deletions Sources/AngouriMath/Convenience/MathS.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//
//
// Copyright (c) 2019-2022 Angouri.
// AngouriMath is licensed under MIT.
// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.
Expand Down Expand Up @@ -3760,9 +3760,9 @@ public static ParsingResult Parse(string source)
/// Console.WriteLine(ToBaseN(13.125m, 2));
/// Console.WriteLine(ToBaseN(13.125m, 10));
///
/// // uncomment when https://github.com/asc-community/AngouriMath/issues/584
/// // is fixed
/// // Console.WriteLine(ToBaseN(13.125m, 5));
/// // A repeating expansion is cut off at the configured decimal precision
/// // instead of hanging; see https://github.com/asc-community/AngouriMath/issues/584.
/// Console.WriteLine(ToBaseN(13.125m, 5).Substring(0, 12) + "...");
///
/// Console.WriteLine(ToBaseN(13.125m, 8));
/// Console.WriteLine("-----------------------");
Expand All @@ -3778,6 +3778,7 @@ public static ParsingResult Parse(string source)
/// 11.11
/// 1101.001
/// 13.125
/// 23.030303030...
/// 15.1
/// -----------------------
/// 255
Expand Down Expand Up @@ -3806,9 +3807,9 @@ public static ParsingResult Parse(string source)
/// Console.WriteLine(ToBaseN(13.125m, 2));
/// Console.WriteLine(ToBaseN(13.125m, 10));
///
/// // uncomment when https://github.com/asc-community/AngouriMath/issues/584
/// // is fixed
/// // Console.WriteLine(ToBaseN(13.125m, 5));
/// // A repeating expansion is cut off at the configured decimal precision
/// // instead of hanging; see issue 584.
/// Console.WriteLine(ToBaseN(13.125m, 5).Substring(0, 12) + "...");
///
/// Console.WriteLine(ToBaseN(13.125m, 8));
/// Console.WriteLine("-----------------------");
Expand All @@ -3824,6 +3825,7 @@ public static ParsingResult Parse(string source)
/// 11.11
/// 1101.001
/// 13.125
/// 23.030303030...
/// 15.1
/// -----------------------
/// 255
Expand Down Expand Up @@ -5464,6 +5466,37 @@ public sealed record NewtonSetting
public static Setting<EDecimal> PrecisionErrorZeroRange => precisionErrorZeroRange ??= EDecimal.Create(1, -16);
[ThreadStatic] private static Setting<EDecimal>? precisionErrorZeroRange;

/// <summary>
/// The tolerance within which downcasting rounds a number onto a nearby integer.
/// </summary>
/// <remarks>
/// This is <see cref="PrecisionErrorZeroRange"/> whenever a caller has set it,
/// but its default of 1e-16 is far too coarse to be applied blindly: numbers are
/// evaluated to <see cref="DecimalPrecisionContext"/> digits, 100 by default, so
/// 1e-16 sits nowhere near the noise floor. Applying it destroyed every legitimate
/// small value -- <c>1e-20</c> parsed to zero and <c>e^(-40)</c> evaluated to zero.
/// Residuals genuinely left over by exact cancellation, such as the one from
/// <c>sin(pi)</c>, land around 1e-99, so half the working digits separates the two
/// cases with room to spare. Never looser than the setting's own default, so that
/// lowering the precision cannot silently widen the tolerance.
/// </remarks>
internal static EDecimal DowncastingTolerance
{
get
{
var configured = PrecisionErrorZeroRange.Value;
if (PrecisionErrorZeroRange.IsOverriden)
return configured;
var precision = DecimalPrecisionContext.Value.Precision;
if (precision.IsZero)
return configured;
// Built from EIntegers throughout: the precision is user-supplied and
// need not fit in an int.
var derived = EDecimal.Create(EInteger.One, precision.Divide(2).Negate());
return derived.LessThan(configured) ? derived : configured;
}
}

/// <summary>
/// If you only need analytical solutions and an empty set if no analytical solutions were found, disable Newton's method
/// </summary>
Expand Down
10 changes: 10 additions & 0 deletions Sources/AngouriMath/Convenience/SettingClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ public TReturnType As<TReturnType>(T value, Func<TReturnType> action)
/// </summary>
public T Default { get; }

/// <summary>
/// Whether anyone has called <see cref="Set"/> on this setting, i.e. whether
/// <see cref="Value"/> is anything other than the value the constructor pushed.
/// Lets a default be treated as "nobody expressed an opinion" rather than as a
/// deliberate choice.
/// </summary>
internal bool IsOverriden => values.Count > 1;

/// <summary>
/// This tiny struct is needed to be under `using` operator, so that your settings
/// are automatically rolled back on the end of your method
Expand Down Expand Up @@ -158,6 +166,8 @@ internal sealed class KeyStack<TKey, TValue>
{
private readonly List<(TKey key, TValue value)> list = new();

internal int Count => list.Count;

internal TValue Peek() => list[^1].value;

internal bool Remove(TKey key)
Expand Down
1 change: 1 addition & 0 deletions Sources/AngouriMath/Core/Antlr/AngouriMath.g
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ atom returns[Entity value]
| '{' cset_args = cset_arguments '}' { $value = new ConditionalSet($cset_args.couple.variable, $cset_args.couple.predicate); }
| '{' args = function_arguments '}' { $value = new FiniteSet((IEnumerable<Entity>)$args.list); }
| 'log(' args = function_arguments ')' { $value = Assert("log", (1, 2), $args.list.Count) ? MathS.Log(10, $args.list[0]) : MathS.Log($args.list[0], $args.list[1]); }
| 'pow(' args = function_arguments ')' { Assert("pow", 2, $args.list.Count); $value = MathS.Pow($args.list[0], $args.list[1]); }
| 'sqrt(' args = function_arguments ')' { Assert("sqrt", 1, $args.list.Count); $value = MathS.Sqrt($args.list[0]); }
| 'cbrt(' args = function_arguments ')' { Assert("cbrt", 1, $args.list.Count); $value = MathS.Cbrt($args.list[0]); }
| 'sqr(' args = function_arguments ')' { Assert("sqr", 1, $args.list.Count); $value = MathS.Sqr($args.list[0]); }
Expand Down
4 changes: 3 additions & 1 deletion Sources/AngouriMath/Core/Antlr/AngouriMath.interp

Large diffs are not rendered by default.

170 changes: 86 additions & 84 deletions Sources/AngouriMath/Core/Antlr/AngouriMath.tokens
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,14 @@ T__116=117
T__117=118
T__118=119
T__119=120
NEWLINE=121
NUMBER=122
SPECIALSET=123
BOOLEAN=124
VARIABLE=125
COMMENT=126
WS=127
T__120=121
NEWLINE=122
NUMBER=123
SPECIALSET=124
BOOLEAN=125
VARIABLE=126
COMMENT=127
WS=128
'!'=1
'^'=2
'-'=3
Expand Down Expand Up @@ -168,80 +169,81 @@ WS=127
'{'=41
'}'=42
'log('=43
'sqrt('=44
'cbrt('=45
'sqr('=46
'ln('=47
'sin('=48
'cos('=49
'tan('=50
'cotan('=51
'cot('=52
'sec('=53
'cosec('=54
'csc('=55
'arcsin('=56
'arccos('=57
'arctan('=58
'arccotan('=59
'arcsec('=60
'arccosec('=61
'arccsc('=62
'acsc('=63
'asin('=64
'acos('=65
'atan('=66
'acotan('=67
'asec('=68
'acosec('=69
'acot('=70
'arccot('=71
'sinh('=72
'sh('=73
'cosh('=74
'ch('=75
'tanh('=76
'th('=77
'cotanh('=78
'coth('=79
'cth('=80
'sech('=81
'sch('=82
'cosech('=83
'csch('=84
'asinh('=85
'arsinh('=86
'arsh('=87
'acosh('=88
'arcosh('=89
'arch('=90
'atanh('=91
'artanh('=92
'arth('=93
'acoth('=94
'arcoth('=95
'acotanh('=96
'arcotanh('=97
'arcth('=98
'asech('=99
'arsech('=100
'arsch('=101
'acosech('=102
'arcosech('=103
'arcsch('=104
'acsch('=105
'gamma('=106
'derivative('=107
'integral('=108
'limit('=109
'limitleft('=110
'limitright('=111
'signum('=112
'sgn('=113
'sign('=114
'abs('=115
'phi('=116
'domain('=117
'piecewise('=118
'apply('=119
'lambda('=120
'pow('=44
'sqrt('=45
'cbrt('=46
'sqr('=47
'ln('=48
'sin('=49
'cos('=50
'tan('=51
'cotan('=52
'cot('=53
'sec('=54
'cosec('=55
'csc('=56
'arcsin('=57
'arccos('=58
'arctan('=59
'arccotan('=60
'arcsec('=61
'arccosec('=62
'arccsc('=63
'acsc('=64
'asin('=65
'acos('=66
'atan('=67
'acotan('=68
'asec('=69
'acosec('=70
'acot('=71
'arccot('=72
'sinh('=73
'sh('=74
'cosh('=75
'ch('=76
'tanh('=77
'th('=78
'cotanh('=79
'coth('=80
'cth('=81
'sech('=82
'sch('=83
'cosech('=84
'csch('=85
'asinh('=86
'arsinh('=87
'arsh('=88
'acosh('=89
'arcosh('=90
'arch('=91
'atanh('=92
'artanh('=93
'arth('=94
'acoth('=95
'arcoth('=96
'acotanh('=97
'arcotanh('=98
'arcth('=99
'asech('=100
'arsech('=101
'arsch('=102
'acosech('=103
'arcosech('=104
'arcsch('=105
'acsch('=106
'gamma('=107
'derivative('=108
'integral('=109
'limit('=110
'limitleft('=111
'limitright('=112
'signum('=113
'sgn('=114
'sign('=115
'abs('=116
'phi('=117
'domain('=118
'piecewise('=119
'apply('=120
'lambda('=121
Loading