主要行与主要列的混淆 [英] Row-major vs Column-major confusion

查看:175
本文介绍了主要行与主要列的混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经读了很多关于这一点的文章,读得越多,我就会越困惑.

I've been reading a lot about this, the more I read the more confused I get.

我的理解:在以行为主的行中连续存储在内存中,在以行为主的列中连续存储在内存中.因此,如果我们有一个数字序列[1, ..., 9],并且想要将它们存储在以行为主的矩阵中,我们将得到:

My understanding: In row-major rows are stored contiguously in memory, in column-major columns are stored contiguously in memory. So if we have a sequence of numbers [1, ..., 9] and we want to store them in a row-major matrix, we get:

|1, 2, 3|
|4, 5, 6|
|7, 8, 9|

主要专栏(如果我错了,请纠正我)是:

while the column-major (correct me if I'm wrong) is:

|1, 4, 7|
|2, 5, 8|
|3, 6, 9|

实际上是前一个矩阵的转置.

which is effectively the transpose of the previous matrix.

我的困惑:嗯,我看不出有什么区别.如果我们对两个矩阵进行迭代(第一个矩阵中的行,第二个矩阵中的列),则将以相同的顺序覆盖相同的值:1, 2, 3, ..., 9

My confusion: Well, I don't see any difference. If we iterate on both the matrices (by rows in the first one, and by columns in the second one) we'll cover the same values in the same order: 1, 2, 3, ..., 9

即使矩阵乘法是相同的,我们也将第一个连续元素与第二个矩阵列相乘.假设我们有矩阵M:

Even matrix multiplication is the same, we take the first contiguous elements and multiply them with the second matrix columns. So say we have the matrix M:

|1, 0, 4| 
|5, 2, 7| 
|6, 0, 0|

如果我们将前一个行主要矩阵RM相乘,即R x M,我们将得到:

If we multiply the previous row-major matrix R with M, that is R x M we'll get:

|1*1 + 2*0 + 3*4, 1*5 + 2*2 + 3*7, etc|
|etc.. |
|etc.. |

如果将列主矩阵CM相乘(即C x M),则采用C的列而不是其行,则从R x M

If we multiply the column-major matrix C with M, that is C x M by taking the columns of C instead of its rows, we get exactly the same result from R x M

我真的很困惑,如果一切都一样,为什么这两个词甚至存在?我的意思是即使在第一个矩阵R中,我也可以查看行并将其视为列...

I'm really confused, if everything is the same, why do these two terms even exist? I mean even in the first matrix R, I could look at the rows and consider them columns...

我错过了什么吗? row-major vs col-major实际上对我的矩阵数学意味着什么?我一直在我的线性代数类中学习到,我们将第一个矩阵的行与第二个矩阵的列相乘,如果第一个矩阵的列为大列,这会改变吗?我们现在是否必须像我在示例中所做的那样,将其列与第二个矩阵中的列相乘,还是完全错了?

Am I missing something? What does row-major vs col-major actually imply on my matrix math? I've always learned in my Linear Algebra classes that we multiply rows from the first matrix with columns from the second one, does that change if the first matrix was in column-major? do we now have to multiply its columns with columns from the second matrix like I did in my example or was that just flat out wrong?

任何澄清都非常感谢!

我感到困惑的其他主要原因之一是GLM ...因此,我将鼠标悬停在其矩阵类型上并点击F12以查看其实现方式,在那里我看到了一个矢量数组,所以如果我们有一个3x3矩阵,我们就有3个向量的数组.在查看这些向量的类型时,我看到了"col_type",因此我假设这些向量中的每一个都代表一列,因此我们有一个以列为主的系统吗?

One of the other main sources of confusion I'm having is GLM... So I hover over its matrix type and hit F12 to see how it's implemented, there I see a vector array, so if we have a 3x3 matrix we have an array of 3 vectors. Looking at the type of those vectors I saw 'col_type' so I assumed that each one of those vectors represent a column, and thus we have a column-major system right?

嗯,老实说,我不知道.我编写了此打印函数,以将翻译矩阵与glm进行比较,在最后一行看到glm的翻译矢量,在最后一列看到我的翻译矢量...

Well, I don't know to be honest. I wrote this print function to compare my translation matrix with glm's, I see the translation vector in glm at the last row, and mine is at the last column...

这只会增加混乱.您可以清楚地看到glmTranslate矩阵中的每个向量代表矩阵中的一行.所以...这意味着矩阵是行优先的吗?那我的矩阵呢? (我使用的是float数组[16]),转换值在最后一列中,这是否意味着我的矩阵是以列为主,而我现在不是吗? 尝试阻止头部旋转

This adds nothing but more confusion. You can clearly see that each vector in glmTranslate matrix represents a row in the matrix. So... that means that the matrix is row-major right? What about my matrix? (I'm using a float array[16]) the translation values are in the last column, does that mean my matrix is column-major and I didn't now it? tries to stop head from spinning

推荐答案

让我们先来看代数;代数甚至没有内存布局"和内容的概念.

Let's look at algebra first; algebra doesn't even have a notion of "memory layout" and stuff.

从代数pov看,MxN实矩阵可作用于右侧的| R ^ N向量,并产生| R ^ M向量.

From an algebraic pov, a MxN real matrix can act on a |R^N vector on its right side and yield a |R^M vector.

因此,如果您正在参加考试并获得MxN矩阵和| R ^ N向量,则可以通过简单的运算将它们相乘并得到结果- 该结果是对还是错将不取决于您教授使用的软件来内部检查您的结果是否使用列主布局或行主布局;它仅取决于您是否正确计算了矩阵的每一行与向量的(单)列的收缩率.

Thus, if you were sitting in an exam and given a MxN Matrix and a |R^N vector, you could with trivial operations multiply them and get a result - whether that result is right or wrong will not depend on whether the software your professor uses to check your results internally uses column-major or a row-major layout; it will only depend on if you calculated the contraction of each row of the matrix with the (single) column of the vector properly.

要产生正确的输出,该软件将(无论采取何种方式)实质上必须像在考试中一样,将Matrix的每一行与列向量进行收缩.

To produce a correct output, the software will - by whatever means - essentially have to contract each row of the Matrix with the column vector, just like you did in the exam.

因此,按列优先排列的软件和使用按行优先排列的软件的区别不是它计算的结果,而只是如何.

Thus, the difference between software that aligns column-major and software that uses row-major-layout is not what it calculates, but just how.

更确切地说,关于布局单行与列向量的收缩,这些布局之间的差异只是确定的方式

To put it more pecisely, the difference between those layouts with regard to the topcial single row's contraction with the column vector is just the means to determine

Where is the next element of the current row?

  • 对于行主要布局,它是内存中下一个存储桶中的元素
  • 对于列主要布局,它是M个存储桶中存储桶中的元素.
  • 就这样.

    向您展示如何在实践中召唤该列/行魔术:

    To show you how that column/row magic is summoned in practice:

    您尚未将问题标记为"c ++",而是因为您提到了" glm ",我认为您可以使用C ++.

    You haven't tagged your question with "c++", but because you mentioned 'glm', I assume that you can get along with C++.

    在C ++的标准库中,有一个臭名昭著的野兽,称为 valarray > ,除了其他棘手的功能外,还具有 operator [] ,其中之一可以使用 std::slice (这本质上是非常无聊的事情,仅由三个整数类型的数字组成).

    In C++'s standard library there's an infamous beast called valarray, which, besides other tricky features, has overloads of operator[], one of them can take a std::slice ( which is essentially a very boring thing, consisting of just three integer-type numbers).

    但是,这片小东西可以满足按列访问主要存储或按列访问主要存储的所有内容-它有一个开始,一个长度和一个步幅-后者代表我提到的到下一个存储桶的距离".

    This little slice thing however, has everything one would need to access a row-major-storage column-wise or a column-major-storage row-wise - it has a start, a length, and a stride - the latter represents the "distance to next bucket" I mentioned.

    这篇关于主要行与主要列的混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