3

I want to express a mathematical subset relation in Java. In Mathematics we have nice relations like: the integers are a subset of the real numbers. I try to somehow express that in java with a Point class with generics:

public class Point<T extends Number> {
 protected Number xCoord;

 public T getXCoordinate() {
      // do some stuff
     return (T) this.xCoord;
}

Unfortunately I have to cast here to T, but then I get the usual warning of unchecked conversion, what I want to avoid. Here it would be nice if Number were instanciable, but it is unfortunately abstract. So I wonder if there is a common instanciable Superclass of Integer and Double (with an explicit Zero). I didn't find one. But mathematically we really do have N as a subset of R. How can I reflect this in Java? Here I am at the end of my knowledge according to generics, because I cannot define a subclass (say InstNumber) of Number that is instanciable and superclass of Integer and Double since I am not able to change the java.lang package. So does anyone have an Idea how to "make Points of Integers a subset of Points of Double" or find a common instanciable class InstNumber. However if not, why is the type safety so hard at this point?

In the end I try to implement an algorithm to encrypt with elliptic curves. But to do so you often need that each Point in FpxFp (p prime) c NxN is also a Point in RxR. So it I want to compute with these "Numbers" even if I didn't know the current subtype. Since mathematically a field is interesting in here it would be nice to have a kind of "abstract" but instanciable Subclass called Field of Number which is Parent class of all the children of number. In Field it would be sufficient to have a concrete 0 and 1 which are present in most subclasses of Number. Thus could Field be some "mathematical field" hence a set with explicit 0 and 1 (like Z/2Z which is indeed a mathematical field). Now let for instance Integer be a subclass of Field. The only "additional job" of the Integer class is to map the "abstract" 0 and 1 of Field to the concrete 0 and 1 interpretation of Integer. This could be also implemented for other subclasses.

I know that associativity is not really possible. But for most calculations and decisions in programming it would be nice to test whether a Field element is 0 or 1 (Specifically to invert a Field element). So I want to restrict myself to the calculation of existing numbers in R, not such things as NaN.

I am sorry that I could not give you more code, but I think its too much Code that I have right now to post it here. For short: I have a ProjectivePoint class which has to do the projective addition of points in RxR. But it would be nice if the calculations in this class also are availible on FpxFp c RxR. Which is mathematically more or less trivial, but I see no current solution in Java.

  • Very interesting question. I've wondered about stuff like that myself and I don't know that there are any really satisfying answers. Java's type system is probably not a great place to start for any kind of subtle question -- have you looked at Haskell? But if working with Java is a requirement, you'll probably find you'll have to make some compromises in order to get something working. PS. By the way, I don't understand why you didn't say `T xCoord` instead of `Number xCoord`. Maybe you can edit your post to explain. PPS. Probably cs.stackexchange.com is more suitable for this question. – Robert Dodier Dec 21 '20 at 16:48
  • For short: My first implementation was with Number and I programmed a static class Calculator to calculcate with Numbers based on their real subtype using the instanceof operator. But also this Calculator class is very repetetive in the way that I repeat the if(x instanceof Double || y instanceof Double) condition multiple times in the implementation of the operations Calculator.add .sub .mult and ,div. So to tell the thruth I am not happy with my Calculator implementation either... – christian2222 Dec 21 '20 at 17:19
  • Could you please provide more code so it is clearer which problem you are trying to solve? It is currently not clear to me how you are planning to create these `Point` objects or why you want `Number` to be instanciable. – Marcono1234 Dec 21 '20 at 17:45
  • Sorry for the missing code, I have given more Information in the main thread. – christian2222 Dec 21 '20 at 18:20
  • Maybe you just just go ahead and define new classes which fit mathematical concepts better. You could have methods plus, times, inverse, etc. in a base class which are then redefined for each subclass. You might try to find out if anyone has already created such classes. – Robert Dodier Dec 21 '20 at 19:40
  • Unfortunately my base class has to be instanciated otherwise I could again use java.lang.Number. I think I found a logical cat that bites itself here... Suppose for example I have a class Field which is father of all possible fields (like Z/2Z,Fp,Q and R). How should I define the elements in Field? Unfortunately they have to have a type and this type should be overriden in the subclases.with elements like int or double I think this is somehow impossible or I don't unsterstand enough in inheritance of java. Even if I use an interface the methods do have to have a return type...a logical cat! – christian2222 Dec 21 '20 at 22:39
  • May I ask why `protected Number xCoord;` is not `protected T xCoord;`? – akuzminykh Dec 22 '20 at 03:03
  • The problem is that the formulas for projective points are "kind of the same" whether you calculate over FpxFp or over RxR. Hence I want to express this calculation somehow. To express a calculation I need methods like addition, multiplication, inversion and so on. Hence T is too abstract to calculate. Moreover if you define such a finite set T and the needed calculations which you could do, you also need to "embed" this set T into R (since mathematically Fp has an injection into R). The problem is that R is overcountable and hence in particular infinite. And Fp can be large for large prime p. – christian2222 Dec 22 '20 at 06:15
  • Did you take a look in existing Java projects and how they do structure the hierarchy? https://github.com/kredel/java-algebra-system/tree/master/src/edu/jas/structure (java-algebra-system) or https://github.com/Hipparchus-Math/hipparchus/blob/master/hipparchus-core/src/main/java/org/hipparchus/FieldElement.java (hipparchus) – axelclk Dec 23 '20 at 16:40
  • Thanks axelclk for this hint. I found @SuppressWarnings("unchecked") directives in there too. Fortunately in the mean time I have constructed a solution by myself which I will post as soon as possible. Thanks for all your support and ideas (especially the idea of defining an instanciable super class based on Roberts comment drove me further), it's been a pleasure to discuss such things with all of you. – christian2222 Dec 24 '20 at 08:23

1 Answers1

1

For short: I used polymorphism multiple times to do calculations and used an instanciable fatherclass Z2 of Fp and R.

I have constructed constructed an inheritance tree of Z2 extends Fp and Fp extends R (all instanciable). The calculations inside Z2 are easy to code. Fp in contrast uses integers to calculate different values modulo p (where p is a prime passed to the constructor. R (or RealNumber) is a class that encapsulates a double and uses "doubled methods" (methods with double arguments and return type) for its calculations. I override with each inherited class the calculation methods with different parameters (i.e. Fp.add(int,int) or R.add(double,double)). Because of the instanciable class Z2 I can now define a PrjoectivePoint and do all needed calculations on Z2. The polymorphism is located in my static Calculator class, where for example add(Z2,Z2) is defined. In my first implementation I use the instanceof operator to decide whether the Z2 argument of add is really a Z2 instance, a Fp instance of a R instance. (By really I mean explicitly hence an Fp object is not instance of R) In a better version I think I can replace this by polymorphism.

The methods intValue() and doubleValue() are common from Z2 to R and implemented in the expected way since each class encapsulates it's own value. Now my calculations in Calculator can be "polymorphically" done over Z2. For security my Calculator class has a reference Z2 instanceType = new Z2|Fp|R dependend on which field I want to calculate. With all my add,mult,invert and so on methods implemnted polymorphically in Calcuator I can now do the calculations for the ProjectivePoint on Z2. Again polymorphism decides which calculations are really done in Calculator (because R extends Fp extends Z2). Moreover Z2 is instanciable and that has made the success, since every calculation can be done polymorphically on Z2.

Note that 4x in a formula for x in Z2 can also be written as Calculator.add(Calculator.add(x,x),Calculator.add(x,x));