【问题标题】:Reassemble matrix in matlab在matlab中重新组装矩阵
【发布时间】:2017-11-12 17:24:17
【问题描述】:

我在 matlab 中有一个矩阵 x,它有 6*n*n*3 行和一列代表 6*n*n 点的 3d 坐标。坐标排列使得第 1:6*n*n 行是 x 坐标,第 6*n*n+1:12*n*n 行是 y 坐标,第 12*n*n+1:18*n* 行n 是 z 坐标。

我想从中构建 2 个新矩阵,一个将给定点的 x、y、z 坐标简单地放在一起,另一个将 i 行与其他点相减。

现在我正在使用双 for 循环来执行此操作,这对于 n>16 来说非常慢。使用 matlab 向量/矩阵功能是否有更好/更快的方法?

这是我当前的代码

x=x(1:6*n*n);
y=y(6*n*n+1:12*n*n);
z=z(12*n*n+1:18*n*n);
N=6*n*n;
points=[];
difs=[];
for i=1:N
    difrow=[];
    points=[points;x(i) y(i) z(i)];
    for j=1:N
       deltax=x(i)-x(j);
       deltay=y(i)-y(j);
       deltaz=z(i)-z(j);
       difrow=[difrow deltax deltay deltaz];
    end  

    difs=[difs;difrow];
end 

【问题讨论】:

    标签: matlab matrix


    【解决方案1】:

    您可以使用bsxfun、数组整形和连接来避免循环(假设x ,y,z 是大小为[N x 1] 的列向量):

    points = [x y z];
    deltax = bsxfun(@minus,x.' , x);
    deltay = bsxfun(@minus,y.' , y);
    deltaz = bsxfun(@minus,z.' , z);
    difs   = reshape([deltax(:) deltay(:) deltaz(:)].',N*3,[]).';
    

    或者在最新版本的 MATLAB 中,您可以这样做:

    points = [x y z];
    deltax = x.' - x;
    deltay = y.' - y;
    deltaz = z.' - z;
    difs   = reshape([deltax(:) deltay(:) deltaz(:)].',N*3,[]).';
    

    【讨论】:

    • points 需要是 N 行(每个点一个)和 3 列(每个点坐标一个)的矩阵。上面的代码给出了一个 1 行 3*N 列的点矩阵。
    • 我明白了。没有 x,y,z 是每 N 长行。
    • OK 大小为[1 x N]
    【解决方案2】:

    我不知道您的数据是什么样的,但让我们尝试简单的事情,然后我最终会扩展我的答案。

    第一次微优化:始终将中间结果缓存在 Matlab 中,以提高循环时的性能。

    x = x(1:6*n*n);
    y = y(6*n*n+1:12*n*n);
    z = z(12*n*n+1:18*n*n);
    
    points = [];
    difs = [];
    
    for i=1:N
        difrow = [];
    
        x_i = x(i);
        y_i = y(i);
        z_i = z(i);
    
        points = [points; x_i y_i z_i];
    
        for j=1:N
           deltax = x_i - x(j);
           deltay = y_i - y(j);
           deltaz = z_i - z(j);
    
           difrow = [difrow deltax deltay deltaz];
        end  
    
        difs=[difs; difrow];
    end
    

    第二次微优化:预先实例化您的数组以避免内联内存重新分配。

    x = x(1:6*n*n);
    y = y(6*n*n+1:12*n*n);
    z = z(12*n*n+1:18*n*n);
    
    points = NaN(N,1);
    difs = [];
    
    for i=1:N
        x_i = x(i);
        y_i = y(i);
        z_i = z(i);
    
        points(i) = [x_i y_i z_i];
    
        difrow = NaN(N,1);
    
        for j=1:N
           deltax = x_i - x(j);
           deltay = y_i - y(j);
           deltaz = z_i - z(j);
    
           difrow(j) = [deltax deltay deltaz];
        end  
    
        difs = [difs; difrow];
    end
    

    【讨论】:

    • 做了这些。它稍微改善了一点,但对于 n=20 即 2400 点,需要 4 分钟,我需要达到 n=36 左右。
    • 4 分钟对于这么多点来说并不是很长,但是由于我不知道您要做什么以及您的数据是什么样的,因此很难为您开发一个全新的逻辑代码以便以更快的性能获得相同的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-25
    • 1970-01-01
    相关资源
    最近更新 更多