I am trying to calculate the euclidean distance between 2 values in a 2d array. I need the largest, so I have 2 for loops to travers the arrays, and I also have a maxDistance variable to store the greatest distance as I compare.
My code looks like this
//Returns the largest Euclidean distance between any two cities
within the cities array
public static double furthestDistance(int[][] x)
{
int power;
double sum = 0.0;
int distance = 0;
int maxDistance = 0;
for (int i = 0; i < x.length; i++)
{
for(int j = 0; j<x[0].length; j++)
{
sum = (x[i][j] - x[i][i+1]) + (x[i][j] - x[i][j+1]);
power = (int) Math.pow(sum, 2);
distance = (int)Math.sqrt(power);
if (distance > maxDistance)
{
maxDistance = distance;
}
}
}
return Math.sqrt(sum);
}
I am having issues, getting an error that says my arrayIndex is out of bounds, but I am not sure what the ebst way to travers my array to find the largest distance between any two values in my 2d array of around 10 "x,y coordinates"
x is an array of cities which looks like this
int[][] cities0 = {{22,-45},{-20,-43},{-45,29},{41,35},{21,4},
{23,-37},{16,-19},{-44,-10},{26,15},{6,-30},{2,35},{6,-19}};
I am not sure if I am approaching the problem the right way of if I am even calculating the distance properly?
The Euclidean distance is
public static double calculateDistance(int[] array1, int[] array2)
{
double Sum = 0.0;
for(int i=0;i<array1.length;i++) {
Sum = Sum + Math.pow((array1[i]-array2[i]),2.0);
}
return Math.sqrt(Sum);
}
Now, the thing is that you have an array of points, each point is represented by a two-element array. The index out of bounds error stems from the fact that you have the line of
sum = (x[i][j] - x[i][i+1]) + (x[i][j] - x[i][j+1]);
which assumes that there is a next i and a next j, also, it assumes that the i'th element of x has at least i + 2 elements, which, if i > 0 will crash. Using the method I described at the start of my answer, your solution would look like:
double maxDistance = -1;
int firstPoint = -1;
int secondPoint = -1;
//notice that the limit is x.length - 1, because we will compare the penultimate
//item with the last
for (int i = 0; i < x.length - 1; i++) {
for (int j = i + 1; j < x.length; j ++) {
double d = calculateDistance(x[i], x[j]);
if (d > maxDistance) {
maxDistance = d;
firstPoint = i;
secondPoint = j;
}
}
}
Your Euclidean distance calculation was wrong in the initial code.
Also, the statement x[i][i+1] is problematic because you have tuples as data points and each tuple is in a different row, which means that the
elements in the array can be accessible by either x[i][0]or x[i][1] and any value greater than 1 in the second bracket will cause an IndexOutOfBounds Error.
Modifying the inner loop of the code can help you :
for(int j = i + 1; j<x.length; j++)
{
sum = Math.pow((x[i][0] - x[j][0]), 2) + Math.pow((x[i][1] - x[j][1]), 2);
distance = Math.sqrt(sum);
System.out.println(distance);
if (distance > maxDistance)
{
maxDistance = distance;
}
}
Since we have tuples as our coordinates, x[i][0] - x[j][0] denotes the difference between x-coordinates of the two points and x[i][1] - x[j][1] denotes the difference between y-coordinates. Using that notation, we calculate Euclidean distance. The rest is what you have wrote previously. Also change the variables to double rather than int for more precision in your calculations!
Note: This example is hard-coded for the input you gave in your question, you might need to modify it for using with different arrays.
Related
I am writing a method that finds the largest distance in a consecutive set of prime numbers. For example, if the set is 2,3,5,7,11,13,17,19,23,29; the method would return 6 because the greatest distance within the set is 6 (23-29).
My code so far is:
public static double primeSpace(int n)
{
int i = 0;
int Prime1;
int Prime2;
while (i <= 0)
{
for(; i <= n; i++)
{
if (isPrime(n))
{
Prime1 = n;
}
}
}
}
So as is obvious, I am not sure of how to store a value for prime2 so I can subtract and after that I am lost.
You do not need a double loop, think about the problem, what you are doing is only calculating the differenct between a number and the one after it.
You only need to store one local variable max, assign a new value to max each time the difference is bigger than max.
It is also unclear what your input is, where does the list of primes come from>? Is n the size of the list of primes starting from 2?
I think you want code like this:
List<Integer> primeList = new ArrayList<>();
primeList.add(2);
primeList.add(3);
primeList.add(5);
primeList.add(7);
primeList.add(11);
primeList.add(13);
primeList.add(17);
primeList.add(19);
primeList.add(23);
primeList.add(29);
int distance = 0;
for(int i=1;i <primeList.size();i++) {
int tempDistance = primeList.get(i)-primeList.get(i-1);
if (tempDistance>distance) {
distance = tempDistance;
}
}
System.out.println(distance);
}
I have a double 2d array that is filled with weather data. Each row is formatted in the same way, the first two numbers are the longitude and latitude of a location and the remaining numbers of the row is the actual weather data of that location. How should I go about finding a specific row and copying only the remaining numbers after index 1 of the row into a 1d array (basically ignoring the first two indexes)?
So far I tried:
int x = 0; //index for new 1d array
for(int i = 0; i <= weather.length; i++) {
for(int j = 0; j < weather[i].length; j++) {
//checks if this row's data is for the correct location
if(weather[i][j] == longitude && weather[i+1][j+1] == latitude) {
/* if the current element is the latitude, that means all of the values after the ith
index is the relevant data and can be copied into the new 1d array*/
data[x] = weather[i+1][j+1];
x++;
}
}
}
But this obviously doesn't work. I can't seem to wrap my head around the logic for doing this. I would appreciate any feedback
You access a specific row using the element index:
double[] specificRow = weather[index];
You copy everything after index 1 using something like Arrays.copyOfRange:
double[] copy = Arrays.copyOfRange(specificRow, 2, specificRow.length);
There seem to be several bugs in the implementation:
i <= weather.length - likely to cause ArrayIndexOutOfBoundsException
(weather[i][j] == longitude && weather[i+1][j+1] == latitude) - the data from different rows are compared; also comparing doubles should be implemented with a threshold.
If Arrays.copyOfRange cannot be used due to some reasons, the copy array should be retrieved this way:
// utility method to compare doubles
static boolean doubleEquals(double d1, double d2) {
return Math.abs(d1 - d2) < 1e-10d;
}
double[] row = null;
for (int i = 0; i < weather.length; i++) {
if (doubleEquals(weather[i][0], longitude)
&& doubleEquals(weather[i][1], latitude )) {
row = new double[weather[i].length - 2];
for (int j = 0; j < weather.length; j++) {
row[j] = weather[i][j + 2];
}
// or just row = Arrays.copyOfRange(weather[i], 2, weather[i].length);
break; // row found
}
}
So I have some code which is finding the distance between a series of points. One method uses the euclidean distance and is working fine, the other is using Manhattan and I don't know why it isn't working.
I have it set up so that the distance of the first element in the array list is zero for both methods, and therefore should print that image 1 is a match. However the Manhattan method always returns image 31, no matter how many different elements I test it with. I have double checked the elements in the array list and it should be returning image 1.
Does anybody have any ideas? Thanks in advance
public void matchEuclidean(){
for(int i = 0; i < numberimages; i++){
distanceE[i][0] = weights[i][0] - testweights[0][0];
distanceE[i][1] = weights[i][1] - testweights[0][1];
}
for(int i = 0; i < numberimages; i++){
distanceEu[i] = (Math.pow(distanceE[i][0], 2)) + (Math.pow(distanceE[i][1], 2));
distanceEu[i] = Math.sqrt(distanceEu[i]);
}
for (double no : distanceEu) {
list.add(Double.valueOf(no));
}
double max= Collections.min(list);
double min = list.indexOf(max) + 1;
System.out.println("(euclidean) the unknown image matches image " + (min));
}
public void matchManhattan(){
for(int i = 0; i < numberimages; i++){
distanceM[i][0] = weights[i][0] - testweights[0][0];
distanceM[i][1] = weights[i][1] - testweights[0][1];
}
for(int i = 0; i < numberimages; i++){
distanceMu[i] = distanceM[i][0] + distanceM[i][1];
}
for (double no : distanceMu) {
listM.add(Double.valueOf(no));
}
double max= Collections.min(listM);
double min = listM.indexOf(max) + 1;
System.out.println("(Manhattan) the unknown image matches image " + (min));
}
It looks like you neglected to use the Math.abs function in Manhattan distance:
distanceMu[i] = Math.abs(distanceM[i][0]) + Math.abs(distanceM[i][1]);
Without it, you don't really have a valid "distance" function: you can get negative values, and the triangle inequality does not hold
int a[] = {6,22,33,12,44,9};
int low = a[0];
for(int i = 1 ; i < a.length ; i ++ )
{
if(a[i] < low)
{
low = a[i];
}
}
System.out.println("The smallest number is the given array is : " + low);
}
}
I have 2D array of type doubles as spectral data in text file. I have to find peaks in the spectrum. I am using Binary Search to find peaks in the array, but I am getting false peaks also. How can I filter the result I am getting. If anybody know about this please help me
Here is the code which I am using
static ArrayList < Double > nPeaks(double[] array, int range) {
if (array == null) {
System.out.println("Error");
}
double result = 0, l, r;
double[] peaks = null;
// Check main body
for (int i = 0; i < array.length; i++) {
boolean isPeak = true;
// Check from left to right
l = Math.max(0, i - range);
r = Math.min(array.length - 1, i + range);
for (int j = (int) l; j <= r; j++) {
// Skip if we are on current
if (i == j) {
continue;
}
if (array[i] < array[j]) {
isPeak = false;
break;
}
}
if (isPeak) {
//System.out.println("Peak at " + i + " = " + array[i]);
peaklist.add(array[i]);
result++;
i += range;
}
}
return peaklist;
}
Your question is not clear to me. I assume you are generating the max to min order of input array. If yes, you are trying to create a sorted array(descending order).
Simply sort the array in descending order. That will have result like
peak1, peak2, peak3...peakn
where,
peak1 - is max value
peakn - is min value
One of the way to find peaks in spectrum is calculating the disspersion of whole spectrum and then devile it by 3*sigma and take floor funstion. After it you shold "see" only peaks and each place higher than 1 shold be a peak
In Java, given a 2D array of double values with dim as 6000*6000, is there an efficient way to query the row max and the row sum?
I am using the data structure double[][] and a two-layer loop to get the row max and sum, but it is not sufficiently efficient, as this function is called frequently.
double MinRowMax = Double.POSITIVE_INFINITY;
int num = 6000;
double[][] array2DDist = new double[num][num];
Random rand = new Random();
// initialising the array2DDist
for(int i=0;i<num;++i)
for(int j=0;j<num;++j)
array2DDist[i][j] = rand.nextDouble();
// get the row.max and row.sum
for(int i=0;i<num;++i) {
double maxDist = Double.NEGATIVE_INFINITY;
double sumDist = 0;
for(int j=0;j<num;++j) {
double dist = array2DDist[i][j];
maxDist = Double.max(maxDist, dist);
sumDist+=dist;
}
if(maxDist < MinRowMax) {
MinRowMax = maxDist;
}
}
Is there any Java library that provides more efficient solutions? Is there any Java library that is similar to Matrix class in Python or R?
Thanks!
To compute the sum of an array, or largest value in an array, you have to visit every element of the array. You cannot speed that up.
However, if the array is not going to change, and you are going to need the sum and max for the array multiple times, then you can compute them once and then look them up. There are two approaches:
Compute the required values for all rows of your 2-D array at the start and store them in a lookup table. This is a form or eager cache.
Use (say) a HashMap<Integer, CacheEntry> (where CacheEntry represents the sum and max), and then use this to lazily cache the required values for each row (indexed by the key).
(Or some variation on the implementation of the above.)
Is there any Java library that provides more efficient solutions? Is there any Java library that is similar to Matrix class in Python or R?
Not to my knowledge. Certainly, not in the standard Java class libraries.
However, if you use eager or lazy caching, you should not need a library ... for this problem.
I don't know if more efficient but way shorter using Stream. Here is a demo using 4x4 array :
double MinRowMax = Double.POSITIVE_INFINITY;
int num = 4;
double[][] array2DDist = new double[num][num];
Random rand = new Random();
// initializing the array2DDist
for(int i=0;i<num;++i) {
for(int j=0;j<num;++j) {
array2DDist[i][j] = rand.nextDouble();
}
}
// get the row.max and row.sum
for(int row=0;row<num;++row) {
double maxDist = Double.NEGATIVE_INFINITY;
double sumDist = 0;
for(int col=0;col<num;++col) {
double dist = array2DDist[row][col];
maxDist = Double.max(maxDist, dist);
sumDist+=dist;
}
//System.out.println(Arrays.toString(array2DDist[row]));
System.out.println("row sum - max " + sumDist +" - " + maxDist);
System.out.println("row sum - max " + Arrays.stream(array2DDist[row]).parallel().sum()
+" - " + Arrays.stream(array2DDist[row]).parallel() .max().getAsDouble());
if(maxDist < MinRowMax) {
MinRowMax = maxDist;
}
}
// Programme to get sum of rows value and column values seprately.
int[] colSum =new int[array[0].length];
for (int i = 0; i < array.length; i++){
for (int j = 0; j < array[i].length; j++){
sum += array[i][j];
colSum[j] += array[i][j];
}
System.out.println("Print the sum of rows =" + sum);
}
for(int k=0;k<colSum.length;k++){
System.out.println("Print the sum of columns =" + colSum[k]);
}
// Programme to get maximum in 2D array.
map<int, int> temp;
int currentMax= -999999,maxCount=0;
for(i=0; i< numberOflines ;i++)
{
for(j=0;j< array[i].length;j++)
{
int newCount = ++temp[array[i][j]];
if (maxCount < newCount) {
maxCount = newCount;
currentMax = array[i][j];
}
}
}