我希望您的建议能让我的代码更快(更优雅)。特别是,sub2ind(和if-loop)根据matlab分析器显着减慢了速度。我将尝试尽可能简单地从代码中解释我的需求。
假设我有以下问题,为简单起见。
每个城市的每个公民都有一辆特定品牌和特定颜色的汽车。
我想要的是一个4D多维数组Data_4D(City,Citizen,Car_brand,Car_color)
,我只能使用这四个维度作为索引来操作(读取和修改)。
然后,我想将我的多维数组重塑为一维数组Data_1D with
length(Data_1D)=(City*Citizen*Car_brand*Car_color)
元素的顺序必须遵循索引规则:
假设City=2, Citizen=2, Car_brand=2, Car_color=2
;
Data_1D(1)=Data_4D(1,1,1,1)
Data_1D(2)=Data_4D(1,1,1,2)
Data_1D(3)=Data_4D(1,1,2,1)
Data_1D(4)=Data_4D(1,1,2,2)
Data_1D(5)=Data_4D(1,2,1,1)
Data_1D(6)=Data_4D(1,2,1,2)
Data_1D(7)=Data_4D(1,2,2,1)
Data_1D(8)=Data_4D(1,2,2,2)
Data_1D(9)=Data_4D(2,1,1,1)
Data_1D(10)=Data_4D(2,1,1,2)
Data_1D(11)=Data_4D(2,1,2,1)
Data_1D(12)=Data_4D(2,1,2,2)
Data_1D(13)=Data_4D(2,2,1,1)
Data_1D(14)=Data_4D(2,2,1,2)
Data_1D(15)=Data_4D(2,2,2,1)
Data_1D(16)=Data_4D(2,2,2,2)
之后我会得到这个1D数组,形状如上,我需要创建一个矩阵Matrix_Final( NRows,length(Data_1D))
,其中每一行都是一个数组Data_1D。在每行NRows中,数组Data_1D将具有相同数量的元素但具有不同的值
行数还取决于四个维度City,Citizen,Car_brand,Car_color中的一些(或全部)(遵循与Data_1D相同的索引规则),并且每行中构建的数组也必须根据值的大小进行操作。矩阵行(通过使用四个索引,这是NRows和Data_1D的通用规则)。
实施例:
假设City=2, Citizen=2, Car_brand=2, Car_color=2
;
假设 NRows取决于所有四个维度。
我会Matrix_Final( length(DATA_1D), length(DATA_1D))
。
我希望我的数组DATA_1D的所有数据都是零,除了一个元素,它必须是与(City,Citizen,Car_brand,Car_color)
具有相同索引值NRows(City,Citizen,Car_brand,Car_color)
的元素。
因此,在NRows(1)
行,只有Data_1D(1)
非零。对于此示例,结果是眼睛矩阵。
clc
clear all
%Dimensions Definition
City=2;
Citizen=2;
Car_brand=2;
Car_color=2;
%Length of Data
Length_Data_1D=City*Citizen*Car_brand*Car_color;
%preallocation Matrix_Final
Matrix_Final=zeros(City*Citizen*Car_brand*Car_color, Length_Data_1D);
%indexes of the dimensions
indexes_array_carcolor=repmat(repelem([1:Car_color], 1), [1 City*Citizen*Car_brand]);
indexes_array_carbrand=repmat(repelem([1:Car_brand], Car_color), [1 City*Citizen]);
indexes_array_citizen=repmat(repelem([1:Citizen],Car_brand*Car_color),[1 City]);
indexes_array_city=repmat(repelem([1:City],Citizen*Car_brand*Car_color),[1 1]);
%Initializing loop variable
column_Matrix_final=1;
for CITY_selected=1:City
for CITIZEN_selected=1:Citizen
for CAR_BRAND_selected=1:Car_brand
for CAR_COLOR_selected=1:Car_color
%Data_4D Construction
Data_4D=zeros(City,Citizen,Car_brand,Car_color);
for city=1:length(indexes_array_city)
for citizen=1:length(indexes_array_citizen)
for car_brand=1:length(indexes_array_carbrand)
for car_color=1:length(indexes_array_carcolor)
if (indexes_array_city(city)==CITY_selected && indexes_array_citizen(citizen)==CITIZEN_selected ...
&& indexes_array_carbrand(car_brand)==CAR_BRAND_selected && ...
indexes_array_carcolor(car_color)==CAR_COLOR_selected)
Data_4D(sub2ind(size(Data_4D),indexes_array_city(city),indexes_array_citizen(citizen),...
indexes_array_carbrand(car_brand), indexes_array_carcolor(car_color)))=1;
end
end
end
end
end
%Data_4D transformation into array Data_1D
Data_1D=zeros(1,City*Citizen*Car_brand*Car_color);
tic=1;
for city=1:City
for citizen=1:Citizen
for car_brand=1:Car_brand
for car_color=1:Car_color
Data_1D(tic)=Data_4D(city,citizen,car_brand,car_color);
tic=tic+1;
end
end
end
end
%Adding Data_1D to the next for of Matrix_Final
Matrix_Final(column_Matrix_final,:)=Data_1D;
column_Matrix_final=column_Matrix_final+1;
%Display of the four most external loops indexes to show code
%advancement
CAR_COLOR_selected
end
CAR_BRAND_selected
end
CITIZEN_selected
end
CITY_selected
end
spy(Matrix_Final)
如果你添加例如
&& indexes_array_carcolor(car_color)==2
在if循环中,只有Data_1D(City,Citizen,Car_brand,Car_color=2)
中NRows(City,Citizen,Car_brand,Car_color=2)
的元素将为非零。
我想知道是否有更快的方法来设置问题,但保持使用四个索引(City,Citizen,Car_brand,Car_color)操作Data_1D和Matrix_Final的相同能力以及关联NRows和Data_1D的元素使用这四个索引。
感谢您的帮助!
答案 0 :(得分:0)
这就是你编码的方式
if (indexes_array_city(city)==CITY_selected && indexes_array_citizen(citizen)==CITIZEN_selected ...
&& indexes_array_carbrand(car_brand)==CAR_BRAND_selected && ...
indexes_array_carcolor(car_color)==CAR_COLOR_selected)
Data_4D(sub2ind(size(Data_4D),indexes_array_city(city),indexes_array_citizen(citizen),...
indexes_array_carbrand(car_brand), indexes_array_carcolor(car_color)))=1;
end
另一种方式1
if (indexes_array_city(city)==CITY_selected && indexes_array_citizen(citizen)==CITIZEN_selected ...
&& indexes_array_carbrand(car_brand)==CAR_BRAND_selected && ...
indexes_array_carcolor(car_color)==CAR_COLOR_selected)
Data_4D(indexes_array_city(city),indexes_array_citizen(citizen),...
indexes_array_carbrand(car_brand), indexes_array_carcolor(car_color))=1;
end
另一种方式2
Data_4D(indexes_array_city(city),indexes_array_citizen(citizen),...
indexes_array_carbrand(car_brand), indexes_array_carcolor(car_color))=double((indexes_array_city(city)==CITY_selected)& ...
(indexes_array_citizen(citizen)==CITIZEN_selected)& ...
(indexes_array_carbrand(car_brand)==CAR_BRAND_selected)& ...
(indexes_array_carcolor(car_color)==CAR_COLOR_selected));
所有这三个都会产生相同的结果。尝试哪个更快并使用它。
%% Data_4D transformation into array Data_1D
Data_4D_size=size(Data_4D);
Data_1D_size=prod(Data_4D_size);
temp = permute(Data_4D, [4 3 2 1]);
Data_1D=reshape(temp,Data_1D_size,1);
将此用于4D到1D转换
如果还需要更快的速度。将其编译为mex。编译的代码运行得更快。