本周文件交换精选

我们最好的用户提交

有效的面向对象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]} views: [1 2 3] numops: 3 eyemask: [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 array with properties: opset: {3×1 cell} views: [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] rangesises: [3 3 9]
s =
81×225 KronProd array with properties: opset: {3×1 cell} views: [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] rangesises: [3 3 9]
v =
225×225 KronProd array with properties: opset: {3×1 cell} views: [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] rangesises: [3 5 15]
马特超负荷了 subsref 所以当你索引到KronProd时,你会得到一个KronProd或者只是一个矩阵。
KKP = kp(1)
kkp =
3×3 KronProd array with properties: opset: {[3×3 double]} views: 1 numops: 1 eyemask: 0 domainset: 3 maxdim: 1 scalarcoeff: 1 scalarcumprods: 1 scalarmask: 0 domainsizes: 3 rangesises: 3
Km = kp{1}
公里= 3×3
8 1 6 3 5 7 4 9 2
他没有超负荷工作 subsasgn 但是,我们不能反其道而行之。
试一试
Kp {1} = rand(3)
ME.message流(2)
结束
无法执行赋值,因为不支持此类型变量的大括号索引。金宝app
他也超负荷了 大小 所以尺寸的外观是完整的克罗内克产品。然而,在引擎盖下 KronProd 实际上是一个标量,它只是 出现 为展开后的尺寸。
Sz =尺寸(s)
深圳= 1×2
81 225
从MATLAB R2021b开始,我们现在有了一个更容易和更正式的方法来控制索引和创建标量对象使用 模块化的索引
现在 subsref 重载()、{}和点(.)。它重载了。,因为它必须用旧的方法,所以我们不需要用新的索引。所以类定义行应该是:
classdefKronProd < matlab.mixin.indexing.RedefinesParen & matlab.mixin.indexing.RedefinesBrace
现在,我们需要实现抽象方法 parenAssign, parenReference, braceAssign, braceReference .这些方法将使用类似于今天所使用的逻辑,在一个受保护的方法块中,大致如下:
函数B = braceReference(obj, indexOp)
inds = m . opinids (indexOp(1). indexes {1});
B = M.opset(第1);
如果isnum(第1)
B = B {:};
结束
结束

评论

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

评论

如欲留言,请点击在这里登录到您的MathWorks帐户或创建一个新帐户。