我希望将列插入矩阵,但矩阵内的插入列位置因行而异。如何在不使用for循环的情况下执行此操作?
以下是MATLAB中的简化示例; 从A,X,P,我想在不使用for循环的情况下获得APX。
public class DisplayAttributeBasedObjectDataProvider : ObjectDataProvider
{
public object GetEnumValues(Enum enumObj)
{
var attribute = enumObj.GetType().GetRuntimeField(enumObj.ToString()).
GetCustomAttributes(typeof(DisplayAttribute), false).
SingleOrDefault() as DisplayAttribute;
return attribute == null ? enumObj.ToString() : attribute.Description;
}
public List<object> GetShortListOfApplicationGestures(Type type)
{
var shortListOfApplicationGestures = Enum.GetValues(type).OfType<Enum>().Select(GetEnumValues).ToList();
return
shortListOfApplicationGestures;
}
}
答案 0 :(得分:6)
它只是确定正确的列主要索引来访问矩阵,因此您可以使用所需的值填充它。首先需要生成正确的行和列值才能访问APX
中的正确位置,以便您可以使用X
填充这些位置。
使用P
,每个元素都会告诉您应该为X
的每一行开始填充哪一列。您需要按递增顺序生成列索引,最多可生成X
中的列数。要生成行索引,只需创建一个与X
大小相同的矩阵,其中每列的行数从0到最多X
减去1(即0:size(X,2)-1
)。此矩阵为您提供正确的偏移量,以便您可以使用P
并使用此矩阵添加它。一旦你这样做,你将有一个列索引矩阵,告诉你每个元素应该与每行P
的输出矩阵的列有关。最后,使用sub2ind
生成列主要索引,使用上面生成的行和列将X
放在APX
中。
换句话说:
P = [3;2;4;1];
X = [9,8;5,7;8,3;6,7];
rowInd = repmat((1:size(X,1)).', 1, size(X,2)); %'
colInd = bsxfun(@plus, P, 0:size(X,2)-1);
APX = zeros(size(X,1), max(colInd(:)));
APX(sub2ind(size(APX), rowInd, colInd)) = X;
要生成行位置,我们使用repmat
创建一个与X
大小相同的矩阵,其中每列的行数从1到最多X
。要生成列位置,我们使用bsxfun
创建一个矩阵,其中每列是向量P
,但每列增加1。然后,我们将APX
创建为兼容大小,然后使用sub2ind
最终填充矩阵。
通过上述测试输入,我们得到:
APX =
0 0 9 8 0
0 5 7 0 0
0 0 0 8 3
6 7 0 0 0
在尝试向量化之前,你真的应该尝试使用循环。虽然在以前版本的MATLAB中使用循环很慢,但MATLAB R2015b有一个改进的JIT引擎,其中循环现在具有竞争力。您应该使用循环对代码进行计时,并确保在切换到矢量化实现之前它是合理的。