Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 加速代码以比较结构中的字段_Performance_Matlab_Struct - Fatal编程技术网

Performance 加速代码以比较结构中的字段

Performance 加速代码以比较结构中的字段,performance,matlab,struct,Performance,Matlab,Struct,我有字段uniqueDate、dateAll、label的结构轨迹:我想比较字段uniqueDate和dateAll,如果有对应关系,我会在label中保存另一个结构的值 我编写了以下代码: for k=1:nCols for j=1:size(Trajectories(1,k).dateAll,1) for i=1:size(Trajectories(1,k).uniqueDate,1) if (~isempty(s(1,k).places))&

我有字段uniqueDate、dateAll、label的结构轨迹:我想比较字段uniqueDate和dateAll,如果有对应关系,我会在label中保存另一个结构的值

我编写了以下代码:

for k=1:nCols
    for j=1:size(Trajectories(1,k).dateAll,1)
        for i=1:size(Trajectories(1,k).uniqueDate,1)
            if (~isempty(s(1,k).places))&&(Trajectories(1,k).dateAll(j,1)==Trajectories(1,k).uniqueDate(i,1))&&(Trajectories(1,k).dateAll(j,2)==Trajectories(1,k).uniqueDate(i,2))&&(Trajectories(1,k).dateAll(j,3)==Trajectories(1,k).uniqueDate(i,3))
                for z=1:24
                    if(Trajectories(1,k).dateAll(j,4)==z)&&(size(s(1,k).places.all,2)>=size(Trajectories(1,k).uniqueDate,1))
                        Trajectories(1,k).label(j)=s(1,k).places.all(z,i);
                    else if(Trajectories(1,k).dateAll(j,4)==z)&&(size(s(1,k).places.all,2)<size(Trajectories(1,k).uniqueDate,1))
                            for l=1:size(s(1,k).places.all,2)
                                Trajectories(1,k).label(l)=s(1,k).places.all(z,l);
                            end
                        end
                    end
                end
            end
        end
    end
end

它能跑,但速度很慢。我如何修改它以加快速度?

让我们从内到外工作,看看它能给我们带来什么

步骤1:简化比较条件:

if (~isempty(s(1,k).places))&&(Trajectories(1,k).dateAll(j,1)==Trajectories(1,k).uniqueDate(i,1))&&(Trajectories(1,k).dateAll(j,2)==Trajectories(1,k).uniqueDate(i,2))&&(Trajectories(1,k).dateAll(j,3)==Trajectories(1,k).uniqueDate(i,3))
变成

if (~isempty(s(1,k).places)) && all( Trajectories(1,k).dateAll(j,1:3)==Trajectories(1,k).uniqueDate(i,1:3) )
然后我们要从for循环中删除它。“intersect”函数在这里很有用:

[ia i1 i2]=intersect(Trajectories(1,k).dateAll(:,1:3),Trajectories(1,k).uniqueDate(:,1:3),'rows');
现在我们有了一个向量
i1
,它包含了
dateAll
中与
uniqueDate
相交的所有行

现在,我们可以使用类似的方法删除比较
z
的循环:

[iz iz1 iz2] = intersect(Trajectories(1,k).dateAll(i1,4),1:24);
在这里,我们必须小心我们的索引,使用子集的子集

这将代码简化为:

for k=1:nCols
    if isempty(s(1,k).places)
        continue; % skip to the next value of k, no need to do the rest of the comparison
    end
    [ia i1 i2]=intersect(Trajectories(1,k).dateAll(:,1:3),Trajectories(1,k).uniqueDate(:,1:3),'rows');
    [iz iz1 iz2] = intersect(Trajectories(1,k).dateAll(i1,4),1:24);

    usescalarlabel = (size(s(1,k).places.all,2)>=size(Trajectories(1,k).uniqueDate,1);
    if (usescalarlabel)
        Trajectories(1,k).label(i1(iz1)) = s(1,k).places.all(iz,i2(iz1));
    else
        % you will need to check this: I think here you were needlessly repeating this step for every match
        Trajectories(1,k).label(i1(iz1)) = s(1,k).places.all(iz,:); 
    end
end
但是等等!z循环与使用索引完全相同。所以我们不需要第二个交叉点:

for k=1:nCols
    if isempty(s(1,k).places)
        continue; % skip to the next value of k, no need to do the rest of the comparison
    end
    [ia i1 i2]=intersect(Trajectories(1,k).dateAll(:,1:3),Trajectories(1,k).uniqueDate(:,1:3),'rows');

    usescalarlabel = (size(s(1,k).places.all,2)>=size(Trajectories(1,k).uniqueDate,1);
    label_indices = Trajectories(1,k).dateAll(i1,4);
    if (usescalarlabel)
        Trajectories(1,k).label(label_indices) = s(1,k).places.all(label_indices,i2);
    else
        % you will need to check this: I think here you were needlessly repeating this step for every match
        Trajectories(1,k).label(label_indices) = s(1,k).places.all(label_indices,:);
    end
end
你需要在这里检查索引-我肯定我在没有数据可供测试的地方犯了一个错误,但这应该会让你知道如何继续删除循环并使用向量表达式。没有看到我能优化的数据。如果您可以将数据重新格式化为一组3d矩阵/单元格,而不是使用结构,那么您可能可以更进一步

我怀疑您的情况,我称之为“usescalarlabel”-似乎您混合了两种数据类型。此外,我强烈建议将dateAll矩阵分为单独的“日期”和“数据”矩阵,因为第4行之后的索引似乎不是日期。另外,您复制/粘贴的示例在行索引1处似乎有一个额外的值?在这种情况下,您需要比较
轨迹(1,k).dateAll(:,2:4)
而不是
轨迹(1,k).dateAll(:,1:3)


祝你好运。

Puuh,也许可以给我们一小部分输入数据(如果可能的话,通过MATLAB生成数据,这样我们就可以轻松地自己尝试了)。我的第一个想法是重新思考整个数据布局。也许使用几个单独的矩阵比使用一个大的结构更容易。
for k=1:nCols
    if isempty(s(1,k).places)
        continue; % skip to the next value of k, no need to do the rest of the comparison
    end
    [ia i1 i2]=intersect(Trajectories(1,k).dateAll(:,1:3),Trajectories(1,k).uniqueDate(:,1:3),'rows');

    usescalarlabel = (size(s(1,k).places.all,2)>=size(Trajectories(1,k).uniqueDate,1);
    label_indices = Trajectories(1,k).dateAll(i1,4);
    if (usescalarlabel)
        Trajectories(1,k).label(label_indices) = s(1,k).places.all(label_indices,i2);
    else
        % you will need to check this: I think here you were needlessly repeating this step for every match
        Trajectories(1,k).label(label_indices) = s(1,k).places.all(label_indices,:);
    end
end