返回一行中满足条件的最大序号数(MATLAB)

返回一行中满足条件的最大序号数(MATLAB),matlab,conditional-statements,sequence,counter,Matlab,Conditional Statements,Sequence,Counter,我有一个0-1之间的大型随机值矩阵(例如200000 x 6000),名为“allGSR” 我使用以下代码创建了一个逻辑数组(?),其中1表示小于.05的数字 sig = (allGSR < .05); sig=(allGSR

我有一个0-1之间的大型随机值矩阵(例如200000 x 6000),名为“allGSR” 我使用以下代码创建了一个逻辑数组(?),其中1表示小于.05的数字

sig = (allGSR < .05);
sig=(allGSR<0.05);
我想做的是返回一个名为maxSIG的大小为1 x 200000的数组,其中每一行表示最大数量的连续行。例如,如果在第1行中,第3-6列为1,即一行中的4列,如果第100-109列为一行中的10列,并且如果这是一行中的最大个数,我希望maxSIG的第一列为值“10”

我一直在用for循环、if语句和计数器来实现这一点;这既丑陋又乏味,我想知道是否有更简单或更有效的方法

谢谢你的见解

编辑:哎呀,可能应该共享循环。 编辑2:所以我用一个较小的(100 x 6000)矩阵写出了我的基本代码。这段代码应该运行。很抱歉给您带来不便

GSR = 6000;
samples = 100;
allGSR = zeros(samples, GSR);
for x = 1:samples
    y = rand(GSR, 1)';  %Transpose so it's 1x6000 and not 6000x1
    allGSR(x,:) = y;
end

countSIG = zeros(samples,1);
abovethreshold = (allGSR < .05); %.05 can be replaced by whatever
for z = 1:samples
    count = 0;
    holdArray = zeros(1,GSR);
    for a = 1:GSR
        if abovethreshold(z,a) == true
            count = count + 1;
        else
            count = 0;
        end
        holdArray(1,a) = count;
    end
    maxrun = max(holdArray);
    countSIG(z,1) = maxrun;
end
GSR=6000;
样本=100;
所有GSR=零(样本,GSR);
对于x=1:样本
y=兰特(GSR,1)';%转换为1x6000而不是6000x1
allGSR(x,:)=y;
结束
countSIG=零(样本,1);
高于阈值=(所有GSR<.05);%。05可以被任何东西代替
对于z=1:样本
计数=0;
holdArray=0(1,GSR);
对于a=1:GSR
如果高于阈值(z,a)=真
计数=计数+1;
其他的
计数=0;
结束
holdArray(1,a)=计数;
结束
maxrun=max(保持阵列);
countSIG(z,1)=maxrun;
结束

如果您担心内存分配、速度等。。。在巨大的数组中,我只需要在C++中做同样的基本算法。将其放入类似于myfunction.cpp的文件中,并使用
mex-largearydims myfunction.cpp
进行编译

然后,您可以使用
counts=myfunction(allGSR.05)
从matlab调用

除了它编译之外,我还没有测试过这个

#include "mex.h"
#include "matrix.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
  if(nrhs != 2)
    mexErrMsgTxt("Invalid number of inputs.  Shoudl be 2 input argument.");
  if(nlhs != 1)
    mexErrMsgTxt("Invalid number of outputs.  Should be 1 output arguments.");
  if(!mxIsDouble(prhs[0]) || !mxIsDouble(prhs[1]))
    mexErrMsgTxt("First two arguments are not doubles");

  const mxArray *input_array = prhs[0];
  const mxArray *threshold_array = prhs[1];
  size_t input_rows = mxGetM(input_array);
  size_t input_cols = mxGetN(input_array);
  size_t threshold_rows = mxGetM(threshold_array);
  size_t threshold_cols = mxGetN(threshold_array);
  if(threshold_rows != 1 || threshold_cols != 1)
    mexErrMsgTxt("threshold array should be a scalar");

  mxArray *output_array = mxCreateDoubleMatrix(1, input_rows, mxREAL);  
  double *output_data = mxGetPr(output_array);
  double *input_data  = mxGetPr(input_array);
  double threshold = *mxGetPr(threshold_array);


  for(int z = 0; z < input_rows; z++) {
    int count = 0;
    int max_count = 0;
    for(int a = 0; a < input_cols; a++) {
      if(input_data[z + a * input_rows] < threshold) {
        count++;
      } else {
        if(count > max_count)
           max_count = count;
        count = 0;
      }
    }
    if(count > max_count)
      max_count = count;
    output_data[z] = max_count;
  }

  plhs[0] = output_array;
}
#包括“mex.h”
#包括“矩阵h”
void MEX函数(int nlhs、mxArray*plhs[]、int nrhs、const mxArray*prhs[]){
如果(nrhs!=2)
MEXERMSGSTXT(“输入数无效。应为2个输入参数”);
如果(nlhs!=1)
mexErrMsgTxt(“输出数无效。应为1个输出参数”);
如果(!mxisDuble(prhs[0])| |!mxisDuble(prhs[1]))
mexErrMsgTxt(“前两个参数不是双参数”);
常量mxArray*输入_数组=prhs[0];
常量mxArray*阈值_数组=prhs[1];
大小\u t输入\u行=mxGetM(输入\u数组);
大小\u t输入\u cols=mxGetN(输入\u数组);
大小\u t阈值\u行=mxGetM(阈值\u数组);
size\u t threshold\u cols=mxGetN(threshold\u数组);
如果(阈值行数!=1 |阈值列数!=1)
mexErrMsgTxt(“阈值数组应该是标量”);
mxArray*output_array=mxCreateDoubleMatrix(1,输入_行,mxREAL);
double*output_data=mxGetPr(output_数组);
双*input_data=mxGetPr(input_数组);
双阈值=*mxGetPr(阈值_数组);
对于(intz=0;z最大计数)
最大计数=计数;
计数=0;
}
}
如果(计数>最大计数)
最大计数=计数;
输出_数据[z]=最大_计数;
}
plhs[0]=输出_阵列;
}
我不确定您是否要检查是否高于或低于阈值?无论您做什么,都要将
input_data[z+a*input_rows]
更改为所需的任何比较运算符。

