优化“遮罩"结构. Matlab中的函数 [英] Optimize a "mask" function in Matlab

查看:96
本文介绍了优化“遮罩"结构. Matlab中的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了进行基准比较,我考虑简单的功能:

 function dealiasing2d(where_dealiased, data)
[n1, n0, nk] = size(data);
for i0=1:n0 
    for i1=1:n1
        if where_dealiased(i1, i0)
            data(i1, i0, :) = 0.;
        end
    end
end
 

在伪光谱模拟(其中data是复数的3d数组)中可能很有用,但基本上它将掩码应用于一组图像,将某些where_dealiased为真的元素置零.

在这种简单情况下,我比较了不同语言(以及实现,编译器等)的性能.对于Matlab,我使用 timeit 对函数计时.由于我不想在Matlab中测试我的无知,因此我想用这种语言真正优化此功能.在Matlab中最快的方法是什么?

我现在使用的简单解决方案是:

 function dealiasing2d(where_dealiased, data)
[n1, n0, nk] = size(data);
N = n0*n1;
ind_zeros = find(reshape(where_dealiased, 1, []));
for ik=1:nk
    data(ind_zeros + N*(ik-1)) = 0;
end
 

我怀疑这不是正确的方法,因为等效的Numpy解决方案的速度大约快10倍.

 import numpy as np

def dealiasing(where, data):
    nk = data.shape[0]
    N = reduce(lambda x, y: x*y, data.shape[1:])
    inds, = np.nonzero(where.flat)
    for ik in xrange(nk):
        data.flat[inds + N*ik] = 0.
 

最后,如果有人告诉我诸如当您想快速使用Matlab中的特定功能时,应该像这样编译它:[...]",我将在基准测试中包括这样的解决方案. /p>


在给出2个答案之后,我已经对这些命题进行了基准测试,并且似乎并没有明显的性能改进.这很奇怪,因为简单的Python-Numpy解决方案的速度实际上快了一个数量级,因此我仍在寻找Matlab更好的解决方案...

解决方案

如果我正确理解,可以使用线性索引的解决方案可能非常快也.为了节省时间,您可以删除reshape,因为find已经返回线性索引:

ind_zeros = find(where_dealiased);

For a benchmark comparison, I consider the simple function:

function dealiasing2d(where_dealiased, data)
[n1, n0, nk] = size(data);
for i0=1:n0 
    for i1=1:n1
        if where_dealiased(i1, i0)
            data(i1, i0, :) = 0.;
        end
    end
end

It can be useful in pseudo-spectral simulations (where data is a 3d array of complex numbers) but basically it applies a mask to a set of images, putting to zeros some elements for which where_dealiased is true.

I compare the performance of different languages (and implementations, compilers, ...) on this simple case. For Matlab, I time the function with timeit. Since I don't want to benchmark my ignorance in Matlab, I would like to really optimize this function with this language. What would be the fastest way to do this in Matlab?

The simple solution I use now is:

function dealiasing2d(where_dealiased, data)
[n1, n0, nk] = size(data);
N = n0*n1;
ind_zeros = find(reshape(where_dealiased, 1, []));
for ik=1:nk
    data(ind_zeros + N*(ik-1)) = 0;
end

I suspect this is not the right way to do it since the equivalent Numpy solution is approximately 10 times faster.

import numpy as np

def dealiasing(where, data):
    nk = data.shape[0]
    N = reduce(lambda x, y: x*y, data.shape[1:])
    inds, = np.nonzero(where.flat)
    for ik in xrange(nk):
        data.flat[inds + N*ik] = 0.

Finally, if someone tells me something like "When you want to be very fast with a particular function in Matlab, you should compile it like that: [...]", I would include such solution in the benchmark.


Edit:

After 2 answers, I've benchmarked the propositions and it seems that there is no noticeable performance improvement. This is strange since the simple Python-Numpy solution is really (one order of magnitude) much faster so I am still looking for a better solution with Matlab...

解决方案

If I understand correctly, this can be done easily and quickly with bsxfun:

data = bsxfun(@times, data, ~where_dealiased);

This sets to 0 all third-dimension-components of the entries for which where_dealiased is true (it multiplies them by 0), and leaves the rest as they were (it multiplies them by 1).

Of course, this assumes [size(data,1) size(data,2]==size(where_dealiased).


Your solution with linear indexing is probably very fast too. To save some time there, you can remove the reshape, because find already returns linear indices:

ind_zeros = find(where_dealiased);

这篇关于优化“遮罩"结构. Matlab中的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