Formatting of 2D arrays of chars - java

I have a program which reads in a pair of integers from a file and stores that in a Point class which i have created. The first integer is the x coordinate and the second is the y coordinate on each line of the file. All valid points have x-coordinates in the range [0, 40] and y-coordinates in the range [1, 20].
The input file contains data like this:
I performed some validation checks so that my program ignores invalid data or out of range data.
I then have to plot a regression line on top of those points. I have to use 2D arrays of chars and would prefer to do it this way insetad of using Point2D class of java or some other graphical classes of java.
"X"s is used to represent the points, "-"s the regression line segments, and ""s where a line segment and a point are located at the same spot*
Th formula used for regression line is this:
# Edit #
Below is the code snippet that i got from #sprinter:
initializeArray(charArray);
int xySum = 0;
int xSqSum = 0;
int xSum = 0;
int ySum = 0;
for (Point points: point) {
xySum += points.getX() * points.getY();
xSqSum += points.getX() * points.getX();
xSum += points.getX();
ySum += points.getY();
}
int xMean = xSum / count;
int yMean = ySum / count;
int n = point.size();
int slope = (xySum - n* xMean * yMean) / (xSqSum - n * xMean * xMean);
for (Point points: point) {
charArray[points.getX()][points.getY()] = 'X';
}
// plot the regression line
for (int x = 0; x <charArray.length; x++) {
int y = yMean + slope * (x - xMean); // calculate regression value
charArray[x][y] = charArray[x][y] == 'X' ? '*' : '-';
}
This is my program's output after i ran sprinter's code.:
whereas i want output like this:
Also this is how i am initializing the charArray:
public static void initializeArray(char[][] charArray) {
for(int k =0; k< charArray.length; k++) {
for(int d = 0; d<charArray[k].length;d++) {
charArray[k][d] = ' ';
}
}
}
This is the new output:

I'm finding it hard to understand what the fillArray function is supposed to do. You could have multiple 'y' values for each 'x' value in your list of points so i assume you are calling this once for each point. But the regression line has lots of 'x' values that aren't in the list of points which means you would have to call this once for each regression point. You also don't need to return the array after filling the value.
Your slope calculation doesn't seem to match the formula at all. This would make more sense to me:
float xySum = 0;
float xSqSum = 0;
float xSum = 0;
float ySum = 0;
for (Point point: points) {
xySum += point.x * point.y;
xSqSum += point.x * point.x;
xSum += point.x;
ySum += point.y;
}
float xMean = xSum / count;
float yMean = ySum / count;
float n = points.size();
float slope = (xySum - n* xMean * yMean) / (xSqSum - n * xMean * xMean);
I suspect you would be much better off plotting all the points then plotting the regression line.
List<Point> points = ...;
// first plot the points
for (Point point: points) {
array[point.x][point.y] = 'X';
}
// now plot the regression line
for (int x = 0; x < 40; x++) {
int y = Math.round(yMean + slope * (x - xMean));
array[x][y] = array[x][y] == 'X' ? '*' : '-';
}
By the way, if you are familiar with Java 8 streams then you could use:
double n = points.size();
double xySum = points.stream().mapToDouble(p -> p.x * p.y).sum();
double xSqSum = points.stream().mapToDouble(p -> p.x * p.x).sum();
double xMean = points.stream().mapToDouble(p -> p.x).sum() / n;
double yMean = points.stream().mapToDouble(p -> p.y).sum() / n;
Finally, your x dimension is the first and y dimension second. So to print you need to iterate through y first, not x:
for (int y = 0; y < 20; y++) {
for (int x = 0; x < 40; x++) {
System.out.print(array[x][20-y-1]);
}
System.out.println();
}

Related

What causes Java version Random walk doesn't converge to expected value?

