Zechariah Schneider - 29 days ago 16
Java Question

# Java Multi-Dimensional Array Indexing

I'm trying to represent an arbitrarily dimensioned matrix in Java as a 1d array and I'm struggling with the implementation the function I'm writing to calculate the correct index in the array given the location in the matrix. Here's what I have so far:

``````private int indexOf(int... indices) {
assert indices.length == rank() :
"Number of indices does not match rank";
if(indices.length == 1) return indices[0];
int x = 0;
for(int i = 1; i < indices.length; ++i){
x += indices[i] % this.dims[i];
}
return x;
}
``````

Where rank() returns the number of dimensions in the matrix and this.dims is an array with the size of each dimension.

I know i=y*numCols + x works for the 2-d version but I'm just having trouble abstracting out to a matrix with variable dimensions.

Thanks for the help.

Sorry, I answer for my own pleasure (in JavaScript - runnable in Chrome Dev tools):

``````function SuperMatrix() {
this.ranks = [].slice.call(arguments);
this.rankCount = this.ranks.length;

this.arraySize =
this.ranks.reduce(function(a,b) { return a*b; }, 1);

this.dimensionSize = [];

this.dimensionSize[this.rankCount-1] = 1;
for (var i = this.rankCount-2; i >= 0; i -= 1) {
this.dimensionSize[i] =
this.dimensionSize[i+1]*this.ranks[i+1];
}

this.array = new Array(this.arraySize);
}

SuperMatrix.prototype._index = function() {

var indexes = [].slice.call(arguments);
if (indexes.length !== this.rankCount)
throw new Error('invalid number of indexes');

var index = 0;
for (var i = 0; i < this.rankCount; i += 1) {
index += indexes[i]*this.dimensionSize[i];
}

if (index < 0 || index >= this.arraySize)
throw new Error('invalid index: ' + indexes.join(', '));

return index;
}

SuperMatrix.prototype.get = function() {
var index = this._index.apply(this, arguments);
return this.array[index];
};

SuperMatrix.prototype.set = function(value) {
var indexes = [].slice.call(arguments, 1);

var index = this._index.apply(this, indexes);
this.array[index] = value;

return value;
};

var foo = new SuperMatrix(2,3,5);

for (var i = 0; i < 2; i+=1) {
for (var j =0; j < 3; j+=1) {
for (var k = 0; k < 5; k+= 1) {
foo.set([i,j,k].join(':'), i,j,k);
}
}
}

for (var i = 0; i < 2; i+=1) {
for (var j =0; j < 3; j+=1) {
for (var k = 0; k < 5; k+= 1) {
console.log(foo.get(i,j,k));
}
}
}

console.log(foo);
``````

For higher dimensional indexes: when index increases by 1 you must move in backing array by size of subarray.

Source (Stackoverflow)