Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.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
MATLAB中单元阵列的极小值_Matlab - Fatal编程技术网

MATLAB中单元阵列的极小值

MATLAB中单元阵列的极小值,matlab,Matlab,我在MATLAB中有一个单元格数组,其中包含一些按大小降序排列的矩阵(例如[512x512 double][256x256 double][128x128 double]等) 现在我想查找并擦除(变为零)单元格数组中矩阵中的100个最小元素(而不是每个矩阵中的单个元素)。例如,最小的元素可能在128x128矩阵中,下一个元素在512x512矩阵中,依此类推 我怎样才能最有效地完成它 下一个是针对三个这样的单元阵列的超慢代码-H、D、V(percent2zero是用于从整个单元阵列擦除的元素百分比

我在MATLAB中有一个单元格数组,其中包含一些按大小降序排列的矩阵(例如[512x512 double][256x256 double][128x128 double]等)

现在我想查找并擦除(变为零)单元格数组中矩阵中的100个最小元素(而不是每个矩阵中的单个元素)。例如,最小的元素可能在128x128矩阵中,下一个元素在512x512矩阵中,依此类推

我怎样才能最有效地完成它

下一个是针对三个这样的单元阵列的超慢代码-H、D、V(
percent2zero
是用于从整个单元阵列擦除的元素百分比的参数):


我可以建议的一件事是将所有矩阵上的每个值放入一个一维向量中,对向量进行排序,然后选择100个最小值。使用和执行此第一步。这背后的逻辑是,如果我们收集所有矩阵上的所有值,并将它们放在一个向量中,然后对整个向量进行排序,我们将选择100个最小值,如您所述

找到这100个最小值后,必须在每个单元格上循环,然后可以使用查看单元格数组中每个矩阵中是否有与100个最小值相同的元素。您可以使用intersect的第二个输出,然后使用它对每个单元格进行索引,并将值设置为0。因为您处理的是单元格,每个单元格的大小不同,所以循环是唯一的选择

我想到了这样的事情。这是假设
详细信息
是一个单元格数组,其中每个单元格都是一个矩阵:

%// Create single 1D vector of all values
vals = cellfun(@(x) reshape(x, [], 1), details, 'uni', 0);
vals = cat(1, vals{:});

%// Sort the UNIQUE values and grab the 100 smallest values
vals = unique(vals);
vals = vals(1:100);

%// Loop through each cell, determine those values that are among
%// the 100 smallest and set to 0
for ii = 1 : numel(details)
    [~,ind,~] = intersect(details{ii}, vals);
    details{ii}(ind) = 0;
end

在数组或矩阵中查找唯一值,但还可以对唯一值进行排序。因此,这段代码将找到100个最小且唯一的值来处理您的单元格数组。

我已经对此做了一点修改,基本上得出了与rayryeng相同的结果。其思想是将每个矩阵重塑为一维向量,对每个向量进行排序并跟踪原始索引,然后开始将一维向量开头的最小元素归零,使用未排序的一维向量的索引返回到二维矩阵并将这些元素归零。我认为,它将一维向量视为队列。无论如何,我为一个包含3个矩阵的单元数组设计了一个函数,它将遵循这个过程。对于具有任意数量矩阵的单元数组来说,它不是漂亮的、优化的或通用的,但我认为改进起来并不困难

function [X] = wipeCellMinima(X,percent2zero)
%wipeCellMinima

x1 = X{1};
x2 = X{2};
x3 = X{3};

l1 = length(x1);
l2 = length(x2);
l3 = length(x3);

%reshape each matrix into a 1D vector and sort them, keeping sorted indices
[q1,I1] = sort(reshape(x1,1,l1^2));
[q2,I2] = sort(reshape(x2,1,l2^2));
[q3,I3] = sort(reshape(x3,1,l3^2));

%total number of elements to be "wiped"
n = fix((l1^2 + l2^2 + l3^2)*percent2zero*0.01); 

i1 = 1;
i2 = 1;
i3 = 1;

%treat the reshaped and sorted matrices kind of like queues
for j = 1:n
    %Find the smallest value indexed in sort1 by i1, in sort2 by i2,
    %and in sort3 by i3.
    [~,idx_min] = min([q1(i1),q2(i2),q3(i3)]);
    if(idx_min == 1)
        %The smallest element in all matrices is the first one in the
        %sorted version of x1. Use it's index in the unsorted version of q1
        %to set the corresponding element in x1 to zero. And increment i1.

        %In the unsorted version of q1, the I1(i1)th element needs to be
        %set to zero. The correct row and column can be extracted from the
        %size of the original matrix x1 and the position of the element in
        %the 1D vector.
        row = mod(I1(i1),l1);
        if(row == 0)
            row = l1;
            col = I1(i1)/l1;
        else
            col = floor(I1(i1)/l1) + 1;
        end
        x1(row,col) = 0;
        i1 = i1 + 1;
    elseif(idx_min == 2)
        row = mod(I2(i2),l2);
        if(row == 0)
            row = l2;
            col = I2(i2)/l2;
        else
            col = floor(I2(i2)/l2) + 1;
        end
        x2(row,col) = 0;
        i2 = i2 + 1;
    else
        row = mod(I3(i3),l3);
        if(row == 0)
            row = l3;
            col = I3(i3)/l3;
        else
            col = floor(I3(i3)/l3) + 1;
        end
        x3(row,col) = 0;
        i3 = i3 + 1;
    end
end

X = {x1,x2,x3};

end

看看嗨…怎么了?我们是否帮助你?如果其中一个答案已经解决了你的问题,请通过点击复选标记来考虑。这表明您已经找到了解决方案,这不再是一个悬而未决的问题。如果您的问题没有得到回答,请解释遗漏的内容。欢迎访问SO。您能否提供一些信息,说明这是如何解决OP的问题的?你到底改变了什么,为什么有帮助?纯代码块可能很难处理此代码能否处理用于删除单元格数组中的值的系数数组具有重复项的情况?另外,对该代码的工作原理进行一些解释也很好。该代码能否处理用于删除单元格数组中的值的系数数组具有重复项的情况?我想这取决于“句柄”的含义。它每次都会将固定数量的元素设置为零,取决于所有矩阵中的元素总数和
percent2zero
,但它不优先根据单元格数组中矩阵的顺序或类似的顺序将元素归零。
function [X] = wipeCellMinima(X,percent2zero)
%wipeCellMinima

x1 = X{1};
x2 = X{2};
x3 = X{3};

l1 = length(x1);
l2 = length(x2);
l3 = length(x3);

%reshape each matrix into a 1D vector and sort them, keeping sorted indices
[q1,I1] = sort(reshape(x1,1,l1^2));
[q2,I2] = sort(reshape(x2,1,l2^2));
[q3,I3] = sort(reshape(x3,1,l3^2));

%total number of elements to be "wiped"
n = fix((l1^2 + l2^2 + l3^2)*percent2zero*0.01); 

i1 = 1;
i2 = 1;
i3 = 1;

%treat the reshaped and sorted matrices kind of like queues
for j = 1:n
    %Find the smallest value indexed in sort1 by i1, in sort2 by i2,
    %and in sort3 by i3.
    [~,idx_min] = min([q1(i1),q2(i2),q3(i3)]);
    if(idx_min == 1)
        %The smallest element in all matrices is the first one in the
        %sorted version of x1. Use it's index in the unsorted version of q1
        %to set the corresponding element in x1 to zero. And increment i1.

        %In the unsorted version of q1, the I1(i1)th element needs to be
        %set to zero. The correct row and column can be extracted from the
        %size of the original matrix x1 and the position of the element in
        %the 1D vector.
        row = mod(I1(i1),l1);
        if(row == 0)
            row = l1;
            col = I1(i1)/l1;
        else
            col = floor(I1(i1)/l1) + 1;
        end
        x1(row,col) = 0;
        i1 = i1 + 1;
    elseif(idx_min == 2)
        row = mod(I2(i2),l2);
        if(row == 0)
            row = l2;
            col = I2(i2)/l2;
        else
            col = floor(I2(i2)/l2) + 1;
        end
        x2(row,col) = 0;
        i2 = i2 + 1;
    else
        row = mod(I3(i3),l3);
        if(row == 0)
            row = l3;
            col = I3(i3)/l3;
        else
            col = floor(I3(i3)/l3) + 1;
        end
        x3(row,col) = 0;
        i3 = i3 + 1;
    end
end

X = {x1,x2,x3};

end
n = sum(cellfun('prodofsize',details),2);
CoeffsToBeRemoved = round(percent2zero/100*n);
for i = 1:size(details,1)
    tmp = cellfun(@(x)x(:),details(i,:),'un',0);
    tmp = sort(abs(vertcat(tmp{:})));
    val = tmp(CoeffsToBeRemoved(i));
    for j = 1:size(details,2)
        details{i,j} = details{i,j}.*(abs(details{i,j})>val);
    end
end