【发布时间】:2016-08-24 06:21:59
【问题描述】:
我希望得到您的建议,以使我的代码更快(更优雅)。特别是,根据 matlab 分析器,sub2ind(和 if 循环)会显着减慢它的速度。我会尽量简单地解释我的代码需要什么。
为简单起见,假设我有以下问题。
每个城市的每个公民都有一辆特定品牌和特定颜色的汽车。
我想要的是一个 4D 多维数组 Data_4D(City,Citizen,Car_brand,Car_color),我可以仅使用这四个维度作为索引来操作(读取和修改)它。
然后,我想用
将我的多维数组重塑为一维数组 Data_1Dlength(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)
之后我会得到这个一维数组,形状如上,我需要创建一个矩阵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 的所有数据都是零,除了一个元素,它必须是具有相同索引 values(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 循环中,只有NRows(City,Citizen,Car_brand,Car_color=2) 中的Data_1D(City,Citizen,Car_brand,Car_color=2) 的元素不为零。
我想知道是否有更快的方法来解决问题,但保持使用四个索引(City、Citizen、Car_brand、Car_color)操作 Data_1D 和 Matrix_Final 的相同能力以及将 NRows 和使用这四个索引的 Data_1D 的元素。
感谢您的帮助!
【问题讨论】:
-
你为什么在那里使用
sub2ind: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;我猜Data_4D(indexes_array_city(city),indexes_array_citizen(citizen),... indexes_array_carbrand(car_brand), indexes_array_carcolor(car_color))=1;会产生完全相同的结果 -
我不明白你创建矩阵
Data_4D的方式,好像你多次将相同的索引覆盖到 1 -
结果不总是眼睛矩阵吗?
-
我认为你的代码没有做你想做的事。对于给定的
(City,Citizen),您可能只想绘制一个Car_Brand和一个Car_Color -
@BillBokeey:感谢您的回答。每个公民都可以拥有多辆不同颜色的汽车(也可以是不同颜色的同一辆车)。
标签: matlab matrix multidimensional-array indexing