3D array and the right hand rule
Hello, I'm a novice with respect to scientific computing using python. I've read that numpy.array isn't arranged according to the 'right-hand-rule' (right-hand-rule => thumb = +x; index finger = +y, bend middle finder = +z). This is also confirmed by an old message I dug up from the mailing list archives. (see message below) I guess this has consequences for certain algorithms (been a while, should actually revise some algebra textbooks). At least it does when I try to mentally visualize a 3D array when I'm not sure which dimensions to use... What are the consequences in using 3D arrays in for example transformation algorithms or other algorithms which expect certain shape? Should I always 'reshape' before using them or do most algorithms take this into account in the underlying algebra? Does the 'Fortran contiguous' shape always respect the 'right-hand-rule' (for 3D arrays)? And just to be sure: Is the information telling if an array is C-contiguous or Fortran-contiguous always stored within the array? kind regards, Dieter / Old message From: Anne Archibald <peridot.faceted <at> gmail.com> Subject: Re: dimension aligment <http://news.gmane.org/find-root.php?message_id=ce557a360805201104r3fd2e192ycf7f0c158559b481%40mail.gmail.com> Newsgroups: gmane.comp.python.numeric.general <http://news.gmane.org/gmane.comp.python.numeric.general> Date: 2008-05-20 18:04:46 GMT (6 years, 35 weeks, 5 days, 4 hours and 34 minutes ago) 2008/5/20 Thomas Hrabe <thrabe <at> burnham.org>:
given a *3d* *array* a = numpy.*array*([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]],[[13,14,15],[16,17,18]],[[19,20,21],[22,23,24]]]) a.shape returns (4,2,3)
so I assume the first digit is the 3rd dimension, second is 2nd dim and third is the first.
how is the data aligned in memory now? according to the strides it should be 1,2,3,4,5,6,7,8,9,10,... *right*?
if I had an *array* of more dimensions, the first digit returned by shape should always be the highest dim.
You are basically *right*, but this is a surprisingly subtle issue for numpy. A numpy *array* is basically a block of memory and some description. One piece of that description is the type of data it contains (i.e., how to interpret each chunk of memory) for example int32, float64, etc. Another is the sizes of all the various dimensions. A third piece, which makes many of the things numpy does possible, is the "strides". The way numpy works is that basically it translates A[i,j,k] into a lookup of the item in the memory block at position i*strides[0]+j*strides[1]+k*strides[2] This means, if you have an *array* A and you want every second element (A[::2]), all numpy needs to do is *hand* you back a new *array* pointing to the same data block, but with strides[0] doubled. Similarly if you want to transpose a two-dimensional *array*, all it needs to do is exchange strides[0] and strides[1]; no data need be moved. This means, though, that if you are *hand*ed a numpy *array*, the elements can be arranged in memory in quite a complicated fashion. Sometimes this is no problem - you can always use the strides to find it all. But sometimes you need the data arranged in a particular way. numpy defines two particular ways: "C contiguous" and "FORTRAN contiguous". "C contiguous" *array*s are what you describe, and they're what numpy produces by default; they are arranged so that the *right*most index has the smallest stride. "FORTRAN contiguous" *array*s are arranged the other way around; the leftmost index has the smallest stride. (This is how FORTRAN *array*s are arranged in memory.) There is also a special case: the reshape() function changes the shape of the *array*. It has an "order" argument that describes not how the elements are arranged in memory but how you want to think of the elements as arranged in memory for the reshape operation. Anne /Old message
On Mon, Jan 26, 2015 at 6:06 AM, Dieter Van Eessen < dieter.van.eessen@gmail.com> wrote:
I've read that numpy.array isn't arranged according to the 'right-hand-rule' (right-hand-rule => thumb = +x; index finger = +y, bend middle finder = +z). This is also confirmed by an old message I dug up from the mailing list archives. (see message below)
Dieter, It looks like you are confusing dimensionality of the array with the dimensionality of a vector that it might store. If you are interested in using numpy for 3D modeling, you will likely only encounter 1-dimensional arrays (vectors) of size 3 and 2-dimensional arrays (matrices) of size 9 or shape (3, 3). A 3-dimensional array is a stack of matrices and the 'right-hand-rule' does not really apply. The notion of C/F-contiguous deals with the order of axes (e.g. width first or depth first) while the right-hand-rule is about the direction of the axes (if you "flip" the middle finger right hand becomes left.) In the case of arrays this would probably correspond to little-endian vs. big-endian: is a[0] stored at a higher or lower address than a[1]. However, whatever the answer to this question is for a particular system, it is the same for all axes in the array, so right-hand - left-hand distinction does not apply.
Ok, thanks for the reply! Indeed, I know about the use of transformation matrices to manipulate points in space. That's all matrix manipulation anyway.... But, (and perhaps this is not the right place to ask the following question): But are there no known mathmatical algorithms which involve the use of 3n arrays (or higher dimensions) to transform an object between one state and the other? This is an open question, as my knowledge of math is lacking on this area. I'm currently limited to 3D object manipulation and some statistics which all rely on matrix calculus... kind regards, Dieter On Fri, Jan 30, 2015 at 2:32 AM, Alexander Belopolsky <ndarray@mac.com> wrote:
On Mon, Jan 26, 2015 at 6:06 AM, Dieter Van Eessen < dieter.van.eessen@gmail.com> wrote:
I've read that numpy.array isn't arranged according to the 'right-hand-rule' (right-hand-rule => thumb = +x; index finger = +y, bend middle finder = +z). This is also confirmed by an old message I dug up from the mailing list archives. (see message below)
Dieter,
It looks like you are confusing dimensionality of the array with the dimensionality of a vector that it might store. If you are interested in using numpy for 3D modeling, you will likely only encounter 1-dimensional arrays (vectors) of size 3 and 2-dimensional arrays (matrices) of size 9 or shape (3, 3).
A 3-dimensional array is a stack of matrices and the 'right-hand-rule' does not really apply. The notion of C/F-contiguous deals with the order of axes (e.g. width first or depth first) while the right-hand-rule is about the direction of the axes (if you "flip" the middle finger right hand becomes left.) In the case of arrays this would probably correspond to little-endian vs. big-endian: is a[0] stored at a higher or lower address than a[1]. However, whatever the answer to this question is for a particular system, it is the same for all axes in the array, so right-hand - left-hand distinction does not apply.
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
-- gtz, Dieter VE
participants (2)
-
Alexander Belopolsky
-
Dieter Van Eessen