Solving Ordinary Differential Equations using Euler in Java Programming - java

I'm trying to write a java program that will solve any ordinary differential equations using Euler method, but I don't know how to write a code to get any differential equation from the user. I was only able to write the code to solve a predefined ordinary differential equations.
I was able to come with a code to solve some particular ordinary differential equations which were written as functions in the program, I also made research online to look for similar problems but it seem they also wrote it to solve some designated problem not general questions on ordinary differential equations. This was found in most of the article have read online.
Here is my Euler class;
import java.lang.Math;
public class Euler {
private double x0, y0, x1, y1, h, actual;
public Euler (double initialx, double initialy,double stepsize,double finalx1) {
x0 = initialx; y0 = initialy; h=stepsize; x1 = finalx1;
}
public void setEuler (double initialx, double initialy,double stepsize,
double finalx1){
x0 = initialx;y0 = initialy;h =stepsize;x1 = finalx1;
}
public double getinitialx(){
return x0;
}
public double getinitialy(){
return y0;
}
public double getinitialexact(){
return (double) (0.9048*Math.exp(0.1*x0*x0));
}
double func(double x, double y){
return (double) (0.2*x*y);
}
double funct(double x){
return (double) (java.lang.Math.exp(0.1*x*x));
}
public double getinitialerror(){
return (double) Math.abs(actual - y0);
}
public double getEulerResult(){
for (double i = x0 + h; i < x1; i += h){
y0 = y0 + h *(func(x0,y0));
x0 += h;
double actual = (0.9048*funct(x0));
double error = Math.abs(actual - y0);
System.out.printf("%f\t%f\t%f\t%f\n",x0,y0,actual, error);
}
return y0;
}
}
Here is my Driver's class
import java.util.Scanner;
public class EulerTest {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Euler myEuler = new Euler(1.0,1.0,0.1,1.5);
System.out.println( "x\t explicit\tactual\t error\t " );
System.out.printf("%f\t%f\t%f\t%f\n", myEuler.getinitialx(),
myEuler.getinitialy(),myEuler.getinitialexact(),
myEuler.getinitialerror());
System.out.printf("my approximated value is %f\n\n",
myEuler.getEulerResult ());
System.out.println("enter another initial value of x: ");
double initialx = input.nextDouble();
System.out.println("enter another initial value of y: ");
double initialy = input.nextDouble();
System.out.println("enter another stepsize value of h: ");
double stepsize = input.nextDouble();
System.out.println("enter another upper bound of x: ");
double finalx1 = input.nextDouble();
myEuler.setEuler(initialx,initialy,stepsize,finalx1);
System.out.println( "x\t explicit\tactual\t error\t " );
System.out.printf("%f\t%f\t%f\t%f\n", myEuler.getinitialx(),
myEuler.getinitialy(),myEuler.getinitialexact(),
myEuler.getinitialerror());
System.out.printf("my approximated value is %f\n\n",
myEuler.getEulerResult ());
}
}
I will be glad if i can en lighted on how to write the java code to collect any ordinary differential equation from the user so as to solve using Euler's method.

What you are looking for is the ability to compile some code at run time, where part of the code is supplied by the user.
There is a package called JOOR that gives you a Reflect class that contains a compile method. The method takes two parameters (a package name:String and the Java code:String).
I've never personally used it, so can not vouch for its robustness, but here is a tutorial and the javadoc:
https://www.jooq.org/products/jOOR/javadoc/latest/org.jooq.joor/org/joor/Reflect.html#compile(java.lang.String,java.lang.String)
https://blog.jooq.org/2018/04/03/how-to-compile-a-class-at-runtime-with-java-8-and-9/
In your case, you would put your user supplied function in place of the following line of code:
return \"Hello World!\";\n"
Beware, you need to be 100% absolutely unconditionally guaranteed that the user can only ever enter a function to be solved. If they are supplying code, remember that unless you take safeguards, the code they enter could very easily be code the removes all of the files on your hard drive (or worse).
For the second part of your question - how do i implement a solution in Java using Euler's method, perhaps check out this link: Euler's Method in java or this https://rosettacode.org/wiki/Euler_method#Java which has it in pretty much every language you can imagine (and probably some you can't).

Related

Java getter with Parameter?

