I'm working on implementing some basic Computational Mathematics in Java. One method for finding the roots of a function f(x) (where roots are the values xi where f(xi) = 0) is the Newton-Rhapson method. To implement in Java I first created a basic class (class to contain Newton-Rhapson method) and some definition of a function f(x):
public class CompMaths {
public double Newton(double x) {
//find root of f(x)
}
public double f(double x) {
//definition of f(x)
}
}
In doing so, if I want this to be compatible with any definition of f(x) that a user wants, i.e. say f(x) = x^2 , f(x) = x*sin(x) , I would have to create a separate class for each definition of f(x) that would also have to contain the definition of Newton-Rhapson method (and the many others comp math methods I need to implement). This seems overkill. Also, it exposes my CompMaths class to the user and I don't want that. Instead it would be great to be able to define each function and just 'pass it in' i.e
public double Newton(double x, f(x)) ...
This, as I'm sure everyone knows is not supported by Java. My initial thought was, well what if you passed in an object that had a definition of f(x), call it Func, i.e
public double Newton(double x, Func func) ...
So initially I thought that this wouldn't be the best solution as I would have to have multiple definitions of CompMaths for each different Func like object. And that would obviously be ridiculous, and is simply inverting the problem from before. To overcome this, I thought, "Well I want multiple different definitions of a function f(x) using a sole class definition Func. And one solution that came to mind was - Make Func abstract with an abstract method f(x) i.e.
public abstract class Func {
public abstract double f(double x);
}
So now I simply have to create separate classes for each function that extend Func and have their own separate definitions of f(x), some examples for f(x), call them f1(x)=x^2 and f2(x) = x - sin(x^2) i.e.
public class f1 extends Func {
@Override
public double f(double x) {return x*x;}
}
public class f2 extends Func {
@Override
public double f(double x) { return x - Math.Sin(x*x);}
}
Now if I want to use either f1 or f2 in the Newton method I use
double x1 = 3, x2 = 4;
CompMaths compMaths = new CompMaths();
compMaths.Newton(x1, new f1());
compMaths.Newton(x2, new f2());
This seems to work incredibly well (note - could define Newton as static to avoid having to create the CompMaths object). The user need only create their functions by extending Func and defining their own f(x). Nothing about the CompMaths class is exposed whatsoever as well. So I'm happy, but in no way do I consider myself an expert whatsoever, so I thought I would present to see what people think, and to see if there was a better approach.
Any comments would be greatly appreciated. Thanks, David
compMaths.Newton(x1, x -> x * x)or a method reference:compMaths.Newton(x1, Math::sqrt). There is already such an interface, BTW: DoubleUnaryOperator. You should also learn and respect the Java naming conventions.