How can I pass a MATLAB result s like shown below to a Java method JSize()
s = size(oImage)
s =
91 121 3
First off, you would need to know how many dimensions your array has. Because this looks like an image, I'm going to assume that you'll expect a 3D array.
Because Java considers multidimensional arrays as an array of arrays, it isn't as dynamic as MATLAB where you can simply figure out how many dimensions there are by just checking the length of the size vector.
Assuming that your matrix is not jagged, you can determine how many rows you have by:
int rows = oImage.length;
If you want to determine how many columns there are, you can use any of the rows in your matrix and obtain its length:
int cols = oImage[0].length;
If you want to see how many elements there are in each 2D location in your matrix, you would just access any column in any row you specify and get its length. In our case, let's stick with oImage[0]:
int dim = oImage[0][0].length;
Therefore, you could write a Java method that could return this as an array of elements similar to size in MATLAB:
public int[] JSize(int[][][] oImage) {
return new int[] {oImage.length, oImage[0].length, oImage[0][0].length};
}
Remember, Java has the capacity of declaring jagged multi-dimensional arrays. This means that each row in your 2D matrix does not necessarily have to have the same number of elements like what you would see in a matrix. If you have a multi-dimensional array in Java that follows the above model, then the above code wlll work.
Related
Let's say I have a 100 by 120 matrix, but I want to have a size of 120 by 120 or 100 by 100, is there any way I can transform this matrix?
In Python, I use opencv.resize, because this function can handle arrays directly, but in Android and Java, it seems that you can't handle arrays directly. Cvresize can handle cVARr data, is there any way to convert a two-dimensional array to Cvarr?
Or some other way?
In java, if you want to work with static arrays (fixed size) which normal arrays are, you will need to create a new 2 dimensional array of 120x120 size for example because you can't change the size of a static array. All its elements will be initialized to 0 by default, finally you just need to copy your 100x120 matrix in that array leaving all the untouched elements to 0.
If you are working with dynamic arrays (variable size) which is a variable-size list data structure like ArrayList, you dont need to create a new array beacuse you can manipulate the size of this ArrayList. So you just increase its size or decrease It depending on what dimensions you want.
Context
I am implementing a seam carving algorithm.
I am representing the pixels in a picture as a 1D array
private int[] picture;
Each int represents the RGB of the pixel.
To access the pixels I use helper methods such as:
private int pixelToIndex(int x, int y) {return (y * width()) + x;}
The alternative would be to store in a 2D array:
private int[][] picture;
The seam carving algorithm has two parts.
Firstly, it does some image processing where it finds the horizontal or vertical connected seam with lowest energy. Here the pixel accesses jump around a bit across rows.
Secondly it removes this connected seam.
For vertical seams I mark the pixel to be removed with -1 and create a new picture array skipping the removed pixels like so:
int i = 0, j = 0;
while (i < temp.length) {
if (picture[j] != -1) {
temp[i++] = picture[j];
}
j++;
}
picture = temp;
For horizontal seams, given a specific column I shift all the pixels after the deleted pixel of that column up by one row as so:
for (int i = 0; i < temp.length; i++) {
int row = indexToY(i);
int col = indexToX(i);
int deletedCell = seam[col];
if (row >= deletedCell) temp[i] = picture[i + width()];
else temp[i] = picture[i];
}
picture = temp;
The question
Obviously the 1D array uses less physical memory because of the overhead for each subarray but given the way I am iterating the matrix would the 2D array be more effectively cached by the CPU and thus more efficient?
How would the arrays differ in the way they would be loaded into the CPU cache and RAM? Would part of the 1D array go into the L1-cache? How would the 1D and 2D array be loaded into memory? Would it be dependent on size of the array?
An array of ints is just represented just as that: an array of int values. An array of arrays ... adds certain overhead. So, short answer: when dealing with really large amounts of data; plain 1-dimensional arrays are your friend.
On the other hand: only start optimizing after understanding the bottlenecks. You know, it doesn't help much to optimize your in-memory-datastructure ... when your application spends most of its time waiting for IO for example. And if your attempts to write "high performance" code yield "complicated, hard to read, thus hard to maintain" code ... you might have focused on the wrong area.
Besides: concrete performance numbers are affected by many different variables. So you want to do profiling first; and see what happens with different hardware, different data sets, and so on.
And another side note: sometimes, for the real number crunching; it can also be a viable option to implement something in C++ can make calls via JNI. It really depends on the nature of your problem; how often things will be used; response times expected by users; and so on.
Java has arrays of arrays for multi-dimensional arrays. In your case int[][] is an array of int[] (and of course int[] is an array of int). So, matrix is represented as a set of rows and pointers for each row. In this case it means that NxM matrix is occupying NxM for data and an array of pointers.
Since you can represent any matrix as an array you'll get less memory consumption storing it that way.
On the other hand address manipulation in case representing a 2D matrix as an arary is not that complex.
If we assume that you have a matrix that is NxM accessing and an Array with size NxM representing this matrix, yo can access element of Matrix[x,y] as Array[x*n+y].
Array[i] is compact and it has a high probability of being in L1 cache, or even in register cache.
Matrix[x,y] requires one memory read and addition
Array[x*n+y] requires one multiplication and one addition.
So, I'll put my two cents on Array, but anyway it has to be tested (don't forget to wait for warming time for JIT compiler)
Our homework assignment asks us to use a jagged array to store the values of a two dimensional boolean matrix. Is there a built in java class for the jagged array or am I going to have to manually create it with an Array of ArrayLists?
In Java, a 2D array is an array of 1D array objects. Each 1D array can have different length, which means that you get jagged arrays out of the box.
For example, the following is perfectly valid Java, and prints out 3 5 3 4:
int x[][] = {{0,1,2,3,4},{0,1,2},{0,1,2,3}};
System.out.println(x.length);
System.out.println(x[0].length);
System.out.println(x[1].length);
System.out.println(x[2].length);
It actually sounds like you might want a sparse matrix implementation. You can get much better performance out of it if you are having to modify the matrix. Array copy operations are pretty expensive. Sparse matrices / arrays in Java
I have been looking through the Java Tutorials at the Interfaces tutorial, specifically on Collections (Set, List, Queue, etc.) and I came across the fact that a Set cannot contain duplicates in its elements.
My problem is the fact that I do not fully understand how to create a set of a multi-dimensional array of an unknown size.
In order to fill the multi-dimensional array, I will be placing 1's and 0's inside of an array so that each one will look like the following: (if it fits the criteria I am looking for)
[ 0 1 1 0
0 1 1 0
0 1 0 0
0 1 0 0
0 0 0 0 ]
Or something of that nature. I would like to think this can be accomplished through declaring an multi-dimensional array like:
int[][] array = new int[5][];
Yet I cannot understand how that would work with filling multiple array elements or how to accomplish this with a set.
Please let me know if this is not clear enough.
List's can contain duplicates, sets cannot. You can declare a (dynamic) multidimensional structure in several ways, heres one:
List<List<Integer>> multiDimensional = new ArrayList<List<Integer>>();
List<Integer> row = Arrays.asList({0, 1, 1, 0});
multiDimensional.add(row);
And so on and so forth. To access the elements of the list utilize the get method in a way similar to what you would do with arrays:
Integer someVal = multiDimensional.get(0).get(3);
Having said that, you only need to use this nested List setup if your multidimensional structure needs to be 100% dynamic, aka you need the ability to grow the rows and columns constantly throughout the execution of your logic. You can actually use an ordinary array for your multidimensional structure, assuming that the number of rows can be determined ahead of time, and that each row's length will not change after that row has been initialized. Case in point:
int[][] multiDimensional = null;
int rows = ... ;// Determine number of rows
multiDimensional = new int[rows][];
for(final int[] row: multiDimensional) {
final int cols = ...; // Determine number of cols for this row
row = new int[cols];
}
And you access the elements with your usual array semantics (multiDimensional[0][3]).
How should I go about asking a 2-dimensional array how many rows it has?
Firstly, Java technically doesn't have 2-dimensional arrays: it has arrays of arrays. So in Java you can do this:
String arr[][] = new String[] {
new String[3],
new String[4],
new String[5]
};
The point I want to get across is the above is not rectangular (as a true 2D array would be).
So, your array of arrays, is it by columns then rows or rows then columns? If it is rows then columns then it's easy:
int rows = arr.length;
(from the above example).
If your array is columns then rows then you've got a problem. You can do this:
int rows = arr[0].length;
but this could fail for a number of reasons:
The array must be size 0 in which case you will get an exception; and
You are assuming the length of the first array element is the number of rows. This is not necessarily correct as the example above shows.
Arrays are a crude tool. If you want a true 2D object I strongly suggest you find or write a class that behaves in the correct way.
Object[][] data = ...
System.out.println(data.length); // number of rows
System.out.println(data[0].length); // number of columns in first row
int[][] ia = new int[5][6];
System.out.println(ia.length);
System.out.println(ia[0].length);
It depends what you mean by "how many rows".
For a start, a 2-dimensional array is actually a 1-D array of 1-D arrays in Java. And there is no requirement that a 2-D array is actually rectangular, or even that all elements in the first dimension are populated.
If you want to find the number of elements in the first dimension, the answer is simply array.length.
If you want to find the number of elements in the second dimension of a rectangular 2-D array, the answer is `array[0].length.
If you want to find the number of elements in the second dimension of a non-rectangular or sparse 2-D array, the answer is undefined.