热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

matlab按照列kron,Matlab学习笔记kron函数

函数kron格式Ckron(A,B)%A为mn矩阵,B为pq矩阵,则C为mpnq矩阵。kron即为Kronecker积,所谓Kroneck

函数 kron

格式 C=kron (A,B) %A为m×n矩阵,B为p×q矩阵,则C为mp×nq矩阵。

kron即为Kronecker积,所谓Kronecker积是一种矩阵运算,其定义可以简单描述成:

X与Y的Kronecker积的结果是一个矩阵:

X11*Y X12*Y … X1n*Y

X21*Y X22*Y … X2n*Y

……

Xm1*Y Xm2*Y … Xmn*Y

Matlab中有kron函数用来计算Kronecker积,我看了代码,简短而有效,先列出代码,然后作简要分析。

function K = kron(A,B)

%KRON Kronecker tensor product.

% KRON(X,Y) is the Kronecker tensor product of X and Y.

% The result is a large matrix formed by taking all possible

% products between the elements of X and those of Y. For

% example, if X is 2 by 3, then KRON(X,Y) is

%

% [ X(1,1)*Y X(1,2)*Y X(1,3)*Y

% X(2,1)*Y X(2,2)*Y X(2,3)*Y ]

%

% If either X or Y is sparse, only nonzero elements are multiplied

% in the computation, and the result is sparse.

%

% Class support for inputs X,Y:

% float: double, single

% Previous versions by Paul Fackler, North Carolina State,

% and Jordan Rosenthal, Georgia Tech.

% Copyright 1984-2004 The MathWorks, Inc.

% $Revision: 5.17.4.2 $ $Date: 2004/06/25 18:52:18 $

[ma,na] = size(A);

[mb,nb] = size(B);

if ~issparse(A) && ~issparse(B)

% Both inputs full, result is full.

[ia,ib] = meshgrid(1:ma,1:mb);

[ja,jb] = meshgrid(1:na,1:nb);

K = A(ia,ja).*B(ib,jb);

else

% At least one input is sparse, result is sparse.

[ia,ja,sa] = find(A);

[ib,jb,sb] = find(B);

ia = ia(:); ja = ja(:); sa = sa(:);

ib = ib(:); jb = jb(:); sb = sb(:);

ka = ones(size(sa));

kb = ones(size(sb));

t = mb*(ia-1)';

ik = t(kb,:)+ib(:,ka);

t = nb*(ja-1)';

jk = t(kb,:)+jb(:,ka);

