0

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

5
  • 1
    This belongs over at codereview stack exchange... Commented May 7, 2017 at 11:07
  • I'm not entirely sure what you're asking here. Are you asking about functional programming? That's become a recent addition to Java. Are you asking for a review of what you've written? If so, please submit for a Code Review. Is it something else? Then please edit your question to make this clearer. Commented May 7, 2017 at 11:12
  • There is no question here. You should use an interface rather than an abstract class. Among other advantages, that would allow passing a lambda: 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. Commented May 7, 2017 at 11:13
  • Hi guys, many apologies for the lack of clarify, I will edit my post. I posted to see if my mode of thought on the situation was correct. The code presented was part of it. I'm not sure if that constitutes Code Review? I'm very new to this and am ignorant to a lot of the terminology (I will correct that). Commented May 7, 2017 at 11:22
  • Will in future do posts of this nature in codereview stack exchange. Thanks for letting me know. Commented May 7, 2017 at 11:23

1 Answer 1

1

Why not use the existing Function interface of Java 8 to define your newton method?

public double newton(double x, Function<Double,Double> f) {
    ...
}

and call it with lambda expressions :

double x1 = 3, x2 = 4;
CompMaths compMaths = new CompMaths();
compMaths.newton(x1, x -> x * x);
compMaths.newton(x2, x -> x - Math.sin(x*x));

EDIT: As JB Nizet commented, if all your functions take a double parameter and return a double value, it would be more efficient to use a DoubleUnaryOperator instead of a Function<Double,Double>, since DoubleUnaryOperator operates on a primitive type, so no boxing/unboxing is involved.

Sign up to request clarification or add additional context in comments.

3 Comments

I'd use a DoubleUnaryOperator instead.
@JBNizet That would certainly be more efficient for the specific example in the OP's question.
I wasn't aware that existed, thanks for the comment, I will adapt to use that instead. Thanks again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.