Changing values in an array with unknown dimension

16 views (last 30 days)
I am trying to write a function for n-dimensional kriging, which mean I will have to deal with arrays that vary in dimension depending on the input data. Is there a way to point to a position in this array without knowing its dimension? The array I have contains the coordinaties and has one more dimension than the input data so it can store the coordinates for all the dimensions in one array.
As an example in 2D this array without data will look like:
coords = zeros(length,length,nrdim);
% accessing the different dimensions
xCoords = coords(:,:,1);
yCoords = coords(:,:,2);
Basically what I want to be able to do is fill this array with data no matter what dimension it has, or if any of you have another solution.
Thanks in advance!

Answers (2)

Steven Lord
Steven Lord on 7 Nov 2024 at 15:19
You can use ind2sub as suggested in the answer posted by @Jaynik. But as they wrote that code, they hard-coded the number of dimensions in the array B. I'll show you how we can relax that to get the information at run-time not at write-time.
Sample data
First let's make some data whose dimensionality we don't know when we write the code. This is going to create an array with between 2 and 6 dimensions, each of which is of length between 3 and 7.
numberOfDimensions = randi([2 6])
numberOfDimensions = 3
sizeOfData = randi([3 7], 1, numberOfDimensions)
sizeOfData = 1×3
6 4 7
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
A = rand(sizeOfData);
Linear indexing
Now we could get an arbitrary individual element of A using a linear index.
whichElement = randi(numel(A))
whichElement = 77
xLinear = A(whichElement)
xLinear = 0.6322
Subscripted indexing
But how would we do this with subscripted indexing? I don't know how many dimensions A will have as I type this. But I can get that information using the ndims function.
n = ndims(A);
Comma-separated list
Now that's how many output arguments I should use when I call ind2sub. But how do I dynamically call it with some number of arguments? I can use a comma-separated list created from a cell array.
subscripts = cell(1, n);
[subscripts{:}] = ind2sub(size(A), whichElement) % essentially equivalent to
subscripts = 1x3 cell array
{[5]} {[1]} {[4]}
% [subscripts{1}, subscripts{2}, ...] = ind2sub(...)
I can use that comma-separated list as the set of subscripts in my indexing expression.
xSubscripted = A(subscripts{:})
xSubscripted = 0.6322
Let's check that the two indexing operations gave the same result.
check = isequal(xSubscripted, xLinear)
check = logical
1
Handling of : as an index
For indexing in particular, you can take advantage of something that I think was introduced for object-oriented programming. A ':' index gets all the data in that dimension. For example, to get all the rows in A:
subscripts2 = subscripts; % So you can compare with the original subscripts cell
subscripts2{1} = ':'
subscripts2 = 1x3 cell array
{':'} {[1]} {[4]}
xAllRows = A(subscripts2{:}) % Equivalent to A(:, something, ...)
xAllRows = 6×1
0.6071 0.0290 0.6437 0.8551 0.6322 0.0274
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Note that the only hard-coded numbers in this example occurred in the "Sample data" section (the size inputs to randi and the 1 to make a row vector to use as the size data in the rand call), the 1 in the cell call in the "Comma-separated list" section to make a row vector cell array, and the 1 in the "Handling of : as an index" section (to say I wanted all the data in the first dimension.) Everything else is computed from qualities of the array A.

Jaynik
Jaynik on 7 Nov 2024 at 7:24
Hi Jesper,
You can use the ind2sub function to convert a linear index that is a single number representing the position in a flattened version of the array to subscript indices, that is the position of an element in an array using its row, column and higher dimensions.
The following script is an example where linearIndex 14 gets converted to subscript (2, 2, 2) which can be used to access the element.
dims = [3, 3, 3];
B = rand(dims);
linearIndex = 14;
[sub1, sub2, sub3] = ind2sub(dims, linearIndex);
element = B(sub1, sub2, sub3);
This method can be adapted to your specific needs for n-dimensional kriging.
Please refer to the following documentation to read more about ind2sub: https://www.mathworks.com/help/matlab/ref/ind2sub.html
Hope this helps!

Categories

Find more on Data Types in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!