For-loop yielding partially correct result - java

So here is my code, I am trying to calculate the area of a wave:
public class coefficient {
public static void main (String[] args) {
double f[] = {14.0,18.7,9,4.1,6.7,6,6.3,8.4,4,2.9};
double T = 10;
double area = 0;
int n = 5;
double w = 2 * Math.PI / T;
for (int i = 1; i <= n; i++) {
System.out.println("n = " + i);
for (int t = 0; t < f.length; t++) {
System.out.println("T = " + t + " .......... " + f[t] * Math.cos(i*(w * t)));
area += f[t] * Math.cos(i*(w * t));
}
System.out.printf("\nTotal Area: \t\t%.2f\n", area);
System.out.printf("Calculated area: \t%.2f\n\n", (2/T)*area);
}
}
}
So my outputs are correct, except for my total and calculated areas, which are RIGHT when i=1, but after that they don't give me the right answer.
Here's the thing though - when I manually input "i":
area += f[t] * Math.cos(1*(w * t)); OR
area += f[t] * Math.cos(2*(w * t));
I get the right areas! So I think there's something wrong with my for-loop, but I'm not sure what...
So when i = 1, my area output = 15.11. That is correct. Now, when i = 2 in my loop, I SHOULD get 10.06 but instead I'm getting 25.17. I get the correct answer when I manually change i, so i isn't being defined in that line. But it is in the line above it.

Maybe it's because you aren't setting area back to 0 after each iteration. Move the declaration of area into the for loop, and see if that workd.
double f[] = {14.0,18.7,9,4.1,6.7,6,6.3,8.4,4,2.9};
double T = 10;
int n = 5;
double w = 2 * Math.PI / T;
for (int i = 1; i <= n; i++) {
double area = 0;
System.out.println("n = " + i);
for (int t = 0; t < f.length; t++) {
System.out.println("T = " + t + " .......... " + f[t] * Math.cos(i*(w * t)));
area += f[t] * Math.cos(i*(w * t));
}
System.out.printf("\nTotal Area: \t\t%.2f\n", area);
System.out.printf("Calculated area: \t%.2f\n\n", (2/T)*area);
}

Related

Print a diamond shape with Java

