1.4 Kronecker积

定义

  矩阵的乘法必须要求左边矩阵的列和右边矩阵的行相等。Kronecker积则没有这个限制,简单地说Kronecker积是把左边矩阵的每一项都乘以右边的矩阵,最终结果是一个放大了的矩阵。Kronecker积的定义,其实更像群和群的乘法(不是群元素的成分),也有点像集合的笛卡尔积。定义如下:
  假如A是 m × n m\times n m×n矩阵,B是 p × q p\times q p×q矩阵,那么Kronecker积定义为:
A ⊗ B = ( A 11 B ⋯ A 1 n B ⋮ ⋱ ⋮ A m 1 B ⋯ A m n B ) A\otimes B=\begin{pmatrix}A_{11}B & \cdots & A_{1n}B\\ \vdots & \ddots & \vdots \\ A_{m1}B & \cdots & A_{mn}B \end{pmatrix} AB= A11BAm1BA1nBAmnB

举例

A = ( 1 3 2 − 1 − 2 1 ) B = ( 4 − 3 6 − 2 − 4 5 ) A ⊗ B = ( 4 − 3 12 − 9 8 − 6 6 − 2 18 − 6 12 − 4 − 4 5 − 12 15 − 8 10 − 4 3 − 8 6 4 − 3 − 5 2 − 12 4 6 − 2 4 − 5 8 − 10 − 4 5 ) A=\begin{pmatrix} 1 & 3 & 2\\ -1 & -2 & 1\end{pmatrix}\\ B=\begin{pmatrix} 4 & -3\\ 6 & -2 \\ -4 & 5\end{pmatrix}\\ A\otimes B=\begin{pmatrix} 4 & -3 & 12 & -9 & 8 & -6 \\ 6 & -2 & 18 & -6 & 12 & -4\\ -4 & 5 & -12 & 15 & -8 & 10\\ -4 & 3 & -8 & 6 & 4 & -3\\ -5 & 2 & -12 & 4 & 6 & -2\\ 4 & -5 & 8 & -10 & -4 & 5\\ \end{pmatrix} A=(113221)B= 464325 AB= 46445432532512181281289615641081284646410325

Python程序

  我的python程序是反过来的,也就是内层数组是列向量,所以这个程序会有点难以理解:

    def kronecker(self, other):
        # 因为采用列向量的形式,所以第一个数组长度才是行数
        # m代表行
        m = len(self.__lines[0])
        # n代表列
        n = len(self.__lines)
        p = len(other.__lines[0])
        q = len(other.__lines)
        result = [[0] * m * p for _ in range(0, n * q)]
        # 总之对左边用除法,对右边用取余
        # i 代表矩阵的列
        for i in range(0, n * q):
            # j 代表矩阵的行
            for j in range(0, m * p):
                x = self.__lines[i // q][j // p]
                y = other.__lines[i % m][j % n]
                result[i][j] = x * y
        return Matrix(result)

  测试代码:

# _*_ coding:utf-8 _*_
import unittest

from com.youngthing.mathalgorithm.matrix import Matrix


class MyTestCase(unittest.TestCase):

    def test(self):
        a = Matrix([[1, 3, 2], [-1, -2, 1]])
        b = Matrix([[4, -3], [6, -2], [-4, 5]])
        print("A=", a.to_latex(), "B= ", b.to_latex(), "A \\otimes B = ", a.kronecker(b).to_latex())


if __name__ == '__main__':
    if __name__ == '__main__':
        unittest.main()

  测试结果:
A = ( 1 − 1 3 − 2 2 1 ) B = ( 4 6 − 4 − 3 − 2 5 ) A ⊗ B = ( 4 6 − 4 − 4 − 6 4 − 3 − 2 5 3 2 − 5 12 18 − 12 − 8 − 12 8 − 9 − 6 15 6 4 − 10 8 12 − 8 4 6 − 4 − 6 − 4 10 − 3 − 2 5 ) A= \begin{pmatrix}1 & -1\\ 3 & -2\\ 2 & 1\\ \end{pmatrix}\\ B= \begin{pmatrix}4 & 6 & -4\\ -3 & -2 & 5\\ \end{pmatrix}\\ A \otimes B = \begin{pmatrix}4 & 6 & -4 & -4 & -6 & 4\\ -3 & -2 & 5 & 3 & 2 & -5\\ 12 & 18 & -12 & -8 & -12 & 8\\ -9 & -6 & 15 & 6 & 4 & -10\\ 8 & 12 & -8 & 4 & 6 & -4\\ -6 & -4 & 10 & -3 & -2 & 5\\ \end{pmatrix}\\ A= 132121 B=(436245)AB= 43129866218612445121581043864362124624581045
  完整代码在GIT里.

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

醒过来摸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值