K = sparse(ik,jk,sb*sa.',ma*mb,na*nb);

end

这个函数的主要部分就是由一个if-else组成的。if用来判断两个输入的矩阵中是否有稀疏矩阵,只要有一个是稀疏的,那么就跳转到else部分执行代码。所以else后面的代码都是针对稀疏矩阵的;首先通过size函数取得了A和B的尺寸信息,ma、mb分别代表A和B的行数,na、nb分别代表A和B的列数;然后使用issparse判断矩阵的类型,如果输入的两个矩阵A和B都不是稀疏矩阵,则执行下面的代码,否则执行else后面的代码。 无论是处理full还是sparse,四个变量ma,mb,na,nb都被使用着,它们分别表示矩阵A的行数,矩阵B的行数,矩阵A的列数,矩阵B的列数,也就是矩阵A和B的尺寸信息;

(1)如果都不是稀疏矩阵:

先分析代码的上半部分,即针对full矩阵的运算。首先通过size函数取得了A和B的尺寸信息,ma、mb分别代表A和B的行数,na、nb分别代表A和B的列数;然后使用issparse判断矩阵的类型,如果输入的两个矩阵A和B都不是稀疏矩阵,则执行下面的代码,否则执行else后面的代码。

两次调用meshgrid构造了4个矩阵ia,ib,ja,jb。其中ia是1:ma按行复制,ib是1:mb按列复制,ja是1:na按行复制,jb是1:nb按列复制。构造两个矩阵A(ia,ja)和B(ib,jb),让这两个矩阵对应元素相乘,得到的新矩阵就是A与B的Kronecker积。

对于full矩阵的kronecker积的代码就是这么少,非常简洁,但可能其原理不是那么一目了然。关键就在A(ia,ja)和B(ib,jb)究竟为何物。如果我们将两个数字作为矩阵的下标,将会得到下标对应的矩阵元素,例如A=eye(3);A(2,2)就是1。但是如果以两个向量作为下标对矩阵进行索引,得到的是什么呢?做实验如下:

>> A=magic(5)

A =

17 24 1 8 15

23 5 7 14 16

4 6 13 20 22

10 12 19 21 3

11 18 25 2 9

>> ia=[1 1 2];ja=[1 3 5];

>> A(ia,ja)

ans =

17 1 15

17 1 15

23 7 16

得到了一个新的矩阵。这个新矩阵是这样构建的:

以ia的第一个元素作为行号,以ja中的所有元素作为列号,取出A中的对应元素,将这些元素摆成一行,构成新矩阵的第一行;

以ia的第二个元素作为行号,以ja中的所有元素作为列号,取出A中的对应元素,将这些元素摆成一行,构成新矩阵的第二行;

依此重复,直到ia中所有的元素被取到。

如果ia和ja是矩阵呢?Matlab会将矩阵形式的ia的列首尾相接,使其变成一个向量,ja也是同样处理。

回到程序中,程序用meshgrid构造了四个矩阵ia,ja,ib,jb。它们的内容分别为:

ia: 每一行都是1:ma,一共有mb行;

ja: 每一行都是1:na,一共有nb行;

ib: 每一列都是(1:mb)',一共有ma列;

jb: 每一列都是(1:nb)',一共有na列。

之后就有了A(ia,ja),Matlab将ia的列首尾相接,变成向量,将ja的列首尾相接变成向量,实际上A(ia,ja)就是A(ia(:),ja(:)),用ia(:)和ja(:)作为下标对A进行索引,得到的新矩阵就是:

C1,1 C1,2 … C1,na

C2,1 C2,2 … C2,na

……

Cma,1 Cma,2… Cma,na其中C

i,j是矩阵A

i,j* ones(mb,nb);

用ib(:)和jb(:)作为下标对B进行索引,得到的新矩阵是:

B B … B

B B … B

……

B B … B每一“行”有na个B,每一“列”有ma个B;

A(ia,ja).*B(ib,jb)是两个新矩阵的对应元素乘积,新矩阵中的“一块”可表示如下:

Ci,j.*B

=Ai,j*ones(mb,nb).*B

=Ai,j*B这就是Kronecker积的定义。

(2)稀疏矩阵的Kronecker代码

else中,首先用find函数取得了A和B中非零元素的信息:

ia表示A中非零元素的行号,ja表示A中非零元素的列号,sa表示A中非零元素的取值;ib表示B中非零元素的行号,jb表示B中非零元素的列号,sb表示B中非零元素的取值。然后利用ia=ia(:)这样的方式将这六个变量转化为列向量的形式;

接着用ones构造了两个尺寸分别与sa和sb相同的全1列向量ka和kb; 构造行向量t=mb*(ia-1)'; 用t和ib构造矩阵ik; 构造行向量t=nb*(ja-1)'; 用t和jb构造矩阵jk; 然后把这些东西利用sparse函数构造出了Kronecker积的结果。 如果不说这段代码是干什么的,我肯定会晕头转向。 下面分析一下为什么这就是计算Kronecker积: K=kron(A,B)的结果是: K= A1,1*BA1,2*B…A1,na*B A2,1*BA2,2*B…A2,na*B …… Ama,1*BAma,2*B…Ama,na*B 假设矩阵B中w行v列有一个非零元素b,那么在进行Kronecker积的时候,它会出现在每一个分块Ai,j*B的w行v列,而这样的分块有(ma*mb)*(na*nb)个,于是所有b出现的行号可以表示成w+(i-1)*mb,b出现的列号可以表示成v+(j-1)*nb。 所以,在K中,所有位于[w+(i-1)*mb,v+(j-1)*nb]的元素等于Ai,j*Bw,v; 由于处理的是稀疏矩阵,零元素不会保存于结果之中,因此上式改写成: Kw+(i-1)*mb,v+(j-1)*nb=Ai,j*Bw,v(Ai,j≠0;Bw,v≠0)(1); 这就是程序的思路; 程序按照这个思路做了:构造行向量t=mb*(ia-1)',并将它按行复制,B中有多少非零元素,就将t复制成多少行的矩阵:t(kb,:)。(kb是长度为size(sb)的全1向量); 把B中所有非零元素的行号作为一个列向量,然后按列复制,A中有多少个非零元素,就复制多少列,然后:ik=t(kb,:)+ib(:,ka) 这个操作非常类似meshgrid。回头看一眼式(1),kron积的结果K中非零元素是:Kw+(i-1)*mb,v+(j-1)*nb 非零元素的行号w+(i-1)*mb是B中非零元素的行号w和A中非零元素的行号i的函数,即K中所非零元素的行号是通过二元函数计算出来的,上面类似meshgrid的操作ik=t(kb,:)+ib(:,ka)是典型的计算二元函数的手法; 这样计算出来的ik就包含了K中所有非零元素的行号,非零元素的列号计算与此相同,就不赘述了; 得到了K中所有非零元素的行号和列号,如果再知道它们的值,K就计算出来了。怎样算呢?根据式(1)即可。程序中这样实现: K = sparse(ik,jk,sb*sa.',ma*mb,na*nb); sparse构造矩阵的方式如下: 将矩阵(sb*sa.')的p行q列元素作为K的m行n列的元素,其中m=ikp,q,n=jkp,q; (sb*sa.')p,q为B中第p个非零元素(稀疏矩阵只存放非零元素,这里“第p个”表示将非零元素排成一排,取出第p个,假设该元素行号为w,列号为v)与A中第q个非零元素(假设行号为i,列号为j)的积(Bw,v*Ai,j),而根据ik和jk的构造方式,可以算出ikp,q=w+mb*(i-1),jkp,q=v+nb*(j-1),这个结果符合式(1)的要求,即上述方法正确计算了Kronecker积。

转自:http://blog.sina.com.cn/s/blog_4513dde60100ofoy.html

http://blog.sina.com.cn/s/blog_4513dde60100ofox.html



推荐阅读
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • 本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文介绍了如何利用JavaScript或jQuery来判断网页中的文本框是否处于焦点状态,以及如何检测鼠标是否悬停在指定的HTML元素上。 ... [详细]
  • 导航栏样式练习:项目实例解析
    本文详细介绍了如何创建一个具有动态效果的导航栏,包括HTML、CSS和JavaScript代码的实现,并附有详细的说明和效果图。 ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • ImmutableX Poised to Pioneer Web3 Gaming Revolution
    ImmutableX is set to spearhead the evolution of Web3 gaming, with its innovative technologies and strategic partnerships driving significant advancements in the industry. ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
author-avatar
菲菲不停2502898155
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有