I'm trying to implement a 3D array in Java but I've a problem, my problem is that I don't know one of the lengths of 3D array size, it means that third length of my 3D is variable and it depends on
the input size. In other words my 3D array called
int arcbits[64][1][length(input)];
first two sizes are fixed, it's always [64][1] and just the third length is variable.
length(input) is always positive integer greater zero.
Input is like this form = {1,0,1,1}, so in this case for instance the arcbits size is:
int arcbits[64][1][4];
How do I implement that in Java? My problem is that there's a variable length which for instance in c++ or c we do dynamic allocation ...because we don't know the size of the array. So do I do 3D array in Java with implicitly variable size?!
I'm stuck on this about two days and I didn't succeed to implement 3D array in Java, this is the first time I counter this, any suggestion to help me out?
int[][][] arcbits = new int[64][1][length(input)];
See https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
see here:
Sum in Java (built in method)'s Implementation?
I already declared 3d array in java, I guess you look on the same concept.
Related
When we create a 2d array such as int[][] a = new int[2][3] why is the resulting 2d array consist of a two-element array that contains three-element int arrays instead of the other way around. The reason why I'm confused is that when we make an array we do datatype[], so when we do int[2][3] why don't we put three int[2] arrays into an array with three spots (from the [3]).
The way it's implemented in Java is more logical. Consider the array element access expression: a[x][y]. Currently, it could be nicely decomposed to (a[x])[y] which means "we get an x-th element of a, then we get a y-th element of the result". So imagine if new int[2][3] produced an array of three elements, each is a two-element array. Then the x should be in range 0..2 and y should be in range 0..1 which is the opposite of the dimension order used at the array creation point. That would be absolutely confusing.
I guess you have a point with your logic. Eventhough you could also argument, writing int[2][3] means "first index can have 2 different values, second 3", what leads to the same as how it really works.
In the end, this is just a matter of specification and compilerbuilding. And since it is specified this way and not that way, it is implemented and works this way.
I know the tittle is not really clear so I am going to do my best to explain the situation here.
I have a Matlab array, say: array = [1,2 ; 3,4]. So basically this is a 4x4 matrix.
I have a java class which goals is to convert matlab matrixes into java arrays. This class has two constructors:
MatlabArray( double[] array );
MatlabArray( double[][] array );
And this class has one member to store the array values:
double[][] values
The class is working perfectly fine with matlab matrices ( both sizes > 1 ), matlab singletons ( 1x1 ) and matlab lines ( 1x2, 1x5 etc ...).
But when it comes to column matrices here comes a downfall, basically a line or a column matrix is still a two dimensional array, it's just that one of its dimension is 1.
When the call to the java constructor is made, the one being called end up being:
MatlabArray( double[] array );
This cause the java arrays to becomes a LINE matrix. Say I had the following Matlab matrix say: array = [1;2;3;4], then the converted java array would be array = {1,2,3,4}
Losing the coherence causes later crashes because the indexes used to access values in the different arrays does not match anymore.
Previously we had a workaround ( people knew when this issue was coming, and they were inverting the indexes ). Workaround which of course I got rid of.
I am looking for ideas to solve this issue in a elegant way, I could specify the dimensions in the constructor but I would rather avoid that.
Thanks for your help
As I know, C++ stores array by putting 2D array values on a block of memory (continuous virtual memory?), which are fast for accessing value by index.
I came out this question after reading this, "using nested array to store 2D grid is efficient in C/C++, but in Java or other memory-managed languages, doing that will actually give you an array of rows where each element is a reference to the array of columns, which may not be as memory-friendly as you'd like".
Does "a reference to the array of columns" mean they actually be stored in many tiny blocks on memory?
Update
Sorry my question should be "If Java store 2D array on many tiny blocks, how is this easy for 'memory-management'"?
In an MxN matrix, it has M references for N arrays. And that is the reason that in C you must tell the second dimension when you want to pass an array as a function argument, and in Java you dont have to.
I am working on a project that involves heuristics, and I built it in Java (Should have probably made it in C).
I am running into problems with memory.
My tree is built up with object nodes, and each object contains an array, a matrix, and three integers.
I already cut down many other values, in order to try and save more memory space, however, it still isn't enough.
So, I was thinking that I could also cut down the matrix, and transform it into an array.
However, my whole project is built on coordinates, to reach a certain point in the matrix.
So before I make any change, I would like to know how much (or not so much) this would affect memory usage.
Edit: The array and matrix both are made of int primitives.
The array is array[25] and the matrix is matrix[5][5].
The matrix represents the board of the game, with information of whether the field is empty, or has a certain type of piece inside it (all int).
I am talking about 16GB of RAM usage, and 25 million nodes.
I made this method, to clone arrays:
public int[] cloneArray(int[] array){
int i = 0;
int[] clone = new int[array.length];
while (i < array.length){
clone[i] = array[i];
i++;
}
return clone;
}
Similar methods were made, to clone matrixes, and the objects themselves.
Edit:
After finding out about the existence of a profiler, I made a check.
Here is a screenshot of the results:
I think these numbers make sense, because in the console, you can see nearly as many nodes that were counted, as you can see in the profiler, the states (in the console, "estados" is the pointer of the state that is currently being expanded).
So, in the profiler, we can see almost 20m states, which are the generated nodes.
Each state contains 1 array and 1 matrix.
We can see 138m arrays, which divided by 6 equals 23m.
And since a matrix is 5x5, then 5x23m of the arrays are contained in the matrix, and the other 23m are the arrays.
Am I making sense? Is this interpretation accurate?
Here is a dropbox link, so you can check the full resolution image:
https://www.dropbox.com/s/7wxz8vch1wnrsyr/Untitled.png?dl=0
Here are a couple of examples:
int[] array = new int[25];
int[][] matrix = new int[5][5];
The space occupied by the array is:
25 x 4 byte ints (the array contents)
12 bytes of object header for the array
total 112 bytes
A 2D int matrix in Java is actually an array of arrays, so the space occupied by the matrix is
(5 x 4 byte ints + 12 bytes of array header) x 5.
5 x 4 byte references + 12 bytes of array header
total 192 bytes
(The above assumes a 32 bit JVM, and typical array header sizes. Those are platform specific assumptions, but for any JVM platform you should be able to tie them down with specificity. And for Oracle HotSpot / OpenJDK JVMs since Java 6, the source code is available for anyone to see.)
Note of course that as the arrays / matrices get larger, the relative saving for an int[N^2] versus an int[N][N] becomes smaller.
Your question may suggest hidden problem in your code rather then "out of memory problem". the heap memory is not finish so fast , you need your code to be extremely heavy in order to get there.
still, I'll dare to say that changing 2 dimensional matrix into an array wouldn't change the memory usage much.
speaking on which - the 2 most common ways to implement higher-dimensions arrays (2 and above) are 1) slice it to one dimension array, then use the formula :
arr[a][b].. = arr[a+b+..]
2) use pointers to pointers , then you get an array of pointers , which points to another array of pointers and so on until the final level which are real objects
this said , (again , with dare) , Java may already slice the matrix into one dimension array behind the scenes.
any way , I highly suspect you have memory leak in your code , or not-ending-recursion, or a combination of the above . try to see you're not there before trying to implement what you suggested.
I have the problem that I want to do parallelization with Android Renderscript. For this I have to allocate my input data to renderscript and allocate them back. I want to do big matrix multiplications with the size of 8x8 or 64x64 matrices. There are two problems:
1) I cannot allocate two dimensional arrays.
2) forEach executes the loop as often as the size of the allocation. E.g. The input vector has 10 elements the loop will be executed 10 times.
To find a solution I did coding. So my matrix is generated randomly in a byte array. This byte array will be coded row or column to an integer array. So I put a 2d array in a one dimensional array with the size of the length. On the other side (Renderscript) I have to decode them, calculating the result and put the back with the allocation. I want to avoid the coding and to speed up the application. Someone know a better solution for my problem?
array[a][b] --> vector[a] or vector[b] but not vector[a*b] Exist there a possible solution?
I'm not sure that I fully understand your problem.
Let me try to make a general suggestion based on what I understand.
You can create a wrapper class that transform input index to the internal index via getters and setters, this wrapper can also implement java.lang.Iterable.
To help with the second part of your problem, bind the matrix Allocations to the Renderscript separately and pass rsForEach another Allocation that is sized to the number of operations you want to perform. You can use values set in this Allocation and/or the x argument of the root() function to help you find where to operate on the matrix data.
My answer for operating per row/column of an image gives more details.