I want to print a grid shape on the output console in Eclipse.
Basically I took an integer from user that is the number of stars in a single border of the grid.
Here the code I have up to now:
public class PrintDiamond {
public static void main(String[] args) {
System.out.print("Enter the number: ");
Scanner scan = new Scanner(System.in);
int num = scan.nextInt();
num--;
for (int i = num; i > 0; --i) {
//Insert spaces in order to center the diamond
for (int n = 0; n < i; ++n) {
System.out.print(" ");
}
System.out.print(" *");
for (int n = i; n < num; ++n) {
System.out.print(" + ");
System.out.print(" ");
}//Ending bracket of nested for-loop
System.out.println();
}//Ending bracket of for loop
//Print out a diamond shape based on user input
for (int i = 0; i <= num; ++i) {//<= to print the last asterisk
//Insert spaces in order to center the diamond
for (int n = 0; n < i; ++n) {
System.out.print(" ");
}
System.out.print(" *");
for (int n = i; n < num; ++n) {
System.out.print(" + ");
System.out.print(" ");
}//Ending bracket of nested for-loop
System.out.println();
}//Ending bracket of for loop
}
}
and the output is (for int. 6):
*
* +
* + +
* + + +
* + + + +
* + + + + +
* + + + +
* + + +
* + +
* +
*
Here is the code:
public static void main(String[] args) {
System.out.print("Enter the number: ");
Scanner scan = new Scanner(System.in);
int num = scan.nextInt();
final char[][] diamond = makeDiamond(num);
for (int i = 0; i < diamond.length; i++) {
for (int j = 0; j < diamond[i].length; j++) {
System.out.print(diamond[i][j]);
}
System.out.println();
}
}
public static char[][] makeDiamond(int n) {
int width = 1 + 4 * (n - 1);
int height = 1 + 2 * (n - 1);
char[][] out = new char[height][width];
int x0 = 2 * (n - 1);
int y0 = n - 1;
for (int i = 0; i < width; i += 2) {
// Top borders
int y1 = Math.abs(y0 - i / 2);
out[y1][i] = '*';
// Bottom borders
int y2 = height - Math.abs(i / 2 - y0) - 1;
out[y2][i] = '*';
if ((x0 - i) % 4 == 0) {
// Plus signs
for (int j = y1 + 1; j < y2; j++) {
out[j][i] = '+';
}
}
}
return out;
}
Some hints for your solution:
Create a method for printing a "diamond row" for a given row width and a given total width of the diamond.
Create a tool method for printing a given number of spaces.
Your main method should have two simple loops: One for the upper, one for the lower half.
The magic is in the method of printing a single diamond row for the given two parameters w and n.
This is always a good approach - reduce your complex problem to a problem with lesser complexity - in this case, by creating methods and using these e.g. in loops.
In your method for printing a single diamond row, you will need to check if you are in an "odd" or "even" row.
Ok, this looks like a school asignment, so I won't write any code.
First you need to understand and write, in pseudo-code or just plain English, what you want to do:
Instructions on how to draw the grid.
How many lines should I print?
How long is each line?
How do I know if I have to print a + or not?
General steps of your program.
Read size of the grid, N.
If N < 1, ask again (or exit program).
If N = 1 or greater, print the grid.
Detailed sub-steps of your program.
Print the grid
Loop for number of lines.
Create empty array/buffer/list/string with correct length for current line.
...
Because right now, it seems like you haven't figured out any of that. And if that's the case, then your problem has nothing to do with Java but rather with basic programming knowledge, which you won't get if we just code the algorith for you.
Two nested for loops from -n to n and one if else statement. The zero point is in the center of a diamond, and the boundary is obtained when:
Math.abs(i) + Math.abs(j) == n
Try it online!
public static void main(String[] args) {
printDiamond(0);
printDiamond(2);
printDiamond(5);
}
static void printDiamond(int n) {
System.out.println("n=" + n);
for (int i = -n; i <= n; i++) {
for (int j = -n; j <= n; j++)
if (Math.abs(i) + Math.abs(j) == n)
System.out.print("* ");
else if (Math.abs(i) + Math.abs(j) < n && j % 2 == 0)
System.out.print("+ ");
else
System.out.print(" ");
System.out.println();
}
}
Output (combined):
n=0
n=2
n=5
*
* * + * * + * * + * *
* * + * * + * * + + + * * + + + * * + + + + + * * + + + * * + + + * * + * * + * *
See also: Print an ASCII diamond of asterisks

points of intersection by determinate not working

I have unfinished code to find the points of intersection of all lines that are perpendicular. So far I have this:
import java.util.Scanner;
public class CountSquares {
public static void main(String args[]) {
Scanner scan = new Scanner(System.in);
int lines = scan.nextInt();
scan.nextLine();
double[][] lineMXYC = new double[4][lines]; // stores the slope, and x
// and y co-ordinates and c
// so the line can be
// represented as y = mx + c
double x1 = 0.0, x2 = 0.0, y1 = 0.0, y2 = 0.0;
double slope = 0.0;
for (int i = 0; i < lines; i++) {
String input = scan.nextLine();
String[] arrayOfInput = input.split(" ");
x1 = Integer.parseInt(arrayOfInput[0]);
y1 = Integer.parseInt(arrayOfInput[1]);
x2 = Integer.parseInt(arrayOfInput[2]);
y2 = Integer.parseInt(arrayOfInput[3]);
if (x1 == x2)
slope = Double.POSITIVE_INFINITY;
else
slope = (y2 - y1) / (x2 - x1);
lineMXYC[0][i] = slope;
lineMXYC[1][i] = x1;
lineMXYC[2][i] = y1;
lineMXYC[3][i] = y1 - (slope * x1);
}
for (int j = 0; j < lines - 1; j++) { //sorts the array by slopes
if (lineMXYC[0][j] > lineMXYC[0][j + 1]) {
double TEMP = lineMXYC[0][j + 1];
lineMXYC[0][j + 1] = lineMXYC[0][j];
lineMXYC[0][j] = TEMP;
}
}
double[] pointsOfIntersectionX = new double[(int) (lines * lines / 4) + 1]; //max number of points there can be
double[] pointsOfIntersectionY = new double[(int) (lines * lines / 4) + 1];
int count = 0;
for (int k = 0; k < lines; k++) {
for (int n = k; n < lines; n++) {
System.out.println(n + " " + k);
if (1 / lineMXYC[0][k] == -lineMXYC[0][n]) {
double m1 = lineMXYC[0][k];
double m2 = lineMXYC[0][n];
double c1 = lineMXYC[3][k];
double c2 = lineMXYC[3][n];
System.out.println("m1: "+m1);
System.out.println("m2: "+m2);
System.out.println("c1: "+c1);
System.out.println("c2: "+c2);
pointsOfIntersectionX[count] = (c1 - c2) / (m2 - m1); //determinate to find x co-ordinate
pointsOfIntersectionY[count] = (m2 * c1 - m1 * c2)
/ (m2 - m1);
System.out.println("The lines intersect at: ("
+ pointsOfIntersectionX[count] + ", "
+ pointsOfIntersectionY[count] + ")");
count++;
}
}
}
scan.close();
}
}
This will take in the number of lines, then two points on each line seperated by spaces. If I enter
2
3 -1 0 8
3 -1 0 -2
It works fine, finding the point (3, -1)
However, if I put in the same values reversed
2
3 -1 0 -2
3 -1 0 8
It gives me (-3.0, 6.999999999999999) which is wrong
What is going wrong with the code? I can't pinpoint where the problem comes from.
Sorting by slopes may mix your input data in your version.
If you want to swap the lines, swap all line data:
for (int j = 0; j < lines - 1; j++) { //sorts the array by slopes
if (lineMXYC[0][j] > lineMXYC[0][j + 1]) {
for (int i = 0; i < 4; i++) {
double TEMP = lineMXYC[i][j + 1];
lineMXYC[i][j + 1] = lineMXYC[i][j];
lineMXYC[i][j] = TEMP;
}
}
}
If I may give you an advice:
make a separate Line class for better design
implement the compare method or a line comparator
use some sorting algorithm, the one you use will not sort correctly for more lines, e.g. see Java Tutorials

