gpt4 book ai didi

c - 行优先与列优先混淆

转载 作者:太空狗 更新时间:2023-10-29 16:33:45 30 4
gpt4 key购买 nike

我读了很多关于这个的书,我读得越多就越困惑。

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

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

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

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

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

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

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

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

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

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

如果我们将列主矩阵 CM 相乘,即 C x MC 的列 而不是它的行,我们从 R x M

得到完全相同的结果

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

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

非常感谢任何澄清!

编辑: 让我感到困惑的另一个主要来源之一是 GLM...所以我将鼠标悬停在它的矩阵类型上并按 F12 以查看它是如何实现的,在那里我看到了一个 vector 数组,所以如果我们有一个 3x3 矩阵,我们就有一个包含 3 个 vector 的数组。查看这些 vector 的类型,我看到了“col_type”,所以我假设这些 vector 中的每一个都代表一列,因此我们有一个列优先系统,对吗?

嗯,老实说我不知道​​。我写了这个打印函数来比较我的翻译矩阵和 glm 的,我在最后一行看到 glm 中的翻译 vector ,而我的在最后一列......

enter image description here

这只会增加困惑。您可以清楚地看到 glmTranslate 矩阵中的每个 vector 代表矩阵中的一行。所以...这意味着矩阵是行优先的,对吗?我的矩阵呢? (我使用的是 float 组[16])翻译值在最后一列,这是否意味着我的矩阵是列优先的,而我现在不是? 试图阻止头部旋转

最佳答案

如果您愿意的话,我认为您混淆了实现细节和用法。

让我们从二维数组或矩阵开始:

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

问题在于计算机内存是一维字节数组。为了使我们的讨论更容易,让我们将单个字节分成四个一组,这样我们有这样的东西,(每个,+-+代表一个字节,四个bytes 表示一个整数值(假设是 32 位操作系统):

   -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
| | | | | | | | |
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
\/ \ /
one byte one integer

low memory ------> high memory

另一种表示方式

所以,问题是如何将二维结构(我们的矩阵)映射到这个一维结构(即内存)上。有两种方法可以做到这一点。

  1. 行优先顺序:按照这个顺序,我们首先将第一行放入内存,然后是第二行,依此类推。这样做,我们将在内存中拥有以下内容:

    -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
    -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

使用此方法,我们可以通过执行以下算术找到数组的给定元素。假设我们要访问数组的 $M_{ij}$ 元素。如果我们假设我们有一个指向数组第一个元素的指针,例如 ptr,并且知道列数 nCol,我们可以通过以下方式找到任何元素:

     $M_{ij} = i*nCol + j$ 

要了解其工作原理,请考虑 M_{02}(即第一行第三列——记住 C 是从零开始的。

      $M_{02} = 0*3 + 2 = 2

所以我们访问数组的第三个元素。

  1. 列优先顺序:按照这个顺序,我们首先将第一列放入内存,然后是第二列,依此类推。这样做我们将在内存中拥有以下内容:

    -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    | 1 | 4 | 7 | 2 | 5 | 8 | 3 | 6 | 9 |
    -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

所以,简短的回答 - 行优先和列优先格式描述了如何将二维(或更高)维数组映射到一维内存数组。

希望这对您有所帮助。

关于c - 行优先与列优先混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33862730/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com