在Matlab中更快地处理非常大的数据?

时间:2016-09-26 11:24:58

标签: performance matlab file-io vectorization plaintext

我必须使用Matlab处理非常大的数据(点云通常超过30 000 000点)。我可以使用textscan函数读取ascii数据。阅读之后,我需要检测无效数据(带有0,0,0坐标的点),然后我需要对数据中的每个点或每一行进行一些数学运算。以我的方式,首先我用textscan读取数据然后我将这些数据分配给矩阵。其次,我使用for循环来检测无效点并对数据中的每个点或线进行一些数学运算。我的代码示例如下所示。根据Matlab textscan的轮廓工具需要37%和行

transformed_list((i:i),(1:4)) = coordinate_list((i:i),(1:4))*t_matrix; 

占所有计算时间的35%。

我尝试使用另一个点云(存储大约5 500 000)并且配置文件工具报告了相同的结果。有没有办法避免for循环,还是有另一种加速计算的方法?

fileID = fopen('C:\Users\Mustafa\Desktop\ptx_all_data\dede5.ptx');             
original_data = textscan(fileID,'%f %f %f %f %f %f %f', 'delimiter',' ');
fclose(fileID);
column = original_data{1}(1);
row = original_data{1}(2);
t_matrix = [original_data{1}(7) original_data{2}(7) original_data{3}(7) original_data{4}(7)
    original_data{1}(8) original_data{2}(8) original_data{3}(8) original_data{4}(8)
    original_data{1}(9) original_data{2}(9) original_data{3}(9) original_data{4}(9)
    original_data{1}(10) original_data{2}(10) original_data{3}(10) original_data{4}(10)];
coordinate_list(:,1) = original_data{1}(11:length(original_data{1}));
coordinate_list(:,2) = original_data{2}(11:length(original_data{2}));
coordinate_list(:,3) = original_data{3}(11:length(original_data{3}));
coordinate_list(:,4) = 0;
coordinate_list(:,5) = original_data{4}(11:length(original_data{4}));

transformed_list = zeros(length(coordinate_list),5);
for i = 1:length(coordinate_list)
    if coordinate_list(i,1) == 0 && coordinate_list(i,2) == 0 && coordinate_list(i,3) == 0
        transformed_list(i,:) = NaN;
    else
        %transformed_list(i,:) = coordinate_list(i,:)*t_matrix;
        transformed_list((i:i),(1:4)) = coordinate_list((i:i),(1:4))*t_matrix;
        transformed_list(i,5) = coordinate_list(i,5);
    end
    %i
end

提前致谢

2 个答案:

答案 0 :(得分:2)

带有条件语句的

for循环将需要很长时间才能运行。但Matlab缺乏循环速度,它弥补了矢量化和索引。

让我们尝试这样的逻辑索引来解决第一步:

coordinate_list(coordinate_list(:,1) == 0 .* ...
                coordinate_list(:,2) == 0 .* ...
                coordinate_list(:,3) == 0)=nan;

然后对第二个语句进行矢量化:

transformed_list(:,(1:4)) = coordinate_list(:,(1:4))*t_matrix;

正如上面提到的EBH,你的RAM可能有点沉重。如果它超出了你的计算机可以处理的问题,如果坐标真的必须是双倍的,那么单精度就可以了。如果仍然没有做,请尝试切片向量并执行部分操作。

给你一个想法的小例子,因为我周围有一个200万元素点云:

在R2015a

transformed_list = zeros(length(coordinate_list),5);

tic
for i = 1:length(coordinate_list)
    if coordinate_list(i,1) == 0 && coordinate_list(i,2) == 0 && coordinate_list(i,3) == 0
        transformed_list(i,:) = NaN;
    else
        %transformed_list(i,:) = coordinate_list(i,:)*t_matrix;
        transformed_list((i:i),(1:3)) = coordinate_list((i:i),(1:3))*t_matrix;
        transformed_list(i,5) = 1;
    end
    %i
end
toc

返回Elapsed time is 10.928142 seconds.

transformed_list=coordinate_list;
tic 

coordinate_list(coordinate_list(:,1) == 0 .* ...
                coordinate_list(:,2) == 0 .* ...
                coordinate_list(:,3) == 0)=nan;

transformed_list(:,(1:3)) = coordinate_list(:,(1:3))*t_matrix;


toc

返回Elapsed time is 0.101696 seconds.

答案 1 :(得分:-2)

不是阅读整个文件,而是最好使用循环 fscanf(fileID, '%f', 7) 并在阅读时处理输入。