我的代码带有一个调用函数,它给出了系统中每个基因的类型。我可以通过比较每个基因与其子女和父母的顺序来找到它。代码工作正常,有一小部分单元格阵列,但当我将数量增加到数千时,需要几个小时。代码是:
Types=[];
type1=level1_root; % it is fixed value (GO:0008150)
% sample values for p1 and c1 are given below
for k=1:100
type{k}=type_fc(p1,c1,type1); % a function call - see function below
type1=type{k}'; %'
temp1=num2cell(repmat(k+1,length(type1),1));
type1=[type1 temp1];
Types=[Types; type1];
end
% display the output:
Types
子功能:
function type=type_fc(p1,c1,type1)
type=[];
for j=1:length(type1)
for i=1:length(p1)
a=[p1(i),c1(i)];
if isequal(a(1), type1(j))
type=[type a(2)];
end
end
end
对于13个基因,我有这些样本输入:
p1'= %refer to parent genes
'GO:0008150'
'GO:0016740'
'GO:0016787'
'GO:0008150'
'GO:0016740'
'GO:0016740'
'GO:0016787'
'GO:0016787'
'GO:0016787'
'GO:0006810'
'GO:0006412'
'GO:0004672'
c1'= % refer to children genes
'GO:0016740'
'GO:0016787'
'GO:0006810'
'GO:0006412'
'GO:0004672'
'GO:0016779'
'GO:0004386'
'GO:0003774'
'GO:0016298'
'GO:0016192'
'GO:0005215'
'GO:0030533'
结果将是:Types =
'GO:0016740' [2]
'GO:0006412' [2]
'GO:0016787' [3]
'GO:0004672' [3]
'GO:0016779' [3]
'GO:0005215' [3]
'GO:0006810' [4]
'GO:0004386' [4]
'GO:0003774' [4]
'GO:0016298' [4]
'GO:0030533' [4]
'GO:0016192' [5]
您是否知道如何提高此代码的速度?
答案 0 :(得分:7)
乍一看,我可以在您的代码中发现一些问题:
首先,Types
和type
在循环内动态增长。就执行时间而言,这在MATLAB中可能非常昂贵。相反,在循环之前预先分配内存(即,使用预定的最终元素数创建数组),您可能会看到性能的显着提升。
你正在使用循环。如果有一个矢量化解决方案(我还没有检查过),计算时间可能会少得多。
您使用i
和j
索引作为循环迭代器的变量名称。这些变量已经有另一个目的:它们代表虚构单位sqrt(-1)
。 MATLAB仍允许使用i
和j
作为变量名,但为了找出正确的上下文,它所做的变量名称解析确实需要很少的成本。您应该选择其他名称,甚至是ii
和jj
编辑:同样适用于type
,它在MATLAB中已经是reserved function name。
尝试以下优化版本,它应该运行至少一个数量级:
Types = cell(numel(c1), 2); % # Preallocate memory
type1 = level1_root; % # ... or p1{1}
kk = [1, 2]; % # Initialize indices
while ~isempty(type1)
type_fc = cellfun(@(x)c1(strcmp(x, p1)), type1, 'Uniform', false);
type1 = vertcat(type_fc{:});
idx = kk(1):kk(1) + numel(type1) - 1;
Types(idx, 1) = type1;
Types(idx, 2) = {kk(2)};
kk = kk + [numel(type1), 1]; % # Advance indices
end
Types = Types(1:kk(1) - 1, :); % # Remove empty output cells
答案 1 :(得分:2)
如果我正确读取它,那么该函数将类型1中的值与p1中的父基因进行比较,在那里找到匹配,然后从c1返回相应的子基因。这是对的吗?
在这种情况下,矢量化解决方案使用 strcmp 来获取type1(j)和p1之间匹配的逻辑数组。
>> strcmp(type1(j),p1)
然后可以将其用于数组c1上的逻辑寻址,实际上它是来自要提取的c1的值的真值表。我假设你正在处理这些作为单元格数组,在这种情况下我认为这样的东西应该工作。
function type=type_fc(p1,c1,type1)
type={};
for j=1:length(type1)
type=[type{:} c1(strcmp(type1(j),p1))'];
end
现在是否让它更快我不确定,我希望你能测试它。这是我对“矢量化”解决方案的建议。