Switching between codes in my program - java

I have three programs calculating PI and I want to refactor it into one. I can't get it working using an if or switch command. It is something to do with case 3.
public class ProgramPI {
public static void main(String[] args) {
// TODO Auto-generated method stub
int z = Integer.parseInt(JOptionPane.showInputDialog("Wybierz metode liczenia PI 1=Leibnitz 2=Wallis 3=MonteCarlo:"));{
switch(z){
case 1:
double pi=0;
double mianownik=1;
double i = Integer.parseInt(JOptionPane.showInputDialog("Obliczamy PI metoda Leibnitza podaj n: "));
for (int x = 0; x < i; x++){
// obliczanie ciagu
if (x % 2 == 0) {
pi = pi + (1 / mianownik);
} else {
pi=pi - (1 / mianownik);
}
mianownik = mianownik + 2;
}
pi = pi * 4;
System.out.println("Przy n= " + i + " Pi = " + pi);
break;
case 2:
double termCount = 2;
double polpi = 1;
double termin;
// double termino2 =0;
double n = Integer.parseInt(JOptionPane.showInputDialog("Liczymy Pi wzorem Wallisa, podaj n:"));
for (double j = 0; j <= n; j++)
{
termin = (termCount / (termCount-1));
// System.out.println(termin);
polpi = polpi * termin;
termin = (termCount / (termCount+1));
// System.out.println(termin+" "+ mediopi);
polpi = polpi * termin;
termCount= termCount + 2;
}
System.out.println("Ilosc wyrazen = " + termCount);
polpi = polpi * 2;
System.out.println("Przy n= " + n + " Pi wynosi: " + polpi);
break;
case 3:
static double podajPi(int liczbaStrzalow) {
int wKole = 0;
// generowanie punktów
for (int i = 0; i < liczbaStrzalow; i++) {
double x = Math.random();
double y = Math.random();
// Sprawdzanie, czy punkt jest w kole
// r = 1, więc r * r = 1
if ((x * x + y * y) <= 1) {
wKole++;
}
}
// obliczanie stosunku liczby punktów w kole do wszystkich punktów
double s = (double) wKole / liczbaStrzalow;
return 4 * s;
}
System.out.println("Pi = " + Math.PI);
// obliczanie Pi dla 00, 1000, 10 000, 100 000 oraz 1000 000 punktów
// można to zrobić za pomocą pętli
for (int i = 100; i <= 1000000; i *= 10) {
double pi = podajPi(i);
System.out.println("Dla " + i + " punktów Pi = " + pi + "\n"
+ "błąd = " + (pi - Math.PI));
}
}
{
}
}

Related

Math in Java(Combinatorics)

My problem is:
My math formula is:
In this case X = N; Y = L;U = K;
public class Play {
public static void main(String args[]) {
//n!(n−k−1)!
int n = 10;
int k =2;
int l = 12;
long result;
result = (calculaFator(n) / calculaFator(n-k-1));
result= (long) (result * Math.pow((n-k),(l-k)-1));
System.out.println(result);
}
public static long calculaFator(long x) {
long f = x;
while (x > 1) {
f = f * (x - 1);
x--;
}
return f;
}
}
It should be 721599986, but it is giving me 96636764160
I have some samples:
With n=10, k=2, l=12 it should be 721599986
With n=10, k=2, l=16 it should be 626284798
With n=10, k=1, l=20 it should be 674941304
With n=5, k=2, l=8 it should be 10800
The java codes is working according to your stated formula.
It seems like the formula is wrong rather than the codes. (or expected results or your x,u,y mapping to n,l,k is incorrect?)
int x = 10;
int u = 2;
int y = 12;
long numerator = calculaFator(x);
long denominator = calculaFator(x - u - 1);
int xu1 = x - u - 1;
long result = numerator / denominator;
System.out.println();
System.out.println(x + "!= numerator: " + numerator); //10!= numerator: 3_628_800
System.out.println(xu1 + "!= denominator: " + denominator); //7!= denominator: 5_040
System.out.println("result1: " + result); //result1: 720 (correct)
int xu = x - u;
int yu1 = y - u - 1;
double remainderPlaylist = Math.pow(xu, yu1);
System.out.println(xu + "^" + yu1 + " = " + remainderPlaylist);//8^9 = 1.34217728E8
System.out.println(xu + "^" + yu1 + " = " + (long) remainderPlaylist);//8^9 = 134_217_728 (correct)
long mul = (long) (result * remainderPlaylist);
System.out.println(result + "x" + (long)remainderPlaylist + " = " + mul); //720x134_217_728 = 96_636_764_160 (mathematically correct)

Fingerprint singular point detection

I am trying to determine the core and delta points of a fingerprint. I'm using the Poincaré index method, but I am unable to successfully detect this points and I can't figure out why.
First I divide the image in 15x15 blocks, then I calculate the x and y gradients which i use in obtaining the orientation map. After getting the mean orientation for each block then i apply the Poincaré index method, described in the image below (credits: Handbook of Fingerprint Recognition, Davide Maltoni):
And the code is this:
public static void detectSgPoints(int blkSze, Mat src) {
utils.console2file("cons_2_file");
int windowX = 1;
int windowY = 1;
if (blkSze < src.width()) {
windowX = src.width() - blkSze;
}
if (blkSze < src.height()) {
windowY = src.height() - blkSze;
}
Map<Point, Double> map = new HashMap<>();
double[][] avg = new double[src.height() / blkSze][src.width() / blkSze];
int m = 0;
int n = 0;
for (int i = 0; i < windowY; i += blkSze) {
for (int j = 0; j < windowX; j += blkSze) {
Mat block = utils.getROI(src, new Rect(j, i, blkSze, blkSze));
Mat dx = new Mat(new Size(blkSze, blkSze), CvType.CV_64FC1);
Mat dy = new Mat(new Size(blkSze, blkSze), CvType.CV_64FC1);
Imgproc.Sobel(block, dx, CvType.CV_64FC1, 1, 0);
Imgproc.Sobel(block, dy, CvType.CV_64FC1, 0, 1);
Mat orientation = calculateOrientation(dx, dy);
int cpx = j + (blkSze / 2), cpy = i + (blkSze / 2);
avg[m][n] = avgAngle(orientation, false);
if (avg[m][n] < 0) {
avg[m][n] = 360 + avg[m][n];
}
map.put(new Point(cpx, cpy), avg[m][n]);
n++;
}
n = 0;
m++;
}
for (int mm = 1; mm < avg.length - 1; mm++) {
for (int nn = 1; nn < avg[0].length - 1; nn++) {
int j = nn * blkSze;
int i = mm * blkSze;
double psum = 0;
int cpx = j + (blkSze / 2), cpy = i + (blkSze / 2);
for (int k = 0; k < anglePos2.length - 1; k++) {
double dif = 0.0;
dif = avg[mm + anglePos2[k + 1][0]][nn + anglePos2[k + 1][1]]
- avg[mm + anglePos2[k][0]][nn + anglePos2[k][1]];
System.out.println("adding " + "(" + avg[mm + anglePos2[k +1[0]][nn + anglePos2[k + 1][1]] + "-"
+ avg[mm + anglePos2[k][0]][nn + anglePos2[k][1]] + ") = " + dif + " to " + psum);
psum = psum + dif;
}
double poincare = psum;
System.out.println("cpx = " + cpx + ", cpy = " + cpy + " poincare = " + poincare);
}
}
}
private static double avgAngle(Mat orientation, boolean toDegrees) {
List<Double> angle = new ArrayList<>();
for (int i = 0; i < orientation.height(); i++) {
for (int j = 0; j < orientation.width(); j++) {
double value = orientation.get(i, j)[0];
value = Math.toDegrees(value);
angle.add(value);
}
}
return getMeanAngle(angle);
}
public static double getMeanAngle(List<Double> sample) {
double x_component = 0.0;
double y_component = 0.0;
double avg_d, avg_r;
for (double angle_d : sample) {
double angle_r;
angle_r = Math.toRadians(angle_d);
x_component += Math.cos(angle_r);
y_component += Math.sin(angle_r);
}
x_component /= sample.size();
y_component /= sample.size();
avg_r = Math.atan2(y_component, x_component);
avg_d = Math.toDegrees(avg_r);
return avg_d;
}
public static Mat calculateOrientation(Mat dx, Mat dy) {
Mat orientation = new Mat(dx.size(), CvType.CV_32F);
for (int i = 0; i < dx.rows(); i++) {
for (int j = 0; j < dx.cols(); j++) {
double valueX = dx.get(i, j)[0];
double valueY = dy.get(i, j)[0];
double result = Math.atan2(valueY, valueX);
orientation.put(i, j, result);
}
}
return orientation;
}
Where is the problem?

How to solve for eigenvectors of a 2x2 Matrix using Java

I'm trying to solve for the eigenvectors of a 2x2 matrix. As of right now, I'm only considering real matrices whose eigenvectors and eigenvalues are also real. I'm currently having issues solving for the eigenvectors.
This is what I have so far:
public double[] getBasis(double[][] basis){
double a = basis[0][0];
double b = basis[0][1];
double c = basis[1][0];
double d = basis[1][1];
double eigenvalue1 = ((a+d) + Math.sqrt( Math.pow(a-d,2) + 4*b*c))/2;
double eigenvalue2 = ((a+d) - Math.sqrt( Math.pow(a-d,2) + 4*b*c))/2;
double tempx;
double tempy;
int counter = 1;
for (double y = -1000; y <= 1000; y++) {
for (double x = -1000; x <= 1000; x++) {
if (((a-eigenvalue1)*x + b*y == 0) && (c*x + (d-eigenvalue1)*y == 0)) {
tempx = x;
tempy = y;
System.out.println("Eigenvector1: (" + x + "," + y + ")");
System.out.println("Eigenvalue1: "+ eigenvalue1);
}
}
}
for (double y = -10; y <= 10; y++) {
for (double x = -10; x <= 10; x++) {
if (((a-eigenvalue2)*x + b*y == 0) && (c*x + (d-eigenvalue2)*y == 0)) {
tempx = x;
tempy = y;
System.out.println("Eigenvector2: (" + x + "," + y + ")");
System.out.println("Eigenvalue2: " + eigenvalue2);
}
}
}return eigenvector1;
}
}
This method should have an input of a 2x2 array and i want it to output the two normalized eigenvectors. How would I be able to output both the eigenvectors?Additionally, I'm not allowed to use any packages that can solve for the eigenvectors or values. Basic math and arithmetic is perfectly acceptable.
Output:
Eigenvector1: (0.0,0.0)
Eigenvector1: (1.0,1.0)
Eigenvector1: (2.0,2.0)
Eigenvector1: (3.0,3.0)
Eigenvector1: (4.0,4.0)
Eigenvector1: (5.0,5.0)
Eigenvector1: (6.0,6.0)
Eigenvector1: (7.0,7.0)
Eigenvector1: (8.0,8.0)
Eigenvector1: (9.0,9.0)
Eigenvector1: (10.0,10.0)
Eigenvector2: (0.0,0.0)
How would I be able to choose only one vector for eigenvector 1 and eigenvector 2. Additionally, If the matrix had input (1,1,1,-1) such that it was a 2x2 matrix then the eigenvalues should be the square root of positive and negative 2. I'm able to get that far. However, once I attempt to calculate the eigenvectors I don't get a value for an eigenvector.
**Edited: I added the errors and took out the infinite loop I got stuck on before
**
There is no need to solve the linear system for the eigenvectors with a trial-and-error loop.
The equation
(a-e)*x+b*y == 0
has always the solution
x = b, y = -(a-e)
which you then would have to normalize. You will need to check if the first equation has the coefficients all zero, then you have to use the second equation
c*x + (d-e)*y == 0
with solution
x = -(d-e), y = c
If also the second equation has all zero coefficients, then any vector is an eigenvector, as the matrix is the diagonal matrix diag([e, e]).
This should result in some code like
e = eigenvalue1;
x = b; y = e-a;
r = Math.sqrt(x*x+y*y)
if( r > 0) { x /= r; y /= r; }
else {
x = e-d; y = c;
r = sqrt(x*x+y*y)
if( r > 0) { x /= r; y /= r; }
else {
x = 1; y = 0;
}
}
System.out.println("Eigenvector1: (" + x + "," + y + ")");
e = eigenvalue2;
x = b; y = e-a;
r = Math.sqrt(x*x+y*y)
if( r > 0) { x /= r; y /= r; }
else {
x = e-d; y = c;
r = sqrt(x*x+y*y)
if( r > 0) { x /= r; y /= r; }
else {
x = 0; y = 1;
}
}
System.out.println("Eigenvector2: (" + x + "," + y + ")");
According to your edit comments, I think this revised code should produce what you want. I've removed your temp variables and I'm returning your computed basis values as a 2 element array. Excuse me if I've misnamed anything, my maths is a little rusty.
public static void main(String[] args) {
// the input matrix
double[][] matrix = {
{1.0, 1.0},
{1.0, -1.0}
};
// compute the basis
double[] basis = getBasis(matrix);
System.out.println("Basis: (" + basis[0] + ", " + basis[1] + ")");
}
public double[] getBasis(double[][] matrix){
double a = matrix[0][0];
double b = matrix[0][1];
double c = matrix[1][0];
double d = matrix[1][1];
double eigenvalue1 = ((a+d) + Math.sqrt( Math.pow(a-d,2) + 4*b*c))/2;
double eigenvalue2 = ((a+d) - Math.sqrt( Math.pow(a-d,2) + 4*b*c))/2;
// store the basis in a 2 element array
double[] basis = new double[2];
for (double y = -1000; y <= 1000; y++) {
for (double x = -1000; x <= 1000; x++) {
if (((a-eigenvalue1)*x + b*y == 0) && (c*x + (d-eigenvalue1)*y == 0)) {
System.out.println("Eigenvector1: (" + x + "," + y + ")");
basis[0] = eigenvalue1;
}
}
}
for (double y = -10; y <= 10; y++) {
for (double x = -10; x <= 10; x++) {
if (((a-eigenvalue2)*x + b*y == 0) && (c*x + (d-eigenvalue2)*y == 0)) {
System.out.println("Eigenvector2: (" + x + "," + y + ")");
basis[1] = eigenvalue2;
}
}
}
return basis;
}
Output:
Basis: (1.4142135623730951, -1.4142135623730951)

What is wrong with my pi calculator?

I'm using Wallis' method to calculate pi, and I think I did it right. At least I thought I did anyway. I think the problem (output is 0)has to do with rounding and remainders, though I can't be sure. Here's the code:
import java.util.Scanner;
public class WallisPi {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int a = 2;
int b = 3;
int c = 1;
int pi = 0;
double acc = 0.0;
int n = scan.nextInt();
scan.close();
for (int i = 0; i <= n; i++) {
pi = (2 / 3) * c;
if (a > b) {
b += 2;
} else {
a += 2;
}
c = a / b;
}
pi *= 4;
System.out.println("The approximation of pi is " + pi + ".");
acc = Math.PI - pi;
System.out.println("It is " + acc + " off.");
}
}
Since posting this I've made some changes to the code, though it's still not quite functional. I get 2.666..., so there's something else at work here as well.
import java.util.Scanner;
public class WallisPi {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
double a = 2.0;
double b = 3.0;
double c = 1.0;
double pi = 0;
double acc = 0.0;
int n = scan.nextInt();
scan.close();
for (int i = 0; i <= n; i++) {
pi = (2.0 / 3.0) * c;
if (a > b) {
b += 2;
} else {
a += 2;
}
c = a / b;
}
pi *= 4;
System.out.println("The approximation of pi is " + pi + ".");
acc = Math.PI - pi;
System.out.println("It is " + acc + " off.");
}
}
int a=2;
int b=3;
double pi=2;
for(int i=0;i<=n;i++){
pi *= (double)a/(double)b;
if(a>b){
b+=2;
} else {
a+=2;
}
}
pi*=2;
Using n = 4000 yields 3.141200
Here's the whole program, fixed:
import java.util.Scanner;
public class WallisPi {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
scan.close();
double pi = 2;
int a = 2;
int b = 3;
for (int i = 0; i <= n; i++){
pi *= (double) a / (double) b;
if (a > b) {
b += 2;
} else {
a += 2;
}
}
pi *= 2;
double acc = Math.PI - pi;
System.out.println("The approximation of pi is " + pi + ".");
System.out.println("It is " + acc + " off.");
}
}
Since your varibles are ints, all your divisions are integer divisions, omitting the fraction (and preserving only the whole part of the result). For accurate results, you should define your variables as doubles:
double a=2;
double b=3;
double c=1;
double pi=0;

