2

I have written my own struct for interval arithmetic, to keep it simple let's just say this is a value defined by a lower and an upper bound. Some of you might know be familiar with the type Range, which is quite similar.

I overloaded the whole arithmetic operators like +,-,*,/,<,>, ... . So I suppose I should have something like a generic type (or should be able to implement the rest to make it one).

Now I want to work/calculate with my type. Since I am handling Linear Equation Systems, need stuff like SVD and don't want to newly invent the wheel, I am planning to use existing Math libraries like Math.NET Numerics. But this is what their matrix class says:

/// <summary>
    /// Defines the base class for <c>Matrix</c> classes.
    /// </summary>
    /// <typeparam name="T">Supported data types are <c>double</c>, <c>single</c>, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
    [Serializable]
    public abstract partial class Matrix<T> :
        IFormattable, IEquatable<Matrix<T>>
#if !PORTABLE
        , ICloneable
#endif
        where T : struct, IEquatable<T>, IFormattable

In short: They say only double, single and complex are allowed. So my generic type won't work, even if it implements all the listed interfaces, right?

So: Am I right that I can't use Math.Net Numerics with my type? Do you know other math libraries that would support my type/a generic? Do I really have to write my own implementations?

Thanks in advance!

selmaohneh
  • 553
  • 2
  • 17
  • This is related to earlier questions about publishing your `+`, `-`, `*`, ... capabilities. In C#, you can't. It's a pity. – H H Feb 13 '17 at 09:38
  • @HenkHolterman this isn't about C#. This isn't about operators either - computational algorithms and accelerated math operations depend on harware implementations, or at least specific assumptions. When something as simple as *addition* becomes expensive, you need to use different algorithms or even binary representations – Panagiotis Kanavos Feb 13 '17 at 09:57
  • @selmaohneh what is the result of *addition* between two *ranges*? Or multiplication? Range division? Your *generic* class isn't generic, it's a vector. That's a different field of math entirely. – Panagiotis Kanavos Feb 13 '17 at 10:01
  • @PanagiotisKanavos all operations between 2 intervals and between an interval and an scalar return a new interval. For exmaple [ 2 , 4] + [ 1 , 3] = [ 3, 7 ] – selmaohneh Feb 13 '17 at 10:02
  • 1
    https://en.wikipedia.org/wiki/Interval_arithmetic#Simple_arithmetic – selmaohneh Feb 13 '17 at 10:04
  • @PanagiotisKanavos - this is clearly about a shortcoming of the generic type constraints, I don't see where the hardware comes in. Note that `Complex` is invited to the party. – H H Feb 13 '17 at 10:09
  • I don't want to invite Complex, it can stay at home. Complex can stay undefined. – selmaohneh Feb 13 '17 at 10:10
  • What I meant is that the comment you quoted is an indication of some `switch(typeof(T)) {}` code inside that Numerics library. And that is not open for extension. – H H Feb 13 '17 at 10:25
  • @selmaohneh you are trying to use libraries that deal with single numbers, not intervals or vectors. The interval can be treated as a specialization of vector. – Panagiotis Kanavos Feb 13 '17 at 10:53
  • @HenkHolterman this has nothing to do with constraints, it's about the math. You can't treat a number as a vector or interval. It's the *math algorithms themselvers* that won't work, because they weren't created for such numbers. BTW, complex numbers btw *are* often treated as vectors, or converted to polar coordinates to simplify/speed up algorithms – Panagiotis Kanavos Feb 13 '17 at 10:57
  • @HenkHolterman as for hardware - it matters a lot. Math.NET and similar libraries for data science are built to solve *computational* problems. Speed matters, and the algorithms are implemented to solve specific problems fast. They are *not* symbolic calculation packages. Simple operations are supposed to be *simple*, ie simple CPU instructions. If possible, such operations *are* accelerated using SIMD operations, like those introduce with .NET 4.6. That's why they require simple types instead of allowing generic ones. That job is mor suitable for Mathematica – Panagiotis Kanavos Feb 13 '17 at 11:05
  • I think you should read the question again. – H H Feb 13 '17 at 11:06
  • @HenkHolterman I think the OP should look for libraries that support intervals instead of trying to force unsuitable libraries work with intervals. – Panagiotis Kanavos Feb 13 '17 at 11:08
  • @HenkHolterman also check [Algorithms for efficient matrix multiplication](https://en.wikipedia.org/wiki/Matrix_multiplication#Algorithms_for_efficient_matrix_multiplication). Libraries like Math.NET don't use the brute force algorithms when possible, they use *different* algorithms to speed up calculations. That's why one *can't* use an algorithm for numbers to work on intervals. It has to do with math and algorithms, not the implementation language – Panagiotis Kanavos Feb 13 '17 at 11:11
  • @selmaohneh notice that the class is *abstract*. The [source](https://github.com/mathnet/mathnet-numerics/tree/8accea16287115b29092990103cac5ce4c0ff23e/src/Numerics/LinearAlgebra/Single) shows that Math.NET contains specializations for `float`, `double` and `Complex` numbers. You'd have to implement your own matrix *and* factorizations like [SVD](https://github.com/mathnet/mathnet-numerics/blob/8accea16287115b29092990103cac5ce4c0ff23e/src/Numerics/LinearAlgebra/Factorization/Svd.cs) for it. – Panagiotis Kanavos Feb 14 '17 at 13:37
  • @selmaohneh Math.NET also provides hardware acceleration for those types [through Intel's MKL](https://numerics.mathdotnet.com/MKL.html). When activated, [MKL-specific versions](https://github.com/mathnet/mathnet-numerics/tree/6d20807570349c44ed360735e065e5587bf6b6ae/src/Numerics/Providers/LinearAlgebra/Mkl) of operations are used, eg [DotProduct](https://github.com/mathnet/mathnet-numerics/blob/6d20807570349c44ed360735e065e5587bf6b6ae/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Double.cs#L90) – Panagiotis Kanavos Feb 14 '17 at 13:43
  • For anyone interested, I wrote my own library that can handle those equation systems: https://github.com/selmaohneh/IntSharp – selmaohneh Oct 12 '17 at 13:09

1 Answers1

0

I cannot comment directly (due to small reputation), so I have to post an "answer", my apologies!

I don't think that what you have is a "generic type", it is a specific, custom (not built-in), type.

Suppose now that you could actually use the Matrix abstract class (you should try this yourself, by the way) to represent an interval matrix. You would still be left with all the hard work, since computing the SVD of the interval matrix is not as far as I know directly related to the SVD of any specific matrix, or is it? Likewise for interval eigenvalue/eigenvector calculations.

Giorgos Altanis
  • 2,742
  • 1
  • 13
  • 14
  • Tsk, tsk, tsk. The rule exist for a reason - one has to understand how the site works before commenting. For example, this *IS* an answer! Math libraries are for *math*. Numbers aren't the classes that somehow implement an interface, much less generic classes. Fast math libraries use specific computation algorithms and hardware acceleration including SIMD operations like .NET's Vector classes. – Panagiotis Kanavos Feb 13 '17 at 09:52
  • In fact, *computational algorithms* all depend on the simple fact, that simple arithmetic *is* simple. If not, then you need a *different* algorithm. For example, addition is assumed to be cheap. If not, eg in big integers or complex numbers, then a *different* algorithm is used to cover up that cost – Panagiotis Kanavos Feb 13 '17 at 09:56
  • @PanagiotisKanavos The arithmetic operations between two interval numbers (which is a very well defined mathematical entity, by the way) are simply defined in terms of elementary arithmetic operations. The problem is that the evaluation of complex expressions is far from trivial, let alone the calculations of quantities such as eigenvalues or singular values. {It is nice meeting you here!} – Giorgos Altanis Feb 13 '17 at 10:08
  • When I mention simple, I mean in the CPU sense - simple CPU operations. A *computational* library like Math.NET uses different algorithms than those taught in early math classes, in order to speed up operations. In addition, it will use optimizations and hardware acceleration where available. Which is probably why Math.NET expects `double` but not `Decimal` - `Decimal` operations aren't simple and can't be accelerated with SIMD operations – Panagiotis Kanavos Feb 14 '17 at 13:14
  • PS, you should buy beers – Panagiotis Kanavos Feb 14 '17 at 13:14
  • PPS, Math.NET has *specific* implementations for single, double, complex *and* hardware-accelerated providers. MKL is documented but there are [other providers too](https://github.com/mathnet/mathnet-numerics/tree/6d20807570349c44ed360735e065e5587bf6b6ae/src/Numerics/Providers/LinearAlgebra) like Cuda, OpenBLAS – Panagiotis Kanavos Feb 14 '17 at 13:44