这里有一种方法使用,&-

在上面发布的代码中,我们正在创建一个
高于阈值的fat数组,然后对其进行转置。从性能的角度来看,转置操作可能不是最好的选择。所以,我们可以在它周围移动东西,而不是它本身,就像这样-

append_col = zeros(size(abovethreshold,1),1);
df = diff([append_col abovethreshold append_col],[],2); %//'
[R1,C1] = find(df==1);
[R2,C2] = find(df==-1);
[~,idx1] = sort(R1);
[~,idx2] = sort(R2);
out = zeros(samples,1);
out(1:max(R1)) = accumarray(R1(idx1),C2(idx2) - C1(idx1),[],@max);

这是一个单行程序,尽管速度很慢,因为
cellfun
是一个循环:

maxSIG=cellfun(@(x) max(getfield(regionprops(x),'Area')),mat2cell(allGSR,ones(6000,1),100));
图像处理工具箱函数
regionprops
标识逻辑矩阵中的1的连接组。通过对矩阵的每一行进行操作,并特别返回
区域
属性,我们可以得到每一行中1的每个连接段的长度。
max
函数选择要查找的每一行的长度


请注意,
mat2cell
调用是将
allGSR
拆分为行的单元格矩阵所必需的,这样就可以调用
cellfun

共享您的循环代码?哎呀,很抱歉遗漏了。添加。请列出实际
allGSR
和其他相关输入的较小代表性版本,以及自包含并使用它们运行的代码,并确保其输出符合预期。此外,在编辑的代码中,
示例
未定义。基本上,我们正在寻找一个最小的、完整的、可验证的示例来演示您想要实现的目标。更多信息-你有一个C++编译器安装在你的机器上吗?使用C++编写的MEX函数,可以从MATLAB调用吗?或者你在寻找一个完全用MATLAB编写的答案?我明白。希望新的区块是所需要的。对不起,误会了。
maxSIG=cellfun(@(x) max(getfield(regionprops(x),'Area')),mat2cell(allGSR,ones(6000,1),100));