本周文件交换精选

我们最好的用户提交

高效的面向对象Kronecker产品操作

肖恩 本周的选择是 KronProd 通过 马特·J

背景

这张很老了,对我来说很珍贵。在2009年的某个时候,当我开始读研究生时,我需要帮助计算两个CT图像体之间的亚像素分辨率位移向量。位移矢量计算是我大部分研究生研究的主要基础部分之一。这是之前 imregcorr 虽然它仍然不支持3D,这是我的要求。金宝app
我已经成功制作了2D版本,但还需要3D版本。Matt回复了我的新闻阅读器帖子,讨论了算法和它的3D扩展,并指出这比使用更有效 克隆亚麻 直接。性能很重要,因为在接下来的一年里我必须计算超过40亿个位移向量。
Matt提供了许多算法,并重载了一堆运算符 KronProd 类并使用自定义索引和大小配置它。在2009年,我不明白自定义索引如何 subsref / subsasgn /尺寸 超负荷运转,就像变魔术一样。现在我知道这些算法是如何工作的,以及在那个时代的性能影响,我可能会为了速度而将核心算法引入一个函数,因为我的使用是无状态的,即一个新的 KronProd 每一次。
这里有一些简单的操作 KronProd .我们将从三个数组中创建一个。
kp = KronProd({魔法(3),(randi (10 4 [3]), 0 (3,1)], randn(9日15)})
kp =
81×225 KronProd array with properties: opset: {[3×3 double] [3×5 double] [9×15 double]} opset: [1 2 3] numops: 3 eymask: [0 0 0] domainset: [3 5 15] maxdim: 3 scalarcoeff: 1 scalarcumprods: [1 1 1] scalarmask: [0 0 0] domainsizes: [3 5 15] rangesize: [3 3 9]
现在我们可以用它来工作就像你从 克隆亚麻 函数。
nzeros = nnz (kp)
nzeros = 14580
或者做矩阵运算,得到克朗探针。
[u, s, v] = svd(kp)
u =
81×81 KronProd数组的属性:opset: {3×1 cell} opindes: [1 2 3] numops: 3 eymask: [0 0 0] domainset: [3×1 double] maxdim: 3 scalarcoeff: 1 scalarcumprods: [1 1 1] scalarmask: [0 0 0] domainsizes: [3 3 9] rangesize: [3 3 9]
s =
81×225 KronProd数组的属性:opset: {3×1 cell} opints: [1 2 3] numops: 3 eymask: [0 0 0] domainset: [3×1 double] maxdim: 3 scalarcoeff: 1 scalarcumprods: [1 1 1] scalarmask: [0 0 0] domainsizes: [3 5 15] rangesize: [3 3 9]
v =
225×225 KronProd数组的属性:opset: {3×1 cell} opints: [1 2 3] numops: 3 eymask: [0 0 0] domainset: [3×1 double] maxdim: 3 scalarcoeff: 1 scalarcumprods: [1 1 1] scalarmask: [0 0 0] domainsizes: [3 5 15] rangesize: [3 5 15]
马特已经超载 subsref 所以当你索引到KronProd时,你会得到一个KronProd或者矩阵。
kkp = kp (1)
kkp =
3×3 KronProd数组的属性:opset: {[3×3 double]} opinds: 1 numops: 1 eymask: 0 domainset: 3 maxdim: 1 scalarcoeff: 1 scalarcumprods: 1 scalararmask: 0 domainsizes: 3 rangesize: 3
公里= kp {1}
公里= 3×3
8 1 6 3 5 7 4 9 2
他没有超负荷工作 subsasgn 但是,我们不能反其道而行之。
试一试
kp{1} =兰德(3)
ME.message流(2)
结束
无法执行赋值,因为此类型的变量不支持大括号索引。金宝app
他还超载 大小 所以外观尺寸是完整的克罗内克产品。然而,在引擎盖下 KronProd 是标量吗 出现 为扩展后的大小。
深圳=大小(年代)
深圳= 1×2
81 225
从MATLAB R2021b开始,我们现在有一个更简单和更正式的方法来控制索引和创建标量对象使用 模块化的索引
现在 subsref 重载(),{}和dot(.)。它重载点,因为它与老方法有关,所以新索引不需要这样做。所以类定义行需要是:
classdefKronProd < matlab.mixin.index . redefinesaren & matlab.mixin.index . redefinesbrace
现在,我们需要实现的抽象方法 parenAssign, parenReference, braceAssign, braceReference .这些方法将使用类似于今天使用的逻辑,在protected方法块中,大致如下:
函数B = braceference (obj, indexOp)
(1)第1 = M.opinds (indexOp .Indices {1});
B = M.opset(第1);
如果isnum(第1)
B = B {:};
结束
结束

评论

马特,如果我们在现实生活中见面,我欠你一杯啤酒!
试试吧,让我们知道你的想法 在这里 或者离开 评论 马特。
|
  • 打印
  • 发送电子邮件

评论

要发表评论,请点击此处登录到您的MathWorks帐户或创建一个新帐户。