Pi with Nilakantha method

I am trying to calculate pi with the Nilakantha method. Whenever I run this program I get -Infinity if I input 1 and anything else I get NaN.
I am trying to modify my program that uses the Leibniz method, and I'm very new to java.
I appreciate all help!
public static void main(String[] args) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the number of calculations you would like to do");
long no = Long.parseLong(reader.readLine());
long cycle = 0;
long w = 2;
long x = 3;
long y = 4;
long z = 4;
long odd=1;
long i=1;
long a = 1;
long b = 1;
double pi= 0.0;
for(;i<=no;i++)
{
a = w*x*y;
b = x*y*z;
double currentTerm=0.0;
if (i%2==0)
{
currentTerm=(double)4/a;
cycle = cycle+1;
w = w+1;
x = x+1;
y = y+1;
}
else
{
currentTerm=(double)-4/b;
cycle = cycle+1;
x = x+1;
y = y+1;
z = z+1;
}
odd=odd+2;
pi = pi+currentTerm;
}
System.out.println("You calculated that pi is");
System.out.println(pi);
System.out.println(3.1415926535897932);
System.out.println("Pi is actually");
double error = pi/3.1415926535897932;
if(error >= 1) {
double bigerror=2-error;
System.out.println("Your accuracy is");
System.out.println(bigerror*100);
System.out.println("percent");
System.out.println(cycle);
}
else {
System.out.println("Your accuracy is");
System.out.println(error*100);
System.out.println("percent");
System.out.println(cycle);
}
}
}
On your first iteration a and b are both zeros.
I don't think you have your initialization part correct.
http://helloacm.com/two-simple-equations-to-compute-pi/
Here I see that j starts from 2.
You have zeroes.
Make sure you implement the algorithm correctly.
Here is your code corrected.
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class MainProgram {
public static void main(String[] args) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the number of calculations you would like to do");
long no = Long.parseLong(reader.readLine());
long step = 0;
double ans = 3;
long j = 2;
double pi = 0.0;
while (true) {
step++;
if ((step % 2) == 1) {
ans += 4.0 / (1.0 * j * (j + 1) * (j + 2));
} else {
ans -= 4.0 / (1.0 * j * (j + 1) * (j + 2));
}
j += 2;
pi = ans;
if (step >= no)
break;
}
System.out.println("You calculated that pi is");
System.out.println(pi);
System.out.println("Pi is actually");
System.out.println(3.1415926535897932);
double error = pi / 3.1415926535897932;
if (error >= 1) {
double bigerror = 2 - error;
System.out.print("Your accuracy is: ");
System.out.print(bigerror * 100);
System.out.println(" percent");
System.out.println(step);
} else {
System.out.print("Your accuracy is: ");
System.out.print(error * 100);
System.out.println(" percent.");
System.out.println(step);
}
}
}

Categories