-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: Add more granular Interfaces to System.INumber<T> #65807
Comments
Tagging subscribers to this area: @dotnet/area-system-numerics Issue DetailsBackground and motivationSystem.INumber implements all binary Operators<T,T,T> with the same Type. In fitting your new C#11 APIs to this Design I have found the Need for at least these two new Interfaces:
API Proposalnamespace System
{
/// <summary> General 'Number' without total Order, including <see cref="Complex"/>, <see cref="Quaternion"/> etc. </summary>
public interface INumber<TSelf, That> :
IAdditionOperators<TSelf, That, That>,
IAdditiveIdentity<TSelf, That>,
ISubtractionOperators<TSelf, That, That>,
IDecrementOperators<TSelf>,
IIncrementOperators<TSelf>,
IMultiplicativeIdentity<TSelf, That>,
IMultiplyOperators<TSelf, That, That>,
IDivisionOperators<TSelf, That, That>,
IModulusOperators<TSelf, That, That>,
ISpanFormattable,
ISpanParseable<TSelf>,
IUnaryNegationOperators<TSelf, That>,
IUnaryPlusOperators<TSelf, That>
where TSelf : INumber<TSelf, That>
{
static abstract TSelf One { get; }
static abstract TSelf Zero { get; }
static abstract TSelf Create<TOther>(TOther value) where TOther : INumber<TOther>;
static abstract bool TryCreate<TOther>(TOther value, out TSelf result) where TOther : INumber<TOther>;
static abstract (TSelf Quotient, TSelf Remainder) DivRem(TSelf left, TSelf right);
static abstract TSelf Parse(string s, NumberStyles style, IFormatProvider? provider);
static abstract TSelf Parse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider);
static abstract bool TryParse([NotNullWhen(true)] string? s, NumberStyles style, IFormatProvider? provider, out TSelf result);
static abstract bool TryParse(
ReadOnlySpan<char> s,
NumberStyles style,
IFormatProvider? provider,
out TSelf result);
}
/// <summary> Number with total Order => Min, Max and Sign are defined </summary>
public interface IScalarNumber<TSelf, That> : INumber<TSelf, That>, IComparisonOperators<TSelf, That>
where TSelf : IScalarNumber<TSelf, That>
{
static abstract TSelf Max(TSelf x, TSelf y);
static abstract TSelf Min(TSelf x, TSelf y);
static abstract TSelf Abs(TSelf value);
static abstract TSelf Sign(TSelf value);
static abstract TSelf Clamp(TSelf value, TSelf min, TSelf max);
static abstract TSelf CreateSaturating<TOther>(TOther value) where TOther : INumber<TOther>;
static abstract TSelf CreateTruncating<TOther>(TOther value) where TOther : INumber<TOther>;
}
/// <summary> Existing INumber{T} can be defined in these Terms without any Changes: </summary>
public interface INumber<TSelf> : IScalarNumber<TSelf, TSelf> { }
} API UsageUsage would be unchanged, but Developers would be able to define generic Algorithms e.g. for Complex and Quaternion.
public struct Complex : INumber<Complex,Complex> { ... }
public struct Quaternion : INumber<Quaternion,Quaternion> { ... } Alternative DesignsI would propose an even more granular Design that involves additive and multiplicative Semi-Groups, Groups, Rings and Fields to align closer with long-standing mathematical Models, but that may be harder to communicate. RisksNone, the API is in Preview and this Design is inspired from a long History of Math Library Development.
|
Thanks for your interest in this space, the current design is being covered in the
The current design is explicitly not looking at or considering groups/rings/fields/etc. There are a lot of expectations around these terms and many of the real-world use cases don't work well with them as the contract required becomes too strict and doesn't integrate well with a variety of languages. The terms themselves, while making sense from a mathematical perspective, are also highly conflicting in the more general programming space. Instead, the design is targeting a set of interfaces and definitions that map well to .NET, the broader framework design guidelines, and considering scenarios around common programming patterns encountered in languages like C#, F#, and other languages where it is expected to be used.
The proposed update will be splitting the current Notably, there are some practical problems that come about from trying to represent When considering single operations (like However, when considering more complex scenarios, like |
Thank you for this Info. I wasn't aware of the discussions. |
Background and motivation
I have developed extensive Math Libraries for the last 30 years in Java, C++ and C# and I am very happy about your native Types to implement the common Interfaces of
System.INumber< T>
.Unfortunately it implements all binary
XxxOperators< T,T,T>
with the same Type.I have found it useful in my work to define many intermediate Interfaces that model mathematical Semi-Groups, Groups, Rings, Fields and ultimately Scalar Numbers, i.e.
INumber< T>
.In fitting your new C#11 APIs to my Designs I have found the Need for at least these two new, intermediate Interfaces:
INumber<TSelf, TResult>
andIScalarNumber<TSelf, TResult>
This also results in a simpler Definition of
INumber< T>
and the opportunity to apply these Interfaces to Complex and Quaternion for many Algorithms (e.g. linear Algebra):The lesser specialized
TResult
Type allows to return the 'smallest' Type and keep Operations efficient.You could e.g. subtract two Complex Numbers with same imaginary Components and return a double instead of another Complex Number with 0 imaginary Component.
I would like to start a Pull-Request with the Definition. In Fact I have already implement them e.g. in
System.Numerics.Complex
and inSystem.Numerics.Quaternion
as displayed below.API Proposal
API Usage
Existing API would be unchanged, but Developers would be able to define generic Algorithms e.g. for Complex and Quaternion.
I have actually working Implementations of Complex and Quaternion Numbers based on this Design.
Alternative Designs
I would propose an even more granular Design that involves additive and multiplicative Semi-Groups, Groups, Rings and Fields to align closer with long-standing mathematical Models, if you are ready to consider this.
This would greatly increase the usefulness for Library Developers, because they have fewer Methods to implement and a more granular Framework to embed their Designs.
It does not the affect long-term Evolvability, because these are stable and proven mathematical Structures.
Risks
None, the API is in Preview and this Design is inspired from a long History of Math Library Development.
The text was updated successfully, but these errors were encountered: