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.
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
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) { ... }
Related
I am trying to use a list of function references as a lookup table (avoiding the need for a long switch statement). The code worked for a list of static methods, but when I tried to use non-static (i.e. instance) methods in the list, Java gives several errors regarding the types not matching.
Here is a minimal example:
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
public class MethodReferences {
// My original list of static references
private final static List<Function<Integer, Integer>> lookupTable = Arrays.asList(MethodReferences::f1, MethodReferences::f2);
// This doesn't work
// private final List<Function<Integer, Integer>> lookupTable = Arrays.asList(MethodReferences::f3, MethodReferences::f4);
private static int f1(int x) { return x * 2; }
private static int f2(int x) { return x * 3; }
private int f3(int x) { return x * 2; }
private int f4(int x) { return x * 3; }
public void run() {
System.out.println(lookupTable.get(1).apply(3));
}
public static void main(String[] args) {
MethodReferences testClass = new MethodReferences();
testClass.run();
}
}
The errors I received were all for the line containing the non-static definition:
Type mismatch: cannot convert from List<Object> to List<Function<Integer,Integer>>
and:
The target type of this expression must be a functional interface
I tried using this:: instead of MethodReferences:: before the function names. The code then compiled, but when it runs, nothing happens, probably because this has to be used within non-static functions.
I then moved the initialisation of the array (still using this:: to within the class constructor, but it continued to produce no output when run.
I've checked through the documentation and tutorials on method references in Java, but I cannot find an examples of creating references to instance methods within the class it is defined in (and I cannot find any examples of lists of function references either).
I'm aware that in the main method, you can do testClass::f1, but for my specific situation (not the example code) I do not even have a main class (the class is instantiated by another library), so this approach isn't possible. The methods have to be non-static because I need to be able to modify instance variables within them.
Edit:
It turns out that using this:: does work for the example code, although I am still unsure as to why it is valid (surely you can only use this within a non-static function?)
You need to use BiFunction instead of Function. The first argument is the implicit this argument.
public class MethodReferences {
private final static List<BiFunction<MethodReferences, Integer, Integer>> lookupTable
= Arrays.asList(MethodReferences::f3, MethodReferences::f4);
private int f3(int x) { return x * 2; }
private int f4(int x) { return x * 3; }
public void run() {
System.out.println(lookupTable.get(1).apply(this, 3));
}
public static void main(String[] args) {
MethodReferences testClass = new MethodReferences();
testClass.run();
}
}
output:
9
For instance method references which use the ClassName::functionName format, instead of instanceName::functionName, you also need to pass the specific instance of the class to the function when calling .apply().
This means that your method references are actually need to be a BiFunction<MethodReferences, Integer, Integer>, even though there is only one explicit parameter to the function.
When calling the method, you also need to pass this into apply:
import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
public class MethodReferences {
// To refer to non-static methods by class name,
// you must pass in the instance explicitly:
private final List<BiFunction<MethodReferences, Integer, Integer>> lookupTable = Arrays.asList(MethodReferences::f3, MethodReferences::f4);
private int f3(int x) {
return x * 2;
}
private int f4(int x) {
return x * 3;
}
public void run() {
// We need to pass this in, because it isn't implicit
// for ClassName::functionName references:
System.out.println(lookupTable.get(1).apply(3));
}
public static void main(String[] args) {
MethodReferences testClass = new MethodReferences();
testClass.run();
}
}
Why float method is not considered of Derive class in below program?
In the below program when I assign derive object to base class at that time base.f(20) consider the Derive class int method but base.f(20.0f) is not considered Derive class float method.
Can you guys explain me what is the logic behind this?
public class Tricky3 {
public static void main(String[] args) {
Derive derive = new Derive();
System.out.println(derive.f(10));
System.out.println(derive.f(10.0f));
System.out.println("------------------New Logic-----------------");
Base base = new Derive();
System.out.println(base.f(20));
System.out.println(base.f(20.0f));
}
}
class Base {
public int f(int i) {
System.out.print("Base f (int): ");
return i + 3;
}
public double f(double i) {
System.out.print("Base f (double) : ");
return i + 3.3;
}
}
class Derive extends Base{
public float f(float i) {
System.out.print("Derive f (float) : ");
return i + 3.3f;
}
public int f(int i) {
System.out.print("Derive f (int): ");
return i + 3;
}
}
Output
Derive f (int): 13
Derive f (float) : 13.3
------------------New Logic-----------------
Derive f (int): 23
Base f (double) : 23.3
You are using Base base reference variable and Derive derive object.
base.f(20.0f) will try to find Base.f(float)method signature, when it cannot find Base.f(float) the Dynamic Binding with Derive.f(float) cannot happen, then it will search for closest method which can support base.f(20.0f) call which is Base.f(double).
If you declare f(float) in Base class then Dynamic Binding will happen and Derive.f(float)
will be called.
When you choose to declare a style
Parent p = new Child();
You are accessing members from parent and implementations from children execute runtime. Since your parent doesn't have method with float type it chosen from Base. If you override the same method in children, that executes.
The problem can be reduced to the following snippet:
class Base {
public double f(double x) {
System.out.println("Base.f");
return x;
}
}
class Derived extends Base {
public float f(float x) {
System.out.println("Derived.f");
return x;
}
}
public class Main {
public static void main(String[] args) {
new Derived().f(1.0f); // Derived.f
( (Base)new Derived() ).f(1.0f); // Base.f
}
}
When evaluating new Derived().f(1.0f) the compiler has the choice
to implicitly convert the float parameter into a double and call Base.f(double), or
to call Derived.f(float) without conversion.
The compiler chooses the Derived.f(float) overload because it manages without conversion.
When evaluating ( (Base)new Derived() ).f(1.0f) the compiler no longer knows about the Derived.f(float) overload and is forced to do the conversion and then call Base.f(double).
The behavior would be different if Derived.f and Base.f had the same signature. Then the method would be overwritten and both statements would call Derived.f:
class Base {
public double f(double x) {
System.out.println("Base.f");
return x;
}
}
class Derived extends Base {
public double f(double x) {
System.out.println("Derived.f");
return x;
}
}
public class Main {
public static void main(String[] args) {
new Derived().f(1.0f); // Derived.f
( (Base)new Derived() ).f(1.0f); // Derived.f
}
}
I would like to make the ODE_solver static so that I model multiple ODE systems without creating an instance of the solver class each time. I would like to call the solver within the ODEsystem object. is there a simple way to do this?
Thanks in advance!
Static Class:
public class ODE_solver {
public static double[] solveODE(ODESystem eqn, double time, double delta) {
// does computation
}
}
Interface:
public interface ODESystem {
int getSystemSize();
double[] getCurrentValues();
double[] getFunction(double time, double[] values);
} // end ODESystem interface
How I'm trying to access the current object:
public class Star implements ODESystem {
// constants & variables
// methods required by the interface
public double[] getPosition(double time, double delta){
return solveODE(this.ODESystem, time, delta);
}
}
Since the method is a static member of ODE_solver, call it on this class:
return ODE_solver.solveODE(this.ODESystem, time, delta);
I'm building a Challenge24Solver class in Java. The logic itself works and finds the solutions as would be expected (with an arbitrary number of arguments). Anyway that part of the projects is works as I expect.
The question comes from problems with the representation of the solutions. It's fair to say that I've completed this project in Python and decided to attempt in Java as a sort of introduction, which may be the problem, that I'm trying to do this too like Python.
Here are some of my classes:
abstract class Operation { \\ Basic operation class
static String token;
abstract public double operate (double x, double y);
}
class AddOp extends Operation {
static String token = "+";
public double operate (double x, double y) {
return x+y;
}
}
//other operation classes SubOp, MulOp, DivOp
class Challenge24Step { // represents one step in a solution
Operation operator;
double x, y; //operands
double value; //the value of the step (x operator y)
public Challenge24Step (Operation operator, double x, double y) {
this.operator = operator;
// constructor code;
}
public String toString () {
return String.format("%s %s %s = %s", this.x, this.operator.token, this.y,
this.value);
}
}
The problem is that it still gets token from the Operation class: "null"
I understand that this is probably because operator is declared as Operation, but I don't understand why it doesn't go through standard inheritance: instance, class, each superclass
How would I rearrange the script so that the more specific operation classes' tokens are used?
You cannot make token static in the base class, because then there would be a single token per all inherited classes. You need to make it an instance variable. You cannot even put it in a static method, because static methods in Java are not overridable.
In Java, variables are not overridable. If you inherit a class and add a variable by the same name, the variable in the derived class will hide, not override the one in the base class.
To fix this, make token an abstract method in the base, provide an implementation in the derived class, and return the desired value. If you do this, you could replace the abstract class with an interface, because there would be no variables or implementations in it:
interface Operation { // Basic operation class
String getToken();
double operate (double x, double y);
}
class AddOp implements Operation {
public String getToken() {return "+"; }
public double operate (double x, double y) {
return x+y;
}
}
Alternatively, leave it unassigned in the base, add a constructor that takes the value of the token, and assign it there:
abstract class Operation { // Basic operation class
public final String token;
abstract public double operate (double x, double y);
protected Operation(String token) {this.token = token; }
}
class AddOp extends Operation {
public AddOp() { super("+"); }
public double operate (double x, double y) {
return x+y;
}
}
Static variables are referenced via the class. You have defined operator as being of type Operation, so operator.token refers to Operation.token.
I recommend using a getter for this purpose:
abstract Operation { \\ Basic operation class
abstract public double operate (double x, double y);
abstract public String getToken();
}
class AddOp extends Operation {
public double operate (double x, double y) {
return x+y;
}
public String getToken() {
return "+";
}
}
My problem is with the return statement in each method,the error in netbeans says:
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - bad operand types for binary operator '+'
first type: T
second type: T
at GenericMath.add(GenericMath.java:8)
at GenericMath.main(GenericMath.java:20)
public class GenericMath<T> {
public T a,b;
public T add() {
return a+b;
}
public T multiply() {
return (a*b);
}
public static <T> void main(String[] args) {
GenericMath<Integer> x=new GenericMath<Integer>();
x.a=5;
x.b=10;
int z=x.add();
GenericMath<Double> y = new GenericMath<Double>();
y.a = 5.5;
y.b = 10.2;
double g=y.multiply();
}
}
The compiler doesn't know that you can multiply and add T values - it's not the return part which the problem, it's the expression itself. You'll see the same effect if you split the two parts:
T result = a + b;
return result;
It will be the first line that fails - and there's no particularly clean answer to this. Generics just aren't built for this sort of work in Java. What you could do is have:
public abstract class GenericMath<T extends Number> {
public abstract T add(T a, T b);
public abstract T multiply(T a, T b);
// etc
}
public final class IntegerMath extends GenericMath<Integer> {
public Integer add(Integer a, Integer b) {
return a + b;
}
// etc
}
... and similar classes for DoubleMath etc.
Then:
// Alternatively, have a static factory method in GenericMath...
GenericMath<Integer> math = new IntegerMath();
int x = math.add(5, 2);
You need to do these things:
Bound the generic type to Number
Make the add() etc method abstract and return T
Provide implementations for each type you want to support
Like this:
public abstract class GenericMath<T extends Number> {
public T a,b;
public abstract T add();
public abstract T multiply();
}
public class IntegerGenericMath extends GenericMath<Integer> {
public Integer add() {
return a + b;
}
public Integer multiply() {
return a * b;
}
}
// similar for Double
public static void main(String[] args) {
IntegerGenericMath x=new IntegerGenericMath();
x.a=5;
x.b=10;
int z=x.add();
DoubleGenericMath y = new DoubleGenericMath();
y.a = 5.5;
y.b = 10.2;
double g=y.multiply();
}
There's a lot of auto boxing going on here, which won't work genericly, which is why you need separate classes for each type.