热门标签 | 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



推荐阅读
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了一个适用于PHP应用快速接入TRX和TRC20数字资产的开发包,该开发包支持使用自有Tron区块链节点的应用场景,也支持基于Tron官方公共API服务的轻量级部署场景。提供的功能包括生成地址、验证地址、查询余额、交易转账、查询最新区块和查询交易信息等。详细信息可参考tron-php的Github地址:https://github.com/Fenguoz/tron-php。 ... [详细]
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社区 版权所有