I am new to Java. I know about some core basics of Java such as setter and getter and recently came across a getter with a parameter (not sure if it is correct way of calling it):
public double getDistance(Point p)
{
// what is inside here? Usually without the "Point p" I simply put "return distance;"
}
This method belongs to a class called Point and it is meant to get the calculation of distance from a private method in the same class.
I will appreciate if someone can enlighten me on the getter "parameter" and how I can apply the return in this method.
Thank you.
EDIT: Added the private calculation method
// Compute distance
private double distance(Point p)
{
double xx;
double yy;
double r;
xx = this.x - p.x;
yy = this.y - p.y;
r = Math.sqrt(nx * nx + ny * ny);
return r;
}
I think a simple argument rename will make things clear, you want to calculate the distance between two-points. Specifically, this point and that point. Assuming you have double x and y coordinates in each Point that might look like,
public double getDistance(Point that) {
double tmpX = that.x - this.x;
double tmpY = that.y - this.y;
return Math.sqrt((tmpX * tmpX) + (tmpY * tmpY));
}
Why not use Point2D? It has built-in methods for computing distances from a supplied point to some point you already have.
Point2D pt = new Point2D.Double(10,20);
double distance = pt.distance(new Point2D.Double(20,30));
System.out.println(distance);
Check it out at java.awt.geom.Point2D

Implementation of Logistic regression with Gradient Descent in Java

I have implemented Logistic Regression with Gradient Descent in Java. It doesn't seem to work well (It does not classify records properly; the probability of y=1 is a lot.) I don't know whether my implementation is correct.I have gone through the code several times and i am unable to find any bug. I have been following Andrew Ng's tutorials on Machine learning on Course Era. My Java implementation has 3 classes. namely :
DataSet.java : To read the data set
Instance.java : Has two members : 1. double[ ] x and 2. double label
Logistic.java : This is the main class that implements Logistic Regression with Gradient Descent.
This is my cost function:
J(Θ) = (- 1/m ) [Σmi=1 y(i) log( hΘ( x(i) ) ) + (1 - y(i) ) log(1 - hΘ (x(i)) )]
For the above Cost function, this is my Gradient Descent algorithm:
Repeat ( Θj := Θj - α Σmi=1 ( hΘ( x(i)) - y(i) ) x(i)j
(Simultaneously update all Θj )
)
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Logistic {
/** the learning rate */
private double alpha;
/** the weight to learn */
private double[] theta;
/** the number of iterations */
private int ITERATIONS = 3000;
public Logistic(int n) {
this.alpha = 0.0001;
theta = new double[n];
}
private double sigmoid(double z) {
return (1 / (1 + Math.exp(-z)));
}
public void train(List<Instance> instances) {
double[] temp = new double[3];
//Gradient Descent algorithm for minimizing theta
for(int i=1;i<=ITERATIONS;i++)
{
for(int j=0;j<3;j++)
{
temp[j]=theta[j] - (alpha * sum(j,instances));
}
//simulataneous updates of theta
for(int j=0;j<3;j++)
{
theta[j] = temp[j];
}
System.out.println(Arrays.toString(theta));
}
}
private double sum(int j,List<Instance> instances)
{
double[] x;
double prediction,sum=0,y;
for(int i=0;i<instances.size();i++)
{
x = instances.get(i).getX();
y = instances.get(i).getLabel();
prediction = classify(x);
sum+=((prediction - y) * x[j]);
}
return (sum/instances.size());
}
private double classify(double[] x) {
double logit = .0;
for (int i=0; i<theta.length;i++) {
logit += (theta[i] * x[i]);
}
return sigmoid(logit);
}
public static void main(String... args) throws FileNotFoundException {
//DataSet is a class with a static method readDataSet which reads the dataset
// Instance is a class with two members: double[] x, double label y
// x contains the features and y is the label.
List<Instance> instances = DataSet.readDataSet("data.txt");
// 3 : number of theta parameters corresponding to the features x
// x0 is always 1
Logistic logistic = new Logistic(3);
logistic.train(instances);
//Test data
double[]x = new double[3];
x[0]=1;
x[1]=45;
x[2] = 85;
System.out.println("Prob: "+logistic.classify(x));
}
}
Can anyone tell me what am I doing wrong?
Thanks in advance! :)
As I am studying logistic regression, I took the time to review your code in detail.
TLDR
In fact, it appears the algorithm is correct.
The reason you had so much false negatives or false positives is, I think, because of the hyper parameters you choose.
The model was under-trained so the hypothesis was under-fitting.
Details
I had to create the DataSet and Instance classes because you did not publish them, and set up a train data set and a test data set based on the Cryotherapy dataset.
See http://archive.ics.uci.edu/ml/datasets/Cryotherapy+Dataset+.
Then, using your same exact code (for the logistic regression part) and by choosing an alpha rate of 0.001 and a number of iterations of 100000, I got a precision rate of 80.64516129032258 percent on the test data set, which is not so bad.
I tried to get a better precision rate by tweaking manualy those hyper parameters but could not obtain any better result.
At this point, an enhancement would be to implement regularization, I suppose.
Gradient descent formula
In Andrew Ng's video about the the cost function and gradient descent, it is correct that the 1/m term is omitted.
A possible explanation is that the 1/m term is included in the alpha term.
Or maybe it's just an oversight.
See https://www.youtube.com/watch?v=TTdcc21Ko9A&index=36&list=PLLssT5z_DsK-h9vYZkQkYNWcItqhlRJLN&t=6m53s at 6m53s.
But if you watch Andrew Ng's video about regularization and logistic regression you'll notice that the term 1/m is clearly present in the formula.
See https://www.youtube.com/watch?v=IXPgm1e0IOo&index=42&list=PLLssT5z_DsK-h9vYZkQkYNWcItqhlRJLN&t=2m19s at 2m19s.