Basically, I implemented a Random walk program in Java. And I know the distance should converge to l * (n ^ 0.5)(l is the step length, n is the total steps). If let l equals to 1, then d = n ^ 0.5 or in other words: d = sqrt(n).
But, strangly, although I cannot find any error in my code, it just converges to unexpected value. For example, given l = 1, n = 100, d should converge to 10, but actually it converges to 8.86 after 1000000 times experiments.
Here is my code:
public class RandomWalk {
private int x = 0;
private int y = 0;
private final Random random = new Random();
private void move(int dx, int dy) {
x += dx;
y += dy;
}
private void randomWalk(int m) {
for (int i = 0; i < m; i++)
randomMove();
}
private void randomMove() {
boolean xOry = random.nextBoolean();
boolean plusOrminus = random.nextBoolean();
int delta = plusOrminus ? 1 : -1;
int dx = xOry ? delta : 0, dy = xOry ? 0 : delta;
move(dx, dy);
}
public double distance() {
return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
}
public static double randomWalkMulti(int m, int n) {
double totalDistance = 0;
for (int i = 0; i < n; i++){
RandomWalk walk = new RandomWalk();
walk.randomWalk(m);
totalDistance += walk.distance();
}
return totalDistance/n ;
}
}
I've thought some possiblities. First I think it may be caused by that the generated boolean by random has bias. Second I think it may be caused by float precision lost. But as this is just a very simple use case, I don't think these two situations are possible.
Could any one tell me why it doesn't work as expected?
I don't think it's true that the distance should average out to √n. According to https://math.stackexchange.com/questions/103142/expected-value-of-random-walk, the square of the distance should average out to n, but that's not the same thing (since the average of the square roots of a set of numbers is not the same as the square root of their average).

Java Nested Loops Issue

so I've been working on this code for a while now, and I've reached a standstill. It's a project for school and it came in two parts, the first part was no issue at all.
A drunkard begins walking aimlessly, starting at a lamp post. At each time step, the drunkard forgets where he or she is, and takes one step at random, either north, east, south, or west, with probability 25%. How far will the drunkard be from the lamp post after N steps?
Write a program RandomWalker.java that takes an integer command-line argument N and simulates the motion of a random walker for N steps. After each step, print the location of the random walker, treating the lamp post as the origin (0, 0). Also, print the square of the final distance from the origin.
My code for this part of the problem was:
import java.util. *;
import java.math. *;
public class RandomWalker {
public static void main(String args[]){
int N = Integer.parseInt(args[0]);
Random rand = new Random();
int x = 0;
int y = 0;
int XorY;
int dist;
int count =0;
while(count<N){
XorY = rand.nextInt(2);
dist = rand.nextInt(2);
if(XorY==0){
if(dist==0)
dist = -1;
x += dist;
System.out.println("("+x+", " +y+")");
}
else{
if(dist==0)
dist = -1;
y += dist;
System.out.println("("+x+", " +y+")");
}
count ++;
}
System.out.println("Squared Distance = " + (x*x + y*y));
}
}
For the second part of the problem-
Write a program RandomWalkers.java that takes two command-line arguments N and T. In each of T independent experiments, simulate a random walk of N steps and compute the squared distance. Output the mean squared distance (the average of the T squared distances.)
% java RandomWalkers 100 10000
squared distance = 101.446
% java RandomWalkers 100 10000
mean squared distance = 99.1674
% java RandomWalkers 200 1000
mean squared distance = 195.75
The code I came up with is-
import java.util.*;
import java.math.*;
public class RandomWalkers {
public static void main(String args[]) {
Random rand = new Random();
int N = Integer.parseInt(args[0]);
int T = Integer.parseInt(args[1]);
double avgDist =0;
int stepCount =0;
int trialCount =0;
int x = 0;
int y = 0;
int XorY;
int dist;
while(trialCount<T){
while(stepCount<N){
XorY = rand.nextInt(2);
dist = rand.nextInt(2);
if(XorY==0){
if(dist==0)
dist = -1;
x += dist;
}
else{
if(dist==0)
dist = -1;
y += dist;
}
stepCount ++;
}
avgDist += ((x*x) + (y*y));
trialCount++;
}
System.out.println("Mean Squared Distance = " + avgDist/(double)trialCount);
}
}
I have been stumped here for a really long time, the code compiles and runs but it seems that all it is giving me is a single trial value, and not the desired average. Any help is appreciated, thank you very much. (Also sorry for the improper formatting, I am new here and tried my best).
The solution with the nested while loop inside the for loop is shown below. You have to reset the x, y and distance variables after each trial. Or, even better, to define and initialize them to 0 at the beginning of the for loop, like so:
public class RandomWalkers {
public static void main(String[] args) {
int r = Integer.parseInt(args[0]);
int trials = Integer.parseInt(args[1]);
double steps = 0.0;
for (int j = 0; j < trials; j++) { // run one experiment
int x = 0;
int y = 0;
int distance = 0;
while (distance < r) { // simulate one random walking
double i = Math.random();
if (i < 0.25) {
y += 1;
distance = Math.abs(x) + Math.abs(y);
steps += 1;
}
if (i >= 0.25 && i < 0.5) {
x += 1;
distance = Math.abs(x) + Math.abs(y);
steps += 1;
}
if (i >= 0.5 && i < 0.75) {
y -= 1;
distance = Math.abs(x) + Math.abs(y);
steps += 1;
}
if (i >= 0.75 && i < 1) {
x -= 1;
distance = Math.abs(x) + Math.abs(y);
steps += 1;
}
}
}
System.out.println("average number of steps = " + steps / trials);
}
}

