在 MATLAB 中的多个循环中从元胞数组中保存、提取相关数据

Saving, extracting relevant data from cell arrays in multiple loops in MATLAB

抱歉,这个问题很简单,但我被困住了。跟元胞数组有关。

我有delay, offset, and threshold.

 delay = [0.01:0.01:0.03];
 offset = [0.02:0.01:0.04];
 threshold = [0.4:0.1:0.9];       
 limit_for_idx  = [0.4:0.1:0.9]; 
 limit = [0.4:0.1:0.9];

我试图提供一个例子来仅询问我遇到问题的部分。

在循环的第一部分,我收到了所有循环的延迟、偏移、J、r、阈值的完整值,如图所示。

delay =0.0300 offset=0.0400 J=16 25 24 25 r = 24 21 46 18 threshold = 0.4:0.9

然后我过滤了J的最小值和r的最大值以及对应于最小J和最大r的阈值。我收到了如图所示的这些值。

   [min_J,min_J_loc] = min(J(:))
   [max_r,max_r_loc] = max(r(:))
   thresh_min_J = threshold(min_J_loc);
   thresh_max_r = threshold(max_r_loc);

对于我用红色标记的一种情况,但我会收到所有循环的这些组合,如整张图片所示。

问题:

• 我想从我所有的组合中找到delay, offset, threshold包含minimum Jmaximum r的组合如图我需要 delay ,offset, threshold 的组合,其中包含 minimum Jmaximum r 。我在单元格数组中保存了值,因为我对如何从单元格数组中获取组合感到困惑。

• 是否有任何好的方法来保存值,或者可能是结构,如果是的话,有人可以解释一下小提示是如何工作的。

代码:

 delay = [0.01:0.01:0.03];
 offset = [0.02:0.01:0.04];
 threshold = [0.4:0.1:0.9];       
 limit_for_idx  = [0.4:0.1:0.9]; 
 limit = [0.4:0.1:0.9];         


 J=0;
 T = 1;
 b=1;
 K=1;
 for H = 1:numel(delay)
     for G = 1:numel(offset)
        for R = 1:numel(threshold);  

          J = randi([10 25],1,4);    
           r = randi([10 50],1,4);
        end
   [min_J,min_J_loc] = min(J(:))
   [max_r,max_r_loc] = max(r(:))
   thresh_min_J = threshold(min_J_loc);
   thresh_max_r = threshold(max_r_loc);
       out{K,:} = [ delay(H) offset(G)  J  r threshold];
       output{T,:} = [delay(H) offset(G)  min_J  max_r  thresh_min_J  thresh_max_r];
     K=K+1;
     T = T+1;
     end

 end


  for X = 1:numel(out)
      disp(' delay ,   offset(G) ,  J,   r ,  threshold  ') 
      Q = out{X};
      disp(Q)
  end

   for X = 1:numel(output)
        disp(' delay ,   offset(G) ,  min_J,   max_r ,   thresh_min_J  thresh_max_r ')
      Z =  output{X};
      disp(Z)

   end 

查看示例的修改版本:

function varargout = q47452082
delay = (0.01:0.01:0.03);
offset = (0.02:0.01:0.04);
threshold = (0.4:0.1:0.9);
nD = numel(delay);
nO = numel(offset);
J = randi([10 25],1,4,nD,nO);
r = randi([10 50],1,4,nD,nO);
%% Preallocate
%{
The simplest way to do it:
out    = NaN(nD*nO,3*1+2*4);
output = NaN(nD*nO,6);
%}
out = struct('delay',[],'offset',[],'J',[],'r',[],'threshold',[]);
out = repmat(out,nD*nO,1);
output = struct('delay',[],'offset',[],'min_J',[],'max_r',[],...
  'thresh_min_J',[],'thresh_max_r',[]);
output = repmat(output,nD*nO,1);
fn{2} = fieldnames(output);
fn{1} = fieldnames(out);
%% Populate the data structures:
K = 1;
for H = 1:numel(delay)
  for G = 1:numel(offset)
    [min_J,min_J_loc] = min(J(:,:,H,G));
    [max_r,max_r_loc] = max(r(:,:,H,G));
    thresh_min_J = threshold(min_J_loc);
    thresh_max_r = threshold(max_r_loc);
    data = {delay(H),offset(G),J(:,:,H,G),r(:,:,H,G),threshold};
    for indF = 1:numel(fn{1})
      out(K).(fn{1}{indF}) = data{indF};
    end
    data = {delay(H), offset(G), min_J, max_r, thresh_min_J, thresh_max_r};
    for indF = 1:numel(fn{2})
      output(K).(fn{2}{indF}) = data{indF};
    end
    K = K+1;
  end
end

if nargout == 0 % if no outputs requested, print
  if ~verLessThan('matlab','8.2') % tables exist in MATLAB R2013b or newer
    disp(struct2table(out));
    disp(struct2table(output));
  else
    for X = 1:numel(out)
      Q = out(X);
      disp(Q)
    end
    for X = 1:numel(output)
      Z = output(X);
      disp(Z)
    end
  end
else % otherwise output the desired data:
  % OPTION #1: separate variables
  % You should call the function like so: [min_J_cases,max_r_cases] = q47452082();
  varargout{1} = output([output.min_J] == min([output.min_J]));
  varargout{2} = output([output.max_r] == max([output.max_r]));
  % OPTION #2: 1 output, 2x1 cell
  %{
  varargout = {output([output.min_J] == min([output.min_J]));...
               output([output.max_r] == max([output.max_r]))};
  %}
  % OPTION #3: 1 output, 2x1 struct
  %{
  varargout = {[output([output.min_J] == min([output.min_J]));...
                output([output.max_r] == max([output.max_r]))]};
  %}
end

您应该注意的几件事:

  • 我删除了一些未使用的变量。
  • 我将 outoutput 预分配为 struct 数组。
  • 我删除了围绕 Jr 随机化的循环(因为它什么都不做)并将随机数生成移动到循环之前(没有理由在每次迭代时都这样做可以在开始的时候一次性完成)。
  • 我使用 dynamic field references 对两个 struct 数组执行赋值。
  • 我添加了一个演示,说明如何根据不同的 MATLAB 版本(以及因此支持的不同功能)运行 不同的代码 - 请参阅最后的打印。
  • 如果您不请求输出,该函数只会打印内容。
  • 您的代码可能还有进一步矢量化的空间(即摆脱循环)。