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