Find Peak value using slope - android - java

I'm trying to code that If the sign value of the slope changed from positive to negative, then that value indexing is my pressure peak of the sensor. and even through if it found the peak, there might be another peak because of the pressure is increasing.
How can I do that please? Thank you in advance.
for (int i =1;i<strNumbers.length -2;i++){ //strNumber is the array stream from sensor.
String y1;
y1 = strNumbers[i];
String y2;
y2 = strNumbers[i+1];
float y_2 = Float.parseFloat(y2);
float y_1 = Float.parseFloat(y1);
float delta_y = y_2 - y_1;
float mySlope = 0;
float delta_x;
delta_x = 1; //always difference is 1.
mySlope = (delta_y / delta_x);
activity.FirstPeak.setTextColor(Color.RED);
activity.FirstPeak.setText(String.valueOf(mySlope));
}
At each point in the loop, you need to compare two gradients - the gradient on the left, and the gradient on the right. If the left is positive, and the right is negative, then you have found a peak.
List<Integer> peaks = new ArrayList<>();
for (int i = 1; i < strNumbers.length - 1; i++)
{
float left = Float.parseFloat(strNumbers[i]) - Float.parseFloat(strNumbers[i - 1]);
float right = Float.parseFloat(strNumbers[i + 1]) - Float.parseFloat(strNumbers[i]);
if (left > 0 && right <= 0)
peaks.add(i);
}
Now you have an array, containing the indices of all peaks. You can find the absolute maximum like this:
float max = 0;
float maxIndex = -1;
for (Integer i : peaks)
{
float peak = Float.parseFloat(strNumbers[i]);
if (peak > max)
{
max = peak;
maxIndex = i;
}
}
And you can find the peak-to-peak distances like this:
int sum = 0;
for (int i = 0; i < peaks.size() - 1; i++)
sum += peaks.get(i + 1) - peaks.get(i);
float average = (float)sum / (peaks.size() - 1)

Finding the closest point

