4

The following class contains a method that should calculate the integral using the callback technique.

package integrals;

import java.lang.*;

public class Integrals 
{
    public static double f1(double x)
    {
        return x*5+Math.sin(x);
    }   

    public static double f2(double x)
    {
        return Math.pow(x*f1(-x),x);      
    }        

    public static double TrapezoidalIntegration(double a,double b,int n,double (*f)(double))
    {
        double rValue=0;
        double dx;

        dx=(b-a)/n;

        for(double i=f(a);i<f(b);i+=dx)
            rValue+=((f(i)+f(i+dx))*dx)/2.0;

        return rValue;
    }        

    public static void main(String[] args) 
    {


    }
}

How to make a callback in this case? I prefer to avoid ☞such solution☜ due to it's complexity and ugliness. Even if it is the least painful, I don't have an idea how to implement it here.

Community
  • 1
  • 1
0x6B6F77616C74
  • 2,559
  • 7
  • 38
  • 65
  • 1) create an interface declaring the method you want to pass; 2) create an anonymous class that implements that interface (`new MyInterface () { int methodIDefined([args I defined]) { [implementation of method]};`); 3) pass that instead if a function pointer; 4) invoke it: `nameOfArgument.methodIDefined();`. – 11684 Mar 31 '13 at 20:28
  • possible duplicate of [What's the nearest substitute for a function pointer in Java?](http://stackoverflow.com/questions/122407/whats-the-nearest-substitute-for-a-function-pointer-in-java) – nawfal Jul 05 '14 at 07:23

2 Answers2

6

How to make a callback in this case? I prefer to avoid such solution due to it's complexity and ugliness. Even if it is the least painful, I don't have an idea how to implement it here.

Since there are no function pointers in Java, you have to use a common interface instead. Your functions then have to be implementations of that interface. It is up to you whether you want to use names for those implementing classes (i.e. class F1 extends Function { … }) or anonymous classes instead (i.e. new Function { … }). It is also up to you whether you write the imp0lementation inside that class, or instead have the class implementation call one of your existing static functions.

Taking one example, with anonymous classes directly containing the implementation:

public class Integrals 
{

    public interface Function {
        double eval(double x);
    }

    public static final Function f1 = new Function() {
      public double eval(double x) {
        return x*5+Math.sin(x);
      }
    };

    public static final Function f2 = new Function() {
      public double eval(double x) {
        return Math.pow(x*f1.eval(-x),x);
      }
    };

    public static double TrapezoidalIntegration(double a,double b,int n,Function f)
    {
        // … using f.eval(x) to compute values
Community
  • 1
  • 1
MvG
  • 57,380
  • 22
  • 148
  • 276
2

This answer is valid for Java 7 or less that doesn't support closures nor callbacks.

First define an abstract class or an interface with a method that will calculate the integral value. For this sample, I'll define an interface:

interface IntegralCalculation {
    double getIntegralValue(double x);
}

In your actual code, let's replace double (*f)(double) parameter for the interface and the method to use:

public static double TrapezoidalIntegration(double a,double b,int n, IntegralCalculation integralCalc) {
    double rValue;
    double dx;

    dx=(b-a)/n;

// for(int i=f(a);i

Now, in your main method (or anywhere else where you will call this TrapezoidalIntegration method), pass an implementation of the interface. You can pass an instance of a class that implements the interface or an anonymous class.

Example using a class instance of a class that implements the interface (sorry, don't know other way to say it):

class BasicFunction implements IntegralCalculation {

    @Override
    public double getIntegralValue(double x) {
        return x*5+Math.sin(x);
    }
}

public class Integrals {

    public static void main(String[] args) {
        double x = TrapezoidalIntegration(0, 10, 10, new BasicFunction());
    }
}

Using an anonymous class:

public class Integrals {

    public static void main(String[] args) {
        double x = TrapezoidalIntegration(0, 10, 10, new IntegralCalculation() {

            private double f1(double x) {
                return x*5+Math.sin(x);
            }

            @Override
            public double getIntegralValue(double x) {
                return Math.pow(x*f1(-x),x);
            }
        });
    }
}

From the code above:

  • You can't pass a function pointer in Java, so double (*f)(double) parameter would be invalid, instead, we use an abstract class or an interface. IMO an interface would be better.
  • Once you have designed the interface, it must have a method that satisfy the rules of your function pointer. In this case, double (*f)(double) means a method that has a double as parameter and returns a double value. This is handled by getIntegralValue method.
  • After replacing the function pointer by the interface as parameter in TrapezoidalIntegration method, you should call the getIntegralValue as if it were the function pointer:

     for(int i = integralCalc.getIntegralValue(a);
        i < integralCalc.getIntegralValue(b); i += dx) { ... }
    
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332