Is there any feasible way of using generics to create a Math library that does not depend on the base type chosen to store data?
In other words, let's assume I want to write a Fraction class. The fraction can be represented by two ints or two doubles or whatnot. The important thing is that the basic four arithmetic operations are well defined. So, I would like to be able to write Fraction<int> frac = new Fraction<int>(1,2) and/or Fraction<double> frac = new Fraction<double>(0.1, 1.0).
Unfortunately there is no interface representing the four basic operations (+,-,*,/). Has anybody found a workable, feasible way of implementing this?
Here is a way to abstract out the operators that is relatively painless.
abstract class MathProvider<T>
{
public abstract T Divide(T a, T b);
public abstract T Multiply(T a, T b);
public abstract T Add(T a, T b);
public abstract T Negate(T a);
public virtual T Subtract(T a, T b)
{
return Add(a, Negate(b));
}
}
class DoubleMathProvider : MathProvider<double>
{
public override double Divide(double a, double b)
{
return a / b;
}
public override double Multiply(double a, double b)
{
return a * b;
}
public override double Add(double a, double b)
{
return a + b;
}
public override double Negate(double a)
{
return -a;
}
}
class IntMathProvider : MathProvider<int>
{
public override int Divide(int a, int b)
{
return a / b;
}
public override int Multiply(int a, int b)
{
return a * b;
}
public override int Add(int a, int b)
{
return a + b;
}
public override int Negate(int a)
{
return -a;
}
}
class Fraction<T>
{
static MathProvider<T> _math;
// Notice this is a type constructor. It gets run the first time a
// variable of a specific type is declared for use.
// Having _math static reduces overhead.
static Fraction()
{
// This part of the code might be cleaner by once
// using reflection and finding all the implementors of
// MathProvider and assigning the instance by the one that
// matches T.
if (typeof(T) == typeof(double))
_math = new DoubleMathProvider() as MathProvider<T>;
else if (typeof(T) == typeof(int))
_math = new IntMathProvider() as MathProvider<T>;
// ... assign other options here.
if (_math == null)
throw new InvalidOperationException(
"Type " + typeof(T).ToString() + " is not supported by Fraction.");
}
// Immutable impementations are better.
public T Numerator { get; private set; }
public T Denominator { get; private set; }
public Fraction(T numerator, T denominator)
{
// We would want this to be reduced to simpilest terms.
// For that we would need GCD, abs, and remainder operations
// defined for each math provider.
Numerator = numerator;
Denominator = denominator;
}
public static Fraction<T> operator +(Fraction<T> a, Fraction<T> b)
{
return new Fraction<T>(
_math.Add(
_math.Multiply(a.Numerator, b.Denominator),
_math.Multiply(b.Numerator, a.Denominator)),
_math.Multiply(a.Denominator, b.Denominator));
}
public static Fraction<T> operator -(Fraction<T> a, Fraction<T> b)
{
return new Fraction<T>(
_math.Subtract(
_math.Multiply(a.Numerator, b.Denominator),
_math.Multiply(b.Numerator, a.Denominator)),
_math.Multiply(a.Denominator, b.Denominator));
}
public static Fraction<T> operator /(Fraction<T> a, Fraction<T> b)
{
return new Fraction<T>(
_math.Multiply(a.Numerator, b.Denominator),
_math.Multiply(a.Denominator, b.Numerator));
}
// ... other operators would follow.
}
If you fail to implement a type that you use, you will get a failure at runtime instead of at compile time (that is bad). The definition of the MathProvider<T> implementations is always going to be the same (also bad). I would suggest that you just avoid doing this in C# and use F# or some other language better suited to this level of abstraction.
Edit: Fixed definitions of add and subtract for Fraction<T>.
Another interesting and simple thing to do is implement a MathProvider that operates on an abstract syntax tree. This idea immediately points to doing things like automatic differentiation: http://conal.net/papers/beautiful-differentiation/
I believe this answers your question:
http://www.codeproject.com/KB/cs/genericnumerics.aspx
Here's a subtle problem that comes with generic types. Suppose an algorithm involves division, say Gaussian elimination to solve a system of equations. If you pass in integers, you'll get a wrong answer because you'll carry out integer division. But if you pass in double arguments that happen have integer values, you'll get the right answer.
The same thing happens with square roots, as in Cholesky factorization. Factoring an integer matrix will go wrong, whereas factoring a matrix of doubles that happen to have integer values will be fine.
First, your class should limit the generic parameter to primitives ( public class Fraction where T : struct, new() ).
Second, you'll probably need to create implicit cast overloads so you can handle casting from one type to another without the compiler crying.
Third, you can overload the four basic operators as well to make the interface more flexible when combining fractions of different types.
Lastly, you have to consider how you are handling arithmetic over and underflows. A good library is going to be extremely explicit in how it handles overflows; otherwise you cannot trust the outcome of operations of different fraction types.
The other approaches here will work, but they have a high performance impact over raw operators. I figured I would post this here for someone who needs the fastest, not the prettiest approach.
If you want to do generic math without paying a performance penalty, then this is, unfortunately, the way to do it:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T IncrementToMax(T value)
{
if (typeof(T) == typeof(char))
return (char)(object)value! < char.MaxValue ? (T)(object)(char)((char)(object)value + 1) : value;
if (typeof(T) == typeof(byte))
return (byte)(object)value! < byte.MaxValue ? (T)(object)(byte)((byte)(object)value + 1) : value;
// ...rest of the types
}
It looks horrific, I know, but using this method will produce code that runs as fast as possible. The JIT will optimize out all the casts and conditional branches.
You can read the explanation and some additional important details here: http://www.singulink.com/codeindex/post/generic-math-at-raw-operator-speed
.NET 7 introduces a new feature - generic math (read more here and here) which is based on addition of static abstract interface methods. This feature introduces a lot of interfaces which allow to generically abstract over number types and/or math operations:
class Fraction<T> :
IAdditionOperators<Fraction<T>, Fraction<T>, Fraction<T>>,
ISubtractionOperators<Fraction<T>, Fraction<T>, Fraction<T>>,
IDivisionOperators<Fraction<T>, Fraction<T>, Fraction<T>>
where T : INumber<T>
{
public T Numerator { get; }
public T Denominator { get; }
public Fraction(T numerator, T denominator)
{
Numerator = numerator;
Denominator = denominator;
}
public static Fraction<T> operator +(Fraction<T> left, Fraction<T> right) =>
new(left.Numerator * right.Denominator + right.Numerator * left.Denominator,
left.Denominator * right.Denominator);
public static Fraction<T> operator -(Fraction<T> left, Fraction<T> right) =>
new(left.Numerator * right.Denominator - right.Numerator * left.Denominator,
left.Denominator * right.Denominator);
public static Fraction<T> operator /(Fraction<T> left, Fraction<T> right) =>
new(left.Numerator * right.Denominator, left.Denominator * right.Numerator);
}
Related
I had a brilliant thought, that does not seem to be so brilliant afterwards, but maybe I don't understand the whole thing correctly.
I have a class, that stores some numbers. Some other functions/methods need int's and some need double's. So I thought I can create a class with a precision conversion implicitly.
public class PreciseInteger
{
public double PreciseValue {get; private set;}
public int RoundedValue {get; private set;}
public PreciseInteger(double value)
{
PreciseValue = value;
RoundedValue = (int)Math.Round(value, 0, MidpointRounding.AwayFromZero);
}
public static implicit operator PreciseInteger(int number)
{
return new PreciseInteger(number);
}
public static implicit operator PreciseInteger(double number)
{
return new PreciseInteger(number);
}
public static implicit operator int(PreciseInteger number)
{
return number.RoundedValue;
}
public static implicit operator double(PreciseInteger number)
{
return number.PreciseValue;
}
public override string ToString()
{
return PreciseValue.ToString();
}
}
And the class that uses this class is really a simple property storing class that does not much. So now I use somthing like
double myValue = myClass.StoredValue1 / myDivider;
But here I only get the integer value. I don't want to use an explicit casting (like Convert.ToDouble or (double)). So how could I make sure that the precise value is used and not the rounded one? Or did I misunderstand the whole concept and that doesn't work at all and I would have to use something like MyClass.MyDouble and MyClass.MyInteger values?
Edit: Ok, if I first say int newInt = myClass.StoredValue1 I get a rounded integer and if I use double newDouble = myClass.StoredValue1 I get the precise floating point number. But isn't there a way to say that one of them is always preferred?
The / operator is defined for both int and double:
double operator /(double x, double y);
int operator /(int x, int y);
These two overloads are both applicable when you do:
// assuming myClass.StoredValue1 and myDivider are PreciseIntegers
double myValue = myClass.StoredValue1 / myDivider;
because you defined an implicit conversion to int and an implicit conversion to double. However, the / that takes ints is actually a better function member, because int is a better conversion target, so the compiler always chooses the second overload.
One way to work around this is to define your own / operator for PreciseInteger:
public static PreciseInteger operator /(PreciseInteger number1, PreciseInteger number2) {
return number1.PreciseValue / number2.PreciseValue;
}
Then you can do:
double myValue = myClass.StoredValue1 / myDivider;
This question already has answers here:
Is there a C# generic constraint for "real number" types? [duplicate]
(8 answers)
Closed 9 years ago.
I'm trying to make structure that represent four-dimensional vector.
I made something like this:
struct Vector4D<T>
{
public T v1;
public T v2;
public T v3;
public T v4;
//...
public static Vector4D<T> operator *(Vector4D<T> a, T b)
{
a.v1 *= b;
a.v2 *= b;
a.v3 *= b;
a.v4 *= b;
return a;
}
}
Well, this structure dosen't make sense if T isn't any numeric type like Int32, Int64, Double, Single, Decimal etc...
So, my question is how can I constrain T to be only one of following types, Int16, Int32, Int64, UInt16, UInt32, UInt64, Byte, SByte, Single, Double, Decimal?
I was trying do something like this
struct Vector4D<T> where T : Int16, Int32, Int64 // and so go on
{
//....
}
But it didn't work.
You do have to explicitly write a multiply method for each type.
However, you can simplify things a bit as this compilable code sample shows:
using System;
namespace Demo
{
internal class Program
{
static void Main()
{
var d = new Vector4D<double>{v1=1, v2=2, v3=3, v4=4};
Console.WriteLine(d*2); // Prints 2, 4, 6, 8
var i = new Vector4D<int>{v1=1, v2=2, v3=3, v4=4};
Console.WriteLine(i*2); // Prints 2, 4, 6, 8
// This will throw a "NotSupported" exception:
var s = new Vector4D<string>{v1="1", v2="2", v3="3", v4="4"};
Console.WriteLine(s*"");
}
}
partial struct Vector4D<T>
{
public T v1;
public T v2;
public T v3;
public T v4;
public static Vector4D<T> operator *(Vector4D<T> a, T b)
{
a.v1 = multiply(a.v1, b);
a.v2 = multiply(a.v2, b);
a.v3 = multiply(a.v3, b);
a.v4 = multiply(a.v4, b);
return a;
}
public override string ToString()
{
return string.Format("v1: {0}, v2: {1}, v3: {2}, v4: {3}", v1, v2, v3, v4);
}
private static Func<T, T, T> multiply;
}
// Partial just to keep this logic separate.
partial struct Vector4D<T>
{
static Vector4D() // Called only once for each T.
{
if (typeof(T) == typeof(int))
Vector4D<int>.multiply = (a, b) => a*b;
else if (typeof(T) == typeof(double))
Vector4D<double>.multiply = (a, b) => a*b;
else if (typeof(T) == typeof(float))
Vector4D<float>.multiply = (a, b) => a*b;
else
multiply = (a, b) =>
{
string message = string.Format("Vector4D<{0}> not supported.", typeof(T));
throw new NotSupportedException(message);
};
}
}
}
That way, you can put all the multiply (and presumably divide, add and subtract) logic into the second partial struct and keep it all separate from the main logic.
The second partial struct only contains a static type constructor which will be called once only (per assembly domain) for each type T which is used to create a struct.
You do have the overhead of querying the type, but it is only once per run of the program and I guess the overhead would be pretty low.
Also, you don't have to use a partial struct at all - you can just put the static type constructor with the rest of the struct implementation. I only separated it out as an example, because it is purely initialisation logic which you could consider separately from the rest of the struct's logic.
Important Note that if you use the Vector4D with a type for which you haven't defined a multiply operation, you'll get the NotSupportedException defined in static Vector4D(). This does at least tell you exactly what is wrong, along the lines of:
Unhandled Exception: System.NotSupportedException: Vector4D<System.String> not supported.
You cannot do this, not this way.
C# does not know anyhting about generic type T. Is it a number? Is it a string? Can you do math with it?
If you want to get this working, you have to use a generic calculator. You must build it yourself. For more info, take a look at: http://www.codeproject.com/Articles/8531/Using-generics-for-calculations
A simpler solution could be:
a.v1 = Convert.ChangeType(Convert.ToDecimal(a.v1) * Convert.ToDecimal(b), typeof(T));
EDIT
I created a few library functions on another location. You can use this to implement in your own code. Calculating with these numbers would be easy. Your Vector-class would be:
partial struct Vector4D<T>
where T: IComparable<T>, IEquatable<T>
{
public Number<T> v1;
public Number<T> v2;
public Number<T> v3;
public Number<T> v4;
public static Vector4D<T> operator *(Vector4D<T> a, T b)
{
a.v1 *= b;
a.v2 *= b;
a.v3 *= b;
a.v4 *= b;
return a;
}
}
See: https://codereview.stackexchange.com/questions/26022/improvement-requested-for-generic-calculator-and-generic-number
public class Faranheit
{
public float Digree { get; set; }
public Faranheit(float f)
{
Digree = f;
}
public static implicit operator Celcius(Faranheit f)
{
return new Celcius((5.0f / 9.0f) * (f.Digree - 32));
}
public static implicit operator Faranheit(Celcius c)
{
return new Faranheit((9.0f / 5.0f) * c.Digree + 32);
}
}
public class Celcius
{
public float Digree{get;set;}
public Celcius(float c)
{
Digree = c;
}
}
I am just confused, where to put the conversion methods exactly..
It works fine even if I put one method in one class and other in the other, or I interchange them or even if I put both of them in any of the two classes..
But if I put it outside these two classes it doesn't work (compile error)..
Could please someone put some light on this..
EDIT:
if it allows the conversion methods to be in either of the class, why doesn't it allow the conversion method to be in a separate class??
All that matters is that the implicit conversion exists in one of the two classes. I would tend to put both conversions in the less-commonly used class.
In this case, the classes look equal, so I would put the conversion to the class in each class i.e. the conversion from F to C would go in the Celsius class, and vice versa.
Really, it's mostly about personal preference.
In this specific case, I would write a Temperature class that lets you get the temperature in C, F, K, R, etc. But that isn't exactly relevant to the actual question.
I would put them in each of the classes. So you can do stuff like:
Celsius c = new Celsius(Value);
Fahrenheit f = c.toFahrenheit();
Celsius newC = f.toCelsius();
edit: or if you wanted to go the Helper class route, you could do:
public static class ConvertTemps
{
public static Celsius toCelsius(Fahrenheit F)
{
return new Celsius(5/8* F - 32);
}
public static Fahrenheit toFahrenheit(Celsius C)
{
return new Fahrenheit(8/5*C + 32);
}
}
and then you could do things like:
Celsius c = new Celsius(value);
Fahrenheit f = ConvertTemps.toFahrenheit(c);
But I'd go the first route.
Is it possible to template methods for any kind of integer size ?
To illustrate, imagine this very trivial example (the body of the method is not important in my question):
public int Mul(int a, int b) {
return a*b;
}
Now, I want the same method that supports any kind of integer (excluding BigInteger of course). I have to write all variants :
public long Mul(long a, long b) {
return a*b;
}
public ulong Mul(ulong a, ulong b) {
return a*b;
}
public short Mul(short a, short b) {
return a*b;
}
public ushort Mul(ushort a, ushort b) {
return a*b;
}
public byte Mul(byte a, byte b) {
return a*b;
}
While this example is very trivial and it's not actually a problem to duplicate, if I have more complex algorithms like this (replicate for all integer kinds):
public static IEnumerable<long> GetPrimesFactors(this long number)
{
for (long i = 2; i <= number / 2; i++)
{
while (number % i == 0)
{
yield return i;
number /= i;
}
}
yield return number;
}
it introduces a maintenance risk as there is duplicated code and logic (coding integrists would say this is the evil to have same logic at multiple place).
Some of you may suggest to implements the long version and cast the result, but having to ask consumer code to cast can be confusing and reduce readability :
void SomeMethod(IEnumerable<int> valuesToProcess)
{
foreach(int value in valuesToProcess) { Console.WriteLine(value); }
}
void Main()
{
int i = 42;
SomeMethod(((long)i).GetPrimesFactors().Select(l=>(int)l));
SomeMethod(GetPrimesFactors(i));
long l = 42L;
SomeMethod(l.GetPrimesFactors().Select(l=>(int)l));
}
When I see the definition of the interface IEnumerable<T>, and especially the definitions of Sum method overloads :
public static decimal? Sum(this IEnumerable<decimal?> source);
public static decimal Sum(this IEnumerable<decimal> source);
public static double? Sum(this IEnumerable<double?> source);
public static double Sum(this IEnumerable<double> source);
public static float? Sum(this IEnumerable<float?> source);
public static float Sum(this IEnumerable<float> source);
public static int? Sum(this IEnumerable<int?> source);
public static int Sum(this IEnumerable<int> source);
public static long? Sum(this IEnumerable<long?> source);
public static long Sum(this IEnumerable<long> source);
I conclude that it's not possible... that's why MS has to implement all overloads.
Does anyone have any tips for designing general purpose integer methods without having to duplicate logic ?
There is no clean high performance solution. The choices I can think of are:
Manually duplicate the code (fast and redundant)
Automatically duplicate the code with a code generator (fast but a bit ugly). One .net numerics library went that way, but I don't remember its name.
Use some form of indirection, such as MiscUtil's Operator class, or the DLR (slow)
The arithmetic helper struct. I'm not sure how good the performance is, but you can try.
Generic methods representing operators:
These were my first idea. The issue is how to implement them. MiscUtil does this by calling a delegate stored in a static field.
static Func<T,T,T> _multiply;
public static T Multiply(T n1,T n2)
{
return _multiply(n1, n2);
}
One point to note here, is that you should avoid a static constructor, since its mere existence slows down static field access.
But that involves an indirect call, and that's expensive. I next tried to improve this by manually specializing for certain known types:
public static T Multiply(T n1,T n2)
{
if(typeof(T)==typeof(int))
return (T)(object)((int)(object)n1*(int)(object)n2);
...
return _multiply(n1, n2);
}
The JIT compiler is smart enough to realize which of those if cases it has to take, and will remove them. While that improved performance, it bloated the IL representation of the methods. And the JIT compiler is not smart enough to inline those method now, since their IL representation is long, and the inline heuristic only looks at the IL length of a method, not its machine code length. I don't remember if these casts cause boxing, or if the JITter was smart enough to optimize that out. Still the lack of inlining is too costly.
How 4) works:
First create an interface that contains the basic operations you need(arithmetic operators,...):
interface IArithmetic<T>
{
T Multiply(T n1,T n2);
}
Implement it for each type you need with a struct:
public struct Int32Arithmetic:IArithmetic<Int32>
{
Int32 Multiply(Int32 n1,Int32 n2)
{
return n1*n2;
}
}
Then make most of your actual code generic, and pass in an arithmetic helper:
internal T MyOperation<T,TArithmetic>(T n1, T n2)
where TArithmetic:struct,IArithmetic<T>
{
return default(TArithmetic).Multiply(n1,n2);
}
And if you want a clean interface for multiple types, create a thin overloaded wrapper forwarding to the generic method:
public Int32 MyOperation(Int32 n1,Int32 n2)
{
return MyOperation<Int32,Int32Arithmetic>(n1, n2);
}
This might be fast, because generics get specialized for each value type. It uses no indirections and the method bodies in IL don't get too long, so inlining is possible. But I haven't tried this myself yet.
Consider the DLR:
static void Main(string[] args)
{
int i = Mul(2, 4);
Console.WriteLine(i);
Console.Read();
}
static dynamic Mul(dynamic x, dynamic y)
{
return x * y;
}
Performance is to be determined (I'd expect it to be slower than straight overloads), but readability is much nicer. Could get a little hairy if you provide types that don't implement the required operators or different types that cause values to truncate.
Updated from comment:
If performance is so critical, then it sounds like you have already chosen the trade-off between duplicating/readability and the performance you seek. Code-gen it and move on. Any maintenance issues from a few pieces of extra code are likely dwarfed by the maintenance of the performance itself.
Well, what you could do is generate the duplicated code during your build process using, for example, T4.
public T Mul<T>(T a, T b){
dynamic x = a;
dynamic y = b;
return (T)x*y;
}
I once tried so implement something similar using CodeDom to generate an assembly during runtime and dynamically load it. This works rather well, but has some limitations. For example, your environment might not allow you to dynamically compile assemblies and there is the big one: performance. Although the "calculator"-class is only generated once, the overhead of calling a virtual method actually doubles the time necessary for the calculation.
You could give it a try to see how it would perform in your environment, I just lay out the classes (since this was a long time ago and I don't have the code anymore).
interface ICalculator<T> {
T Add(T left, T right);
T Multiply(T left, T right);
}
internal static class Calculator<T> {
static ICalculator<T> instance;
static Calculator() {
Type type = typeof(T);
// 1. Use CodeDom to design a class that implements ICalculator<T> using the
// builtin +,-,*,/ operators
// 2. Compile assembly in memory
// 3. Load assembly and create an instance of the ICalculator<T> class
Type concreteType = GetTypeFromDynamicAssembly(); // Get this from the assembly.
instance = Activator.CreateInstance(concreteType) as ICalculator<T>;
}
public static T Add(T left, T right) {
return instance.Add(left, right);
}
}
class MyClassUsingGenericMathType<T> {
T Sum(params T[] values) {
T sum = default(T);
foreach (T value in values) {
sum = Calculator<T>.Add(sum, value);
}
return sum;
}
}
The idea is that you dynamically built the implementation first time it is used (the static constructor is invoked then), after that the Calculator methods directly call the corresponding operator of the numeric type you are using. As I said, I remember that this adds an overhead everytime an operation is performed, but I never analyzed whether there is a potential for speeding up the process using some Compiler-attributes.
Another thing: using a type that doesn't implement the corresponding operators would cause a runtime-exception rather than a compile error. So it's far from perfect.
If I have a method for calculating the greatest common divisor of two integers as:
public static int GCD(int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
What would be the best way to attach that to the System.Math class?
Here are the three ways I have come up with:
public static int GCD(this int a, int b)
{
return b == 0 ? a : b.GCD(a % b);
}
// Lame...
var gcd = a.GCD(b);
and:
public static class RationalMath
{
public static int GCD(int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
}
// Lame...
var gcd = RationalMath.GCD(a, b);
and:
public static int GCD(this Type math, int a, int b)
{
return b == 0 ? a : typeof(Math).GCD(b, a % b);
}
// Neat?
var gcd = typeof(Math).GCD(a, b);
The desired syntax is Math.GCD since that is the standard for all mathematical functions.
Any suggestions? What should I do to get the desired syntax?
You cannot. Extension methods are just syntactic sugar for calling a static function and passing an instance of a particular type. Given that, they operate only on instances, as they must be defined by passing a this parameter of the type you want to attach to.
I would prefer the one with RationalMath. You really don't need extension methods here, because their aim is to mimic instance methods of objects of you can't modify. But here one should use plain old static method.
Given the fact that you cannot extend the static Math class I would go for sample #2. It follows the pattern used by Math, does not clutter the int method space, and is simple and clean to invoke. #3 is plain horrible :)
Personally, I wouldn't do it the way you want. System.Math is just one static class that contains some mathematical functions . . . there's no reason it has to contain every mathematical function you'd ever want to use.
However, if you really want this, I suppose you could write your own static Math class that's a sort of wrapper for System.Math . . . basically just implement every function in System.Math by passing it along to the actual System.Math class. Like this:
public static class Math
{
public static int GCD(int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
// Implement the System.Math methods
public static double Pow(double x, double y)
{
return System.Math.Pow(x, y);
}
// etc.
}
This seems like a real pain in the neck though for not much benefit. (Kind of an anti-syntactic sugar.) But it would let you call Math.GCD(a,b) and, say, Math.Pow(x,y) from the same class, which is what it sounds like you want.
Ok, one other way I thought of:
namespace My
{
public static class Math
{
}
}
namespace MainApp
{
...
var gcd = My.Math.GCD(a, b);
...
}