In my program, I am attempting to find the closest point from the starting position (0,0), then "move" again to the next point. The points are read in through a file. The next point I am trying to move to is the "closest" point. I use the Pythagorean Theorem to find the distance. But what can I do to "check" the point I am going to to determine if I have already have visited it. For instance, if the point is 0,0, and then it goes to 1,1, how do check to "tell" the program that 0,0 is no longer an option?
public class PointsNStuff {
public static void main(String [] args) {
final int P = StdIn.readInt();
double [] x = new double[P];
double [] y = new double[P];
double [] visit= new double[P]; //Set an array that stores points that have been visited already
double [] math= new double[P]; //Set an array that stores the distance to all the points
for( int i= 0; i< P; i++){ //Store the values from the text file
x[i] = StdIn.readDouble();
y[i] = StdIn.readDouble();
}
double lowX = x[0];
double lowY = y[0];
double highX = x[0];
double highY = y[0];
//Find the lowest X and the lowest Y values:
for (int i = 0; i < P; i++){
if (lowX > x[i])
lowX = x[i];
}for (int i = 0; i < P; i++){
if (lowY > y[i])
lowY = y[i];
}
for (int i = 0; i < P; i++){
if (highX < x[i])
highX = x[i];
}
for (int i = 0; i < P; i++){
if (highY < y[i])
highY = y[i];
}
System.out.println(lowX + " " + lowY);
System.out.println(highX + " " + highY);
System.out.println("");
System.out.println(P);
//Determine the closest point
double xCoord=0.0;
double yCoord=0.0;
double dist = -1.0;
for (int i= 0; i < P; i ++){ //Repeat entire section for all P (number of points)
for (int j = 0; j < P; j++){ //Find the distance between current point and all other points. Go through all points (do the math).
xCoord = x[j]; // # x point
yCoord = y[j]; // # y point
double save= Math.sqrt( ( (xCoord+x[j]) * (xCoord+x[j]) ) + ( (yCoord + y[j]) * (yCoord + y[j]) ) ); //Pythagorean theorem
save = math[j]; //store the distance in the array slot
}
for (int j = 0; j < P; j++){
if (dist < math[j]){
dist = math[j];
//What boolean check can I put here to double check whether I have visited this point already?
xCoord = x[j]; // set the two points to what number they should be at.
yCoord = y[j];
}
}
System.out.println(xCoord + " " + yCoord);
}
}
}
I have not used any points into the Array I named "visit". Any and all help is appreciated! Thanks!
Use ArrayList to Store points,
ArrayList<Double> x = new ArrayList<Double>();
ArrayList<Double> y = new ArrayList<Double>();
add points to arraylist,
for( int i= 0; i< P; i++){ //Store the values from the text file
x.add(StdIn.readDouble());
y.add(StdIn.readDouble());
}
select point from araylist,
x.get(i); insted of x[i];
y.get(i); insted of y[i];
and remove already used points,
x.remove(new Double(used_x_value));
y.remove(new Double(used_y_value));
see Class ArrayList
What you have here is a perfect candidate for encapsulation! I would start by thinking about another object to encapsulate the 'point' concept you keep referring to:
class Point {
private final double x;
private final double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
}
One minor caveat: this assumes that you will not have duplicate x,y pairs in the input file. If you do, you may need to override hashcode and equals. But if not, this should do it. Then you can put these Points into a data structure ( see HashSet ) like this:
import java.util.Set;
import java.util.HashSet;
public class PointsNStuff {
public static void main(String args[]) {
Set<Point> pointsVisited = new HashSet<>();
//when you visit a point, put it in the set like this
//the numbers are just for example
Point currentPoint = new Point(10.0, 12.0);
pointsVisited.add(currentPoint);
//now in the future you can check if you 'visited' this point
if(!pointsVisited.contains(currentPoint)) {
System.out.println("Haven't been to current point yet...");
}
}
}

QRS Detection in java from ecg byte array