Infinite while loop in Java - Newton-Raphson method

Ok this code was in another question but I couldn't work out how to add my updated code. I got this code working and putting out the right answers but it isn't stopping according to my while loop conditions. i'm not sure what I've done wrong there? The answer clearly converges and all values are right, just while loop is ignored.
/* Newton Raphson Method*/
import java.util.Scanner;
import static java.lang.Math.*;
public class NewtRaphEx {
// Creating Function f = x - cos(3.5x)
double f = 0.0;
double df = 0.0;
public static double function(double x) {
return (x - cos(3.5 * x));
}
public static double dfunction (double x) {
return (1 + 3.5*sin(3.5 * x));
}
public static void main (String[] args) {
//Initialising all variables
double xn = 0.06;
double xnew = 0.0;
double e_allow = 0.001;
double fn = 0.0;
double eps = 0.0;
double dfn = 0.0;
double dx = 0.0;
int n = 0;
int nMax = 10000;
do {
for (n = 0; n <= nMax; n++) {
fn = function(xn);
dfn = dfunction(xn);
dx = -(fn / dfn);
xnew = xn + dx;
xn = xnew;
eps = abs(dx / xn);
n = n + 1;
}
} while (eps <= e_allow || n < nMax);
System.out.print("N" + "\t" + "X" + "\t" + "F(x)" + "\t" + "dF(x)" + "\t");
System.out.println("delX" + "\t" + "X_new" + "\t" + "Epsilon");
System.out.format("%d\t" + "%.3f\t" + "%.3f\t" + "%.3f\t" + "%.3f\t" + "%.3f\t" + "%.3f", n, xn, fn, dfn, dx, xnew, eps);
}
}
The expression
eps <= e_allow || n < nMax
evaluates to true when you reach it, therefore the for loop will run again, setting n = 0 and thus the infinite loop.
Specifically, you would have:
eps = 0.0;
e_allow = 0.001;
n = 10002; // due to the increment inside the loop
nmax = 10000;
as as such:
eps <= e_allow || n < nMax
0.0 <= 0.001 (true) OR 10002 <= 10000 (false) -> true

How put values from cycle to multi array

