了解向量乘法

Posted

技术标签:

【中文标题】了解向量乘法【英文标题】:Understanding vector multiplication 【发布时间】:2017-07-03 03:33:18 【问题描述】:

我必须通过在 c++ 中使用向量来执行乘法运算,例如,要将数字 123 和 528 相乘,我必须将每个数字存储在向量中并将它们相乘。我的导师提供了一个乘法算法。以下段落的第一行可能看起来有点混乱,但我想让您知道,我只是在重载 operator* 以使用向量执行两个数字之间的乘法。

ubigint::operator* 中的乘法通过分配一个新向量来进行,该向量的大小等于其他两个操作数的大小之和。如果 u 是大小为 m 的向量,v 是大小为 n 的向量,则以 O(mn) 速度,对一个参数执行外循环,对另一个参数执行内循环,将新的部分乘积添加到乘积 p就像你用手一样。该算法在数学上可以描述如下:

p ←Φ   
for i ∈ [0, m):  
 c ← 0  
   for j ∈ [0, n):  
     d ← p_i+ j + u_iv_j + c  
     p_i+ j ← d % 10  
     c ← ceil(d÷10)  
  p_i+n ← c  

注意区间 [a,b) 指的是集合 x|a ≤ x

问题是我不明白这个算法是如何工作的。例如,什么是 u_iv_j?。有人可以解决这个问题吗?

【问题讨论】:

我相信这意味着u_i × v_j 你可能在很小的时候就被教过这个算法——但是以一种非正式的方式——并且已经使用了数百次。 什么是“向量乘法”?请定义或参考!你所说的与我所知道的两者没有任何共同之处。它们与数字乘法无关。顺便说一句,你把数字和数字混在一起了,你注意到了吗? 【参考方案1】:

将您的算法视为对如何乘以大数的正式描述:

for i ∈ [0, m):                  # For every digit of the first number
   c ← 0                         # Initialize the carry
   for j ∈ [0, n):               # For every digit of the second number
     d ← p_i+j + u_i * v_j + c # Compute the product of the digits + carry + previous result
     p_i+j ← d % 10            # extract the lowest digit and store it
     c ← ceil(d÷10)              # carry the higher digits
 p_i+n ← c                     # In the end, store the carry in the
                                 # highest, not yet used digit

我遗漏了一些细节(操作顺序,...),但如有必要,我可以添加它们。

编辑:为了澄清我的意思,我将展示代码对 56*12 的作用: p 被初始化为 0

i = 0:                       # Calculate 6 * 12
  carry = 0
  j = 0:                     # Calculate 6 * 2
    d = p0 + 6 * 2 + carry # == 0 + 12 + 0
    p0 = d % 10            # == 2
    carry = ceil(d/10)       # == 1
  j = 1:                     # Calculate 6 * 1 + carry
    d = p0 + 6 * 1 + carry # == 0 + 6 + 1
    p1 = d % 10            # == 7
    carry = ceil(d/10)       # == 0
  p2 = carry               # == 0
i = 1:                       # Calculate 5 * 12
  carry = 0
  j = 0:                     # Calculate 5 * 2
    d = p1 + 5 * 2 + carry # == 7 + 10 + 0
    p1 = d % 10            # == 7
    carry = ceil(d/10)       # == 1
  j = 1:                     # Calculate 5 * 1
    d = p2 + 5 * 1 + carry # == 0 + 5 + 1
    p2 = d % 10            # == 6
    carry = ceil(d/10)       # == 0
  p3 = carry               # == 0

对于 i = 0,我们计算出 6 * 12 = 72,对于 i = 1,我们计算出 5 * 12 = 60。

由于5在第二位,我们实际上计算了50 * 12 = 600。现在我们需要将结果相加(即72 + 600),这就是为什么我提到前面的值:第一次运行循环之后, 72 存储在 p 中,要添加 600,我们只需将本地产品 u_i * v_j 添加到 pi+j 中的现有值,同时保留进位。

【讨论】:

之前的结果是什么?

以上是关于了解向量乘法的主要内容,如果未能解决你的问题,请参考以下文章

机器学习-最小二乘法

向量乘法(矩阵乘法)奇数输出的向量

向量矩阵乘法、浮点向量、二进制矩阵

犰狳 vs for 循环向量乘法

犰狳向量矩阵乘法

numpy矩阵向量乘法[重复]