i read ecg byte array from file.now i want to detect QRS of read ecg byte.
how can i acheive this in java.
i get byte array from Lifegain defibrilator(an ecg device).i draw ecg on android from these bytes.now i want to detect QRS complex(term used for calculation of time and voltage of a wave of one heart beat).DATA=LeadData":"-284,-127,-122,17,-35,10,32,10,52,16,49,33,38,69,70,58,45,93,47,88,58,90,149,5,82,-12,-4,40,-34,29,-29,5,-4,-17,-13,-29,-13,-4,-9,-9,-10,-20,-15,-22,-32,-25,-23,-2,-15,-7,-13,-19,-17,-28,-27,-27,-33,-20,-16,-13,-20,-10,-22,-20,-19,-28,-15,-19,-22,-21,-9,-3,-6,-8,-6,-11,-8,-8,-5,-10,-5,-6,-9,-4,-6,3,20,3,14,7,11,10,5,11,5,10,2,10,13,14"
Regards,
shah
If the data you have is the data I think you have, you need to use one of the algorithms to detect your QRS complex.
There are a lot of algorithms out there to detect a QRS complex, one of the easiest is A Moving Average based Filtering System with its Application to Real-time QRS Detection by HC Chen and SW Chen (you can get it on http://www.cinc.org/archives/2003/pdf/585.pdf).
The stages are:
High Pass filtering
Low Pass filtering
Descision making stage
From the low pass picture you can notice that now we have the peaks we need to detect our QRS complex. The last stage is the decision stage making. In the article you have a formula to implement this.
We need to know when a QRS complex starts, so we need to set a threshold for this. The formula in this implementation is:
threshold = alpha * gamma * peak + (1 - alpha) * threshold
The peak is the local maximum in the window (we usually search the signal with a window of width 250), the threshold is the initial value (the first one can be the firstly found peak), alpha and gamma are randomly created, alpha is greater than 0 and smaller than 1 whereas gamma is 0.15 or 0.20. If the value of the current signal exceeds the threshold, a QRS complex is found.
Here is the source code in Java for low pass, high pass and decision making:
// High pass filter
// y1[n] = 1/M * Sum[m=0, M-1] x[n-m]
// y2[n] = x[n - (M+1)/2]
public static float[] highPass(int[] sig0, int nsamp) {
float[] highPass = new float[nsamp];
int M = 5; // M is recommended to be 5 or 7 according to the paper
float constant = (float) 1/M;
for(int i=0; i<sig0.length; i++) {
float y1 = 0;
float y2 = 0;
int y2_index = i-((M+1)/2);
if(y2_index < 0) {
y2_index = nsamp + y2_index;
}
y2 = sig0[y2_index];
float y1_sum = 0;
for(int j=i; j>i-M; j--) {
int x_index = i - (i-j);
if(x_index < 0) {
x_index = nsamp + x_index;
}
y1_sum += sig0[x_index];
}
y1 = constant * y1_sum;
highPass[i] = y2 - y1;
}
return highPass;
}
// Low pass filter; na n-to mesto zapiši kvadrat 30ih števil v oknu
public static float[] lowPass(float[] sig0, int nsamp) {
float[] lowPass = new float[nsamp];
for(int i=0; i<sig0.length; i++) {
float sum = 0;
if(i+30 < sig0.length) {
for(int j=i; j<i+30; j++) {
float current = sig0[j] * sig0[j];
sum += current;
}
}
else if(i+30 >= sig0.length) {
int over = i+30 - sig0.length;
for(int j=i; j<sig0.length; j++) {
float current = sig0[j] * sig0[j];
sum += current;
}
for(int j=0; j<over; j++) {
float current = sig0[j] * sig0[j];
sum += current;
}
}
lowPass[i] = sum;
}
return lowPass;
}
public static int[] QRS(float[] lowPass, int nsamp) {
int[] QRS = new int[nsamp];
double treshold = 0;
for(int i=0; i<200; i++) {
if(lowPass[i] > treshold) {
treshold = lowPass[i];
}
}
int frame = 250;
for(int i=0; i<lowPass.length; i+=frame) {
float max = 0;
int index = 0;
if(i + frame > lowPass.length) {
index = lowPass.length;
}
else {
index = i + frame;
}
for(int j=i; j<index; j++) {
if(lowPass[j] > max) max = lowPass[j];
}
boolean added = false;
for(int j=i; j<index; j++) {
if(lowPass[j] > treshold && !added) {
QRS[j] = 1;
added = true;
}
else {
QRS[j] = 0;
}
}
double gama = (Math.random() > 0.5) ? 0.15 : 0.20;
double alpha = 0.01 + (Math.random() * ((0.1 - 0.01)));
treshold = alpha * gama * max + (1 - alpha) * treshold;
}
return QRS;
}
Please follow the link below , i think they will help you.
http://www.cinc.org/archives/2008/pdf/0441.pdf
http://carg.site.uottawa.ca/doc/ELG6163GeoffreyGreen.pdf
http://www.eplimited.com/osea13.pdf
http://mirel.xmu.edu.cn/mirel/public/Teaching/QRSdetection.pdf
http://sourceforge.net/projects/ecgtoolkit-cs/files/ecgtoolkit-cs/ecgtoolkit-cs-2_2/

Categories

Resources