I have such a cycle (it is piece of my other code):
for (int i = 2; i < 257; i = i * 2) {
V -= i + 0;
System.out.println("Suma: " +V+ " atemus: "+i);
///////////////////
int X [][] = new int [8][16]; //multi array where i need to put "i" values
}
and how you see in code have i muti array:
int X [][] = new int [8][16];
How put values of i in array and print it into a screen?
ok i put my whole code:
import java.util.Scanner;
public class IV_darbas {
public static void main(String[] arguments) {
int r, H, R, V, x, k, z;
Scanner ivestis = new Scanner(System.in);
boolean pabaiga = false;
while (!pabaiga) {
System.out.println("");
System.out.println("Si programa leis skaiciuoti turi");
System.out.println("Jei noresi testi spausk bet kuri klavisa");
System.out.println("Kai noresi baigti ivesk zodi: pabaiga ");
String first = "testi";
// Ivedi "R" reiksme
Scanner one = new Scanner(System.in);
System.out.println("Ivesk reiksme: R");
R = one.nextInt();
// Ivedi "H" reiksme
Scanner two = new Scanner(System.in);
System.out.println("Ivesk reiksme: H");
H = two.nextInt();
// Ivedi "R" reiksme
Scanner three = new Scanner(System.in);
System.out.println("Ivesk reiksme: r");
r = three.nextInt();
V = (int) ((Math.PI * Math.pow(H, 4) * (Math.pow(R, 2)
+ Math.pow(r, 2) + Math.pow(r, 5) * Math.pow(r, 3))) / 3);
System.out.println("Tavo gautas turis: " + V);
z = V * (-1);
System.out.println("Tavo gautas turis(su priesingu zenklu):" + z);
// Ivedamas papildomas skaicius
Scanner four = new Scanner(System.in);
System.out.println("Ivesk dar viena skaiciu: ");
x = four.nextInt();
k = x * z;
// salygos if sakinys
System.out.println("Pakeisto ir papildomo skaciaus sandauga: " + k);
if (k > 0) {
System.out.println("gautas skaicius " + k + " yra teigiamas");
} else if (k < 0) {
System.out.println("gautas skaicius " + k + " yra neigiamas");
} else if (k == 0) {
System.out.println("gautas skaicius " + k + " yra neutralus");
}
System.out.println("");
System.out.println("Sumavimas. Prie gauto rezultato: " + V);
for (int i=2; i<257; i=i*2 ){
V += i+0;
System.out.println("Suma: " +V+ " pridejus: "+i);
}
V = (int) ((Math.PI * Math.pow(H, 4) * (Math.pow(R, 2)
+ Math.pow(r, 2) + Math.pow(r, 5) * Math.pow(r, 3))) / 3);
System.out.println("");
System.out.println("Atimtis. Prie gauto rezultato: " + V);
for (int i=2; i<257; i=i*2 ){
V -= i+0;
System.out.println("Suma: " +V+ " atemus: "+i);
///////////////////
int X [][] = new int [8][16];
}
System.out.println("");
System.out.println("Ar testi? (n/y)");
first = ivestis.next();
if (first.equalsIgnoreCase("Pabaiga")) {
System.out.println("Darbas baigtas!");
break;
}
}
}
}
It is very unclear what you are trying to do and here is an example of what you might want to do.
// declared before any loop so it is in scope after the loop
int[][] values = new int[8][16];
int i = 1;
for(int x = 0; x < values.length; x++) {
for(int y = 0; y < values[x].length; y++) {
values[x][y] = i;
i += 2;
}
}
// to print the values
for(int x = 0; x < values.length; x++) {
for(int y = 0; y < values[x].length; y++) {
System.out.print(values[x][y] + " ");
}
System.out.println();
}
If you're asking just how to add something to an array it goes like this:
X[n] = i;
where n is an index in the array. But as someone already said you need to declare your array outside of the loop, otherwise it won't be accessible.

Detecting fundamental frequency with comb filter

