Search code examples
c#genericsmiscutils

Generic Sqrt Implementation


I'm using the MiscUtils library (thanks Marc G. and Jon S.) and am trying to add a generic Sqrt function to it. The problem can be easily reproduced with this:

class N<T>
{
    public N(T value)
    {
        Value = value;
    }

    public readonly T Value;

    public static implicit operator T(N<T> n)
    {
        return n.Value;
    }

    public static implicit operator N<T>(T value)
    {
        return new N<T>(value);
    }

    public static T operator /(N<T> lhs, T rhs)
    {
        // Operator.Divide is essentially a wrapper around 
        // System.Linq.Expressions.Expression.Divide
        return Operator.Divide(lhs.Value, rhs);
    }
}

// fails with: No coercion operator is defined 
// between types 'System.Double' and 'N`1[System.Single]'.
var n = new Numeric<float>(1f);
var x = Operator.DivideAlternative(n, 1.0);

// this works as the N<T> is first converted to a 
// float via the implicit conversion operator 
var result = n / 1.0;

Now, I realize why this is happening, but I have not yet been able to think of a way around it. For reference, here is the current Sqrt implementation. I have little experience building expression trees.

public static double Sqrt<T>(T value)
{
    double oldGuess = -1;
    double guess = 1;
    while(Abs(guess - oldGuess) > 1)
    {
        oldGuess = guess;
        // the first evaluated call to DivideAlternative throws
        guess = Operator.Divide(
                    Operator.AddAlternative(guess, 
                        Operator.DivideAlternative(value, guess)),
                    2);
    }

    return guess;
}

EDIT: Ok, so I solved this on my own, but in an attempt to keep the question as simple as possible I apparently went too far and spent far too much time answering questions from confused people trying to help.

So, this is the problem in its entirety.

I two classes; one that performs transformations and another which performs statistical analysis of image data (pixels). Let's focus on the latter as the problem is the same:

abstract class ImageStatistics
{
    private readonly object _pixels;

    public ImageStatistics(object pixelArray)
    {
        Pixels = pixelArray;
    }

    // calculate the standard deviation of pixel values
    public double CalcStdDev();
}

The array of pixels can be any numeric type. In practice, it will be either float, int, ushort, or byte. Now, because generics cannot do things like this:

public T Add<T>(T lhs, T rhs)
{
    return lhs + rhs;  // oops, no operator + for T
}

I cannot perform any sort of statistical analyses on the pixel values themselves without casting to the proper array type. So, I need to have N sub-classes of ImageProcessor to support N pixel types.

Well, that sucks. I would love to just have a generic ImageProcessor<T> class which has a T[] of pixel data. So, I looked into the MiscUtils library which would allow just this.


Solution

  • This question was asked 10 years ago; since then, .NET has solved this problem: https://devblogs.microsoft.com/dotnet/dotnet-7-generic-math/

    Example:

    class N<T> where T: IRootFunctions<T> // interface provided by .NET
    {
        public required T Value { get; init; }
    
        public void DoWork()
        {
            var result = T.Sqrt(Value); // Sqrt is available on T
            Console.WriteLine(result);
        }
    }
    
    var myN = new N<float>() { Value = 10 };
    myN.DoWork(); // prints 3.1622777
    
    var myN2 = new N<double>() { Value = 10 };
    myN2.DoWork(); // prints 3.1622776601683795
    

    Note that int and decimal do not implement IRootFunctions<T>. (Maybe in a future release of .NET...)