Can I invoke input from main method into another method in the class

I need to use information gathered from my main method in a different method within the same class. Is that possible? If so, how do I go about doing so? Basically I have to gather the info in main method and implement it in the other. Help!
If I gain information say:
import java.util.Scanner;
public class MyClass
{
public static double main (String[] args)
{
double x, y, z;
Scanner scan = new Scanner(System.in);
System.out.print ("Please enter x value: ");
x= scan.nextDouble();
System.out.print ("Please enter y value: ");
y= scan.nextDouble();
System.out.print ("Please enter z value: ");
z= scan.nextDouble();
}
public static void OtherMethod()
{
int a=0;
while(x<y)
{
a++;
double b=x* (z/100);
x+=b;
}
System.out.println("After " + a + " time at " + z+ "%, you will have " + "$" + x);
}
}
It sounds like you are asking how to pass arguments to a function.
Try writing:
public static void OtherMethod(double x, double y, double z)
Inside Main:
OtherMethod(x,y,z)
Yes. If you change the first line of OtherMethod to
public static void OtherMethod(double x, double y, double z)
then you can call it from main with
OtherMethod(x, y, z);
which makes the x, y, z defined in OtherMethod equal to the x, y, z defined in main, for the purposes of the one method call.
Gratuitous advice
For the record, there are a few bad programming practices in your code snippet. It's OK for now, since you're a beginner, but don't make a habit of any of them.
Single letter variable names. It's not obvious to someone working on this code that x is an amount of money, y is your savings target, z is the interest rate, and so on. You should use full words or even multiple words for your variables. Like savingsTarget and interestRate.
Inconsistent spacing and indentation make code hard to read.
Most people prefer not to put the { character on a line by itself. Put it at the end of the previous line instead.
You've used floating point types for money. Don't ever store an amount of money in a double or a float variable. These aren't designed for accurate mathematics with decimals. Learn to use the BigDecimal class instead.
Having static methods instead of creating objects is often indicative of poor design. It also makes big programs much more difficult to test, if there are many static methods.
Method names should begin with a lower case letter. It makes your code a little easier to follow.
Just a few things to think about for your future programming efforts.
declare double x, y, z; as class level static attibutes -
private static double x;
private static double y;
private static double z;
Inside your main method then you can call OtherMethod();

Calculate interest rate in Java (TVM)

I've been working on a Java project which is calculator which can be used for calculating different scenarios of compound interest (very similar to the TVM Function found on a graphics calculator like this one)
The main function of the calculator is to calculate missing values using the known values in a formula. I have gotten all of the formulas working except for the one which calculates Interest rate (I)
I have done some research and apparently there is no straight formula to calculate the interest rate. This website: http://www.getobjects.com/Components/Finance/TVM/formulas.html shows the method i need to use, but it requires some iteration to find I using trial and error. (Check the link, Scroll down to the heading "Interest Rate Per Year")
Here is the structure I have set up for it:
public static double calculateI(double N, double PV, double PMT, double FV, double PY){
//method for calculating I goes here
return I;
}
I am not sure how to implement this, could someone please suggest how this can be done or point me in the right direction?
Thanks in advance.
Here is my code after the suggestion made by #rocketboy
public static double formulaI(double ip, double N, double PV, double PMT, double FV, double PY){
double I1=(PV*Math.pow((1+ip),N))+((PMT*1)*(Math.pow((1+ip),N))-1)+FV;
return I1;
}
public static double calculateI(double N, double PV, double PMT, double FV, double PY){
double ip=0;
double res;
do{
res = formulaI(ip,N,PV,PMT,FV,PY);
ip=ip+0.01;
System.out.println(res);
}while(res!=0);
double I=ip*PY;
return I;
}
Try something like:
double calculateI(/*all values for varialbles*/){
//definition;
}
Double.valueOf(d).equals(0.0);
long ip =0;
double res;
do{
res = calculateI(ip, /*other constant values*/);
ip++; /*Or you can increase ip according to your logic*/
}while ( Double.valueOf(res).equals(0.0/*Expected result*/));
Edit: You have to handle the edge cases. The equation may not ever converge to 0.

Extending java point class to find midpoint

Im studying for an upcoming exam and am working at sample problems, in particular the following one:
Add to class Point below an instance method called midpoint which returns an object of type Point representing the midpoint of two points, where one of the points is supplied as a parameter and the other is the current point (i.e. the point provided by the local instance variables). Note that midpoint returns a new Point object. Making good use of class Point, write a program which reads two points and prints their midpoint. The input consists of two lines where each line contains the x- and y-coordinates of a point. An example of input/output follows, with input indicated by bolding:
Enter two points
2.1 3.2
3.0 2.8
The midpoint is (2.55,3.0)
My code for the point class is as follows and seems to be ok (feel free to point out any errors or improvements):
class Point {
private double x, y; // coordinates
Point(double x0, double y0){ // all-args constructor
x = x0; y = y0;
}
Point(){}; // no-args constructor (defaults apply)
void get() {
x = Console.readDouble();
y = Console.readDouble();
}
public Point midPoint(Point p) {
double mx = (p.x + x)/2;
double my = (p.y + y)/2;
return new Point(mx,my);
}
public String toString()
{
return "(" + x + "," + y + ")";
}
}
And where I run into trouble is in actually using my midPoint method in the below code, any advice is appreciated.
import java.util.Scanner;
import java.io.*;
class Midpoint extends Point
{
public static void main (String[] args ) {
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter two points:");
double x1 = scanner.nextDouble();
double y1 = scanner.nextDouble();
double x2 = scanner.nextDouble();
double y2 = scanner.nextDouble();
Point p1 = new Point(x1, y1);
Point p2 = new Point(x2, y2);
p1.get();
return midPoint(p2);
}
}
The call to get() method seems unnecessary.
Secondly, call your midPoint using an object(as per the requirement in the question). Hence, it should be:
p1.midPoint(p2);
Finally, since that method returns a Point type, ensure you catch what is returned.
Point p3 = p1.midPoint(p2);
Well from what you've presented as your code , it's definitely wrong , midPoint is a class method so the only way to use it is to first instantiate the class , like you p1 , and then call the method for that specific instace:
Point p1 = new Point(whatever);
Point p2 = new Point(whatever);
Point p3 = p1.midPoint(p2);
your main method is void so it cant return point
if you want to operate on points p1 and p2, midpoint between them is p1.midPoint(p2) if you do this way, you don't need extend point class
what is your p1.get() actually doing? by any chance is it same as scanner?
Besides all that was written by others, your MidPoint class shouldn't extend Point class. I think you did that for purpose of using that midPoint method but it's wrong. You didn't add any new behaviour to Point class.
import java.util.*;
public class Hello {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int a=sc.nextInt();
int b=sc.nextInt();
int c=sc.nextInt();
int d=sc.nextInt();
System.out.println((a+c)/2,(b+d)/2);
}
}

Categories