I need to use comb filter/transform to detect fundamental frequency of a wav file in java.
I also needed to implement ZCR, but this was easy.
Now I have this:
int best = 0, best_step = 0;
for (int step = 3; step < 400; ++step) {
int sum = 0;
for (i = 1; i < 10 && i * step < spectrum.length; ++i) {
for (int di = 0; di < i; ++di) {
sum += spectrum[i * step + di] / i;
}
}
sum *= 100;
comb.add(sum);
}
int sum = 0;
for (i = 0; i < comb.size(); ++i) {
sum = comb.get(i); // 3 * comb[i] - comb[i-1] - comb[i+1];
System.out.println(i + " - " + sum);
if (sum > best) {
best_step = i;
best = sum;
}
}
And my problem is that this code detects the wrong frequency. ;( I have searched for an algorithm/implementation (in any language) but have not found anything.
Note, I cannot use autocorelation, etc.. It must be comb filtering.
Edit: A little more explanation of my code:
I load a wav file and put frames to array frames. Then I make fft on it and have array of Complex (named widmo) (simple structure to handle complex numbers).
Now I put abs of Complex numbers into array spectrum:
double[] spectrum = new double[widmo.length];
for (i = 0; i + 1 < widmo.length; ++i) {
spectrum[i] = widmo[i].abs();
}
ArrayList<Integer> comb = new ArrayList<Integer>();
int best = 0, best_step = 0;
for (int step = 3; step < 400; ++step) {
int sum = 0;
for (i = 1; i < 10 && i * step < spectrum.length; ++i) {
for (int di = 0; di < i; ++di) {
sum += spectrum[i * step + di] / i;
}
}
// sum /= step + 100; // ta linijka pozwala usunąć sporo
// niespodziewanych skoków częstotliwości
sum *= 100;
comb.add(sum);
}
int sum = 0;
for (i = 0; i < comb.size(); ++i) {
sum = comb.get(i); // 3 * comb[i] - comb[i-1] - comb[i+1];
// ctx.fillRect(i, canvas.height, 1, -sum);
System.out.println(i + " - " + sum);
// tmp.add(new freqTime(sum,));
if (sum > best) {
best_step = i;
best = sum;
}
}
System.out.println();
System.out.println(best_step);
System.out.println(4 * 44100);
System.out.println((frames.length / numChanels));
System.out.println(best_step * 44100
/ (frames.length / numChanels));
The last println should show me my fundamental frequency, but it doesn't,.
I got this in javascript from my friend.
I figure it out (i think:P). Last println gives basic freq :). Maybe someone will need it or even imporve it :)
ArrayList<double[]> okna = new ArrayList<>();
ArrayList<freqTime> lista = new ArrayList<freqTime>();
int po2 = (int) Math.pow(2,
Integer.parseInt((String) potega2Input.getText()));
po2 /= 2;
double[] triangles = new double[po2];
double maxWykres = 0;
int licznik = 0;
int licznik2 = 0;
int T = frames.length;
boolean wykresFlaga = false;
for (int k = 0; k < T; k += po2) {
licznik = 0;
licznik2 = 0;
double[] tmp = new double[po2];
Complex[] zespolone = new Complex[po2];
for (int i = k; i < k + po2; i++) {
if (i < T) {
tmp[licznik] = frames[i];
zespolone[licznik] = new Complex(frames[i], 0);
licznik2 = licznik;
} else {
tmp[licznik] = frames[licznik2];
zespolone[licznik] = zespolone[licznik2];
}
licznik++;
}
okna.add(tmp);
FFT fft = new FFT();
zespolone = fft.fft(zespolone);
double maxF = 0;
double maxFI = 0;
double maxH = findMaxComp(zespolone);
double[] doWykresu = new double[zespolone.length];
for (int a = 2; a < 100; a++) {
for (int i = 0; i < po2; i++) {
doWykresu[i] = zespolone[i].abs();
triangles[i] = Math.abs(i % (2 * a) - a)
* (maxH) / a;
// triangles[i] = Math.abs(i % (2 * a) - a) * (maxH)
// / a;
}
double sumT = 0;
for (int i = 0; i < po2 / 2; i++) {
sumT += triangles[i] * doWykresu[i];
}
if (sumT > maxF) {
maxF = sumT;
maxFI = a;
}
}
//
// maxFI /= 2;
//
if (wykresFlaga == false) {
maxWykres = maxH;
}
for (int i = 0; i < po2; i++) {
doWykresu[i] = zespolone[i].abs();
triangles[i] = Math.abs(i % (2 * maxFI) - maxFI)
* (maxWykres) / maxFI;
}
if (wykresFlaga == false) {
System.out.println("Max w widmie: " + maxWykres);
new Wykres(doWykresu, 1, triangles);
wykresFlaga = true;
}
// System.out.println((2 * 44100 / po2) * maxFI);
System.out.println((float) (44100 / (float) po2)
* 2*(float) maxFI + " Znalzione a: " + maxFI);
lista.add(new freqTime(
(int) ((float) (44100 / (float) po2) *2* (float) maxFI),
(double) ((double) po2 / 44100)));
/*
* System.out.println((44100 / po2) * maxFI + " " + maxFI +
* " " + maxFI / 44100 + " " + 44100 / (maxFI / po2 * 44100)
* + " " + 44100 * maxFI / T);
*/
// System.out.println(zespolone[(int) maxFI/2].abs());
}

Categories

Resources