What is the mathematical function that gives the address of an array with more than 3 dimensions?
I already know that for an array a[x][y] with 2 dimensions is (a (x * max_second_dimension + y) * byte)
Given an array a[N1][N2][N3]...[Nk] the address of the element a[i1][i2]...[ik] would be equal to:
a +
+ i1 * (N2 * N3 * ... * Nk) +
+ i2 * (N3 * N4 * ... * Nk) +
+ i3 * (N4 * N5 * ... * Nk) +
...
+ i(k - 1) * Nk +
+ ik
Here what follows i and N are indexes (and so is (k - 1) in i(k - 1).
let dimension of array be lxbxhxg which means array has declared using
data_type array[l][b][h][g];
if you want address of cell at array[x][y][z][a] then it will be
array + (x*b*h*g + y*h*g + z*g + a) * sizeof(array[x][y][z][a])
There is a finite formula for array accessors of arbitrary dimensionality, which I will explain below.
But before, you should know that formal languages usually handle multi dimensional arrays in a grammar rule by accessing the topmost array over an index multiplied by the inner array size - which, in turn, results from a recursion. This may end up in another array, accessed by an index multiplied by the inner array size, with a specific offset and so on, until the accessed element is not an array. You should have a look at (e. g.) ANTLR, if you want to understand how formal languages work.
Of course, you can always find a specific expression, if you know the count of dimensions and the size of each dimension. For example: Let a be the address of the array, s an array of dimension sizes, d the number of dimensions, c an array of indexes (the coordinates in the space described by the array) and e the element size. The address would evaluate in pseudocode to:
a + e * sum(i := 0, d - 1, c[i] * prod(j := i + 1, d - 1, s[j]))
where i, j are loop variables and sum, prod are the big sum/product operator with corresponding lower limit in the first and upper limit in the second parameter. Please note, the empty product operator (last iteration) results to 1. I Haven't tested the above, but the principle should be clear. Sorra, but I don't seem to be able to post formulas in mathematical notation here.
Related
I have a number n that my program uses to represent a list of natural numbers of size n:
[0,1,2] // n=3
[0,1,2,3,4,5] // n=6
The lists always begin with 0 and their elements appear in sequential order with no numbers skipped. The last element is always (n-1).
Now, I need to get the unique pairs of elements for these arrays. So I wrote an algorithm that takes n as an input, and returns an array of unique pairs of elements from its counterpart above.
[[0,1],[0,2],[1,2]] // n=3
[[0,1],[0,2],[0,3],[0,4],[0,5],[1,2],[1,3],[1,4],[1,5],[2,3],[2,4],[2,5],[3,4],[3,5],[4,5]] // n=6
In this implementation, elements cannot pair with themselves (e.g. [0,0]). The pair [1,2] is considered equivalent to [2,1], so only the former would appear.
However, since the pairs have a consistent ordering and follow a basic pattern, I suspect that there is some numeric formula I can use to calculate their values directly—without programmatically creating a list of them.
What I want is a function f(n,i) that would give me the values in the ith pair in the array of pairs for n, for example:
f(3,2) => [1,2]
f(6,8) => [1,5]
Alternatively, it'd be fine to have two functions: One, g(n,i), that returns the first pair-element and another, h(n,i), that returns the second. Like this:
g(3,2) => 1
h(3,2) => 2
g(6,8) => 1
h(6,8) => 5
Is there a formula that can calculate those numbers?
Note: I am not looking for an algorithm to generate the combinations arrays. I have that already. I want to avoid generating array combinations and simply calculate the combination values directly, numerically.
f(n, i):
m = (n - 1) * n / 2 # error check i <= m
i = m - i # zero-based index
t = floor((sqrt(8 * i + 1) - 1) / 2)
r = i - t * (t + 1) / 2
[n - t - 2, n - r - 1]
The trick is to count backward from the end. Otherwise you're basically looking to find the triangular number preceding i and calculating relative to that.
Wikipedia has many properties on triangular roots including the formula used above to derive the triangular root.
Credit to #shawnt00 for the basic idea of inverting the triangular number; I used x = (sqrt(8*i + 1) - 1)//2 as the triangular root, which worked out.
def find(n, i):
m = n * (n - 1) // 2
i = m - i - 1
t = (sqrt(8 * i + 1) - 1)//2
return (n - t - 2, n - 1 - (i - t * (t + 1) // 2))
I have a 221 x 24 cell array, S. Within each array is another array consisting of several different fields (let's just say A, B, C, and D), whereby each field (A, B, C, D) are a 50 x 50 array. I want to sum only the A's, B's, C's, and D's within each column of array S. For example:
S{1,1}.A + S{2,1}.A + ... + S{23,1}.A ...
S{1,2}.B + S{2,2}.B + ... + S{153,2}.B ...
S{111,3}.C + S{117,3}.C + ... + S{230,3}.C ...
What is the simplest way to do this? I know there is a function to sum if there are no fields within the structure (e.g., sum([S{:}]) ), but I only want the specific fields in each summed. Any thoughts?
There is likely more "MATLABy" way of avoiding loops and making this even simpler, but this loop should be reasonably straightforward:
FN = fieldnames(S{1});
for i = 1 : size(S, 1)
sumStruct{i} = 0;
for j = 1 : size(S, 2)
sumStruct{i} = sumStruct{i} + S{i,j}.(FN{j});
end
end
This assumes you want sum of all S{1...N, 1}.A, S{1...N, 2}.B and so on, as it appears in the question. If you want S{1...N, 1}.B too you need 3rd loop and 2 indices for sumStruct - it should be relatively straightforward to implement.
I am looking for the formulas to find the memory location of an element in a 3-D Array for row major and for column major. After using my logic I end up with the following formulas.
say array is A[L][M][N].
row-major:Loc(A[i][j][k])=base+w(M*N(i-x)+N*(j-y)+(k-z))
column-major:Loc(A[i][j][k])=base+w(M*n(i-x)+M*(k-z)+(j-y))
where x, y, z are lower bounds of 1st(L) 2nd(M) and 3rd(N) index.
I tried this formula and got the correct result but when I applied this formula on a Question in the book then the answer did not match. Please can anyone help me out with this.
Formula for 3D Array
Row Major Order:
Address of
A[I, J, K] = B + W * [(D - Do)*RC + (I - Ro)*C + (J - Co)]
Column Major Order:
Address of
A[I, J, K] = B + W * [(D - Do)*RC + (I - Ro) + (J - Co)*R]
Where:
B = Base Address (start address)
W = Weight (storage size of one element stored in the array)
R = Row (total number of rows)
C = Column (total number of columns)
D = Width (total number of cells depth-wise)
Ro = Lower Bound of Row
Co = Lower Bound of Column
Do = Lower Bound of Width
Right one is:
row-major:Loc(A[i][j][k])=base+w(N*(i-x)+(j-y)+M*N(k-z))
column-major:Loc(A[i][j][k])=base+w((i-x)+M*N(k-z)+M*(j-y))
Thanks! #Vinay Yadav for your comment. As suggested by Vinay please visit the link to understand this in great detail: https://eli.thegreenplace.net/2015/memory-layout-of-multi-dimensional-arrays.
Keep this in mind and you never get it wrong:
Row Major: Lexicographical Order
Column Major: Co-lexicographical Order
If you don't know what Co-lexicographical and Lexicographical are: Check out this Wikipedia page for more. Let me highlight important part for you, do give it a read:
The words in a lexicon (the set of words used in some language) have a
conventional ordering, used in dictionaries and encyclopedias, that
depends on the underlying ordering of the alphabet of symbols used to
build the words. The lexicographical order is one way of formalizing
word order given the order of the underlying symbols.
The formal notion starts with a finite set A, often called the
alphabet, which is totally ordered. That is, for any two symbols a and
b in A that are not the same symbol, either a < b or b < a.
The words of A are the finite sequences of symbols from A, including
words of length 1 containing a single symbol, words of length 2 with 2
symbols, and so on, even including the empty sequence varepsilon with no symbols
at all. The lexicographical
order on the set of all these finite words orders the words as
follows:
Given two different words of the same length, say a = a1a2...ak and b
= b1b2...bk, the order of the two words depends on the alphabetic order of the symbols in the first place i where the two words differ
(counting from the beginning of the words): a < b if and only if ai <
bi in the underlying order of the alphabet A. If two words have
different lengths, the usual lexicographical order pads the shorter
one with "blanks" (a special symbol that is treated as smaller than
every element of A) at the end until the words are the same length,
and then the words are compared as in the previous case.
After this you can learn about Co-Lexicographical Order from the same Wikipedia page mentioned above. Above quoted part is taken directly from the Motivation and Definition titled part of the Wikipedia page mentioned above. Visit it once and you will have a better understanding of both.
You just need to find the Lexicographical and Co-Lexicographical position of (i, j, k) among all possible (foo1, foo2, foo3) in the array A of yours:
foo1 -> L possibilities: [Lower Bound x, Upper Bound x + L - 1]
foo2 -> M possibilities: [Lower Bound y, Upper Bound y + M - 1]
foo3 -> N possibilities: [Lower Bound z, Upper Bound z + N - 1]
Based on the this knowledge, you will get that:
1). Number of elements A[foo1][foo2][foo3] (foo1, foo2, foo3) present before element A[i][j][k] (i, j, k) in Row Major Order or Lexicographical Order are:
[ (i - x)*M*N + (j - y)*N + (k - z) ]
2). Number of elements A[foo1][foo2][foo3] (foo1, foo2, foo3) present before element A[i][j][k] (i, j, k) in Column Major Order or Co-lexicographical Order are:
[ (i - x) + (j - y)*L + (k - z)*L*M ]
Now, you can do the rest of your calculation where you bring in your base and W thing to get the final answer you need.
Suppose, I have an n-dimensional array of integers (for n=1 it's a vector, for n=2 it's a rectangular matrix, for n=3 it's a parallelepiped, etc). I need to reorder elements of the array so that elements in each row, column, etc are in a non-decreasing order.
Is it possible for any input array?
Is the required ordering unique for any input array? I just realized that the answer for this question in general is no, e.g. for square matrices.
Is the required ordering unique for any input array that has different lengths in all dimensions?
What is the fastest algorithm to produce the required ordering?
Is it possible for any input array?
Yes, if we will look on the array as a single dimension array, with the same number of elements, and then sort it, by traversing it back to the original n-dimensions array, it remains sorted, since for each i1,....,i_k,...,i_m: for all i_k < i_k':
i_1 + n1*i_2 + n2^2*i_3 + .... (n_k-1)^(k-1)(i_k) + ... < i_1 + n1*i_2 + n2^2*i_3 + .... (n_k-1)^(k-1)(i_k') + ...
Thus (the array is ordered):
arr[i_1 + n1*i_2 + n2^2*i_3 + .... (n_k-1)^(k-1)(i_k) + ...] < arr[ i_1 + n1*i_2 + n2^2*i_3 + .... (n_k-1)^(k-1)(i_k') + ...]
Thus (back to original array):
arr[i_1][i_2]...[i_k]... < arr[i_1][i_2]...[i_k']...
As for the 2nd question:
Is the required ordering unique for any input array that has different
lengths in all dimensions?
No:
1 1 1 3
3 4 1 4
5 6 5 6
What is the fastest algorithm to produce the required ordering?
One solution is suggested already: regard it is a big long array and sort it.
Complexity is O(n_1*n_2*...*n_m*log(n_1*n_2*...*n_m))
My gut says if you could do it faster, you could sory faster then O(nlogn), but I have no proof for this claim, so it might be wrong.
Let me elaborate more about Alptigin Jalayr's idea.
Suppose we have rows sorted, so for the following data, we have a <= b and c <= d.
. .
..., a, ..., b, ...
. .
..., c, ..., d, ...
. .
When a is greater than c, i.e. c <a, then swap of them gives us c < b since a <= b, and a <=d since b <= d (if b > d, we swap b and d as well). In a word, sorting rows first and then columns next can give you the desired matrix.
I am trying to read some Fortran code but there is something I can't understand with array subsets operations like this one
Assume n = 3
And the arrays
INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(12)
REAL(KIND=dp) :: P(n+1),P0(n)
what does this line exactly do?
DO i=1,n-1
…..
P(3:i+2) = P(3:i+2) - i*P0(1:i) / (i+1)
….
END DO
Is it a nested loop? Like j from 3 to i+2 for P and k from 1 to i for P0?
Thanks in advance.
Take the line
P(3:i+2) = P(3:i+2) - i*P0(1:i) / (i+1)
and replace i with 1 (the first value it takes in the do loop)
P(3:3) = P(3:3) - 1*P0(1:1) / 2
On the lhs you have a slice (or section) of array P from element 3 to element 3, so in this case just one element -- but still an array slice not a scalar. This is updated by subtracting 1 times the (same sized) slice of array P0 and divided by 2.
It's a bit more interesting in the next iteration, with i==2 and
P(3:4) = P(3:4) - 2*P0(1:2) / 3
where the array slices are now 2 elements each. The operations on array slices are applied on corresponding elements from each array so this statement is approximately equivalent to the two statements
P(3) = P(3) - 2*P0(1) / 3
P(4) = P(4) - 2*P0(2) / 3
It's better to think of this in Fortran terms, as operations on array sections, than as some kind of syntactic sugar for nested loops.