clear pro


rd /s /q  Release rcc_generated ui_generated moc_generated pack
del /q *.ncb  *.sln *.vcproj vc70*.* ui_*.h
del /a:h *.suo

call "D:\svn\project\youtubedownloader\main\ProToVc.bat"

cd "D:\svn\project\youtubedownloader\main\debug"
call clearDebugDir.bat

start "" "D:\svn\project\youtubedownloader\main\youtubedownloader.vcproj"


function main() %%%%%%%%%%%%%%%%%%%%%%%-------注入与产出数据处理-------%%%%%%%%%%%%%%%%%%%%%% close all; clear; clc; %形成生产井数据 [num,txt]=xlsread('pro.xls'); proname = num(:,1); %n*1---井名的列向量 num = num(:,2:end); %num(n,:)为第n口井在各时间点上的数据,行为井 %num = num'; [hNum,lNum] = size(num); for i=1:2:lNum pro1(:,(1+i)/2) = num(:,i) + num(:,i+1); %产液 pro1_hsl(:,(1+i)/2) = num(:,i+1)./(num(:,i) + num(:,i+1)+0.00001*ones(length(num(:,i+1)),1)); %含水率 end %%%%形成注入数据 [num,txt]=xlsread('inj.xls'); injname = num(2:end,1)'; %n*1---井名的行向量 num = num'; inj1=num(:,2:end); %inj1(:,n)为第n口井在各时间点上的数据,行为时间 %xlswrite('coord_pro.xls',proname'); %xlswrite('coord_inj.xls',injname')%形成头文件 % xlswrite('连通系数.xls', proname', '连通系数', 'A2') ; % xlswrite('连通系数.xls', injname, '连通系数', 'B1') ; % xlswrite('连通系数.xls', xlsnada, '连通系数', 'B2') ; %提取计算数据,3个月为1组 pro1 = pro1'; pro1_hsl = pro1_hsl'; for i=1:3:size(pro1,1) pro((2+i)/3,:) = pro1(i,:)+pro1(i+1,:)+pro1(i+2,:); pro_hsl(:,(2+i)/3) = (pro1_hsl(i,:)+pro1_hsl(i+1,:)+pro1_hsl(i+2,:))./3; %含水率 inj((2+i)/3,:) = inj1(i,:)+inj1(i+1,:)+inj1(i+2,:); end %clear pro1_hsl; clear pro1; %xlswrite('inj3.xls',inj); xlswrite('pro3.xls',pro) %形成文件 %%%%%%%%%%%%%%%%%%%%%%-------井位坐标处理-------%%%%%%%%%%%%%%%%%%%%%%%%%%%% [cdpro,tmp] = xlsread('coord_pro.xls'); %cdpro(n,:)--第n口井xy坐标 procdname=cdpro(:,1); %procdname列井名 [cdinj,tmp] = xlsread('coord_inj.xls');%cdinj(n,:)--第n口井xy坐标, injcdname = cdinj(:,1); %列井名 %计算注入井和各生产井之间的距离 for i = 1:size(cdinj,1) for j=1:size(cdpro,1) inj_pro_dis(j,i) = norm(cdpro(j,:)-cdinj(i,:)); end end for i=1:size(inj_pro_dis,2) [y I]=sort(inj_pro_dis(:,i),'ascend'); dis_sort(:,i)=I; end % for i=1:size(dis_sort,1) % aa = reshape(dis_sort(1:i,:),1,size(dis_sort,2)*i); % size(unique(aa)) % end % clear aa; %%%%%%%%%%%%%%%%%%%%%-------灰色关联度分析-------%%%%%%%%%%%%%%%%%%%%%%%%%%% %xi=pro_hsl; [rows,cols]=size(xi); p= 0.3 %含水率波动太小 xi=pro'; [rows,cols]=size(xi); p= 0.3 for k = 1:size(inj,2) x0 = inj(:,k)'; %母数据 %求差值 for i = 1:rows deta0i(i,:)=abs(xi(i,:) - x0); end detamax = max(max(deta0i)); detamin = min(min(deta0i)); %得到最大最小值 %求灰色关联系数 for i = 1:rows %rows个油井 for j = 1:cols kc0i(i,j) = (detamin + p*detamax)/(deta0i(i,j)+p*detamax); end end out(:,k) = mean(kc0i,2); %井距离限制 for i = 1:rows if inj_pro_dis(i,k) > inj_pro_dis(dis_sort(12,k),k) out(i,k) = out(i,k) - 1; end % if(size(find(xi(i,:)<=0.01),2) > size(xi,2)*0.7) %去掉很多数据为0的井 % out(i,k) = out(i,k) - 2; % end end end for i=1:size(out,2) [y I]=sort(out(:,i),'descend'); well(:,i)=I; end % for i=1:size(well,1) % aa = reshape(well(1:i,:),1,size(well,2)*i); % size(unique(aa)) % end % clear aa; clear inj_pro_dis; clear dis_sort;clear out; clear xi; clear pro_hsl; % pro=pro1; % inj=inj1; %%%%%%%%%%%%%%%%%%%%%%----拟合----%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% nadaxls = zeros(size(proname,2),size(injname,2)); for i = 1:size(inj,2) %注入井 %for i = 1:2 %注入井 pron = [pro(:,well(1,i)) pro(:,well(2,i)) pro(:,well(3,i)) pro(:,well(4,i)) pro(:,well(5,i)) ..., pro(:,well(6,i)) pro(:,well(7,i)) pro(:,well(8,i)) pro(:,well(9,i)) pro(:,well(10,i))]; thiswell = [proname(well(1,i)) proname(well(2,i)) proname(well(3,i)) proname(well(4,i)) proname(well(5,i)) ..., proname(well(6,i)) proname(well(7,i)) proname(well(8,i)) proname(well(9,i)) proname(well(10,i))]; j = 1; injn = inj(:,i); while(1) if sum(pron(j,:) < 0.01) == size(pron,2) pron(j ,:) = []; injn(j ,:) = []; j = j-1; end j = j+1; if(j == size(pron,1)) break end end [nadaout(:,i),dout(:,i)] = cal_nada(pron,injn,i,thiswell); i for kk = 1:10 if (nadaout(kk,i) < 0.01) nadaout(kk,i) = 0; end nadaxls(well(kk,i),i) = nadaout(kk,i); delayxls(well(kk,i),i) = dout(kk,i); end end dlmwrite('xlsnada',nadaxls); dlmwrite('xlsdelay',delayxls); dlmwrite('xlsnada8',nadaout); dlmwrite('xlsdelay8',dout); dlmwrite('nadaout',nadaout); dlmwrite('nadout',dout); dlmwrite('bbb',nadaxls); sum(sum(nadaxls')>0) nadaout = dlmread('xlsnada8'); dout = dlmread('xlsdelay8'); nadaxls = dlmread('xlsnada'); %%%%%%%%%%%%%%%%%%%-----绘图-----%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% for i=1:size(well,2) figure(i); plot(inj1(:,i),'bv-','LineWidth',2);hold on; plot(pro1(:,well(1,i)),'r-','LineWidth',1);hold on; plot(pro1(:,well(2,i)),'y-','LineWidth',1);hold on; plot(pro1(:,well(3,i)),'g-','LineWidth',1);hold on; plot(pro1(:,well(4,i)),'c-','LineWidth',1);hold on; plot(pro1(:,well(5,i)),'k-','LineWidth',1); s1 = num2str(injname(i)); s2 = num2str(proname(well(1,i))); s3 = num2str(proname(well(2,i))); s4 = num2str(proname(well(3,i))); s5 = num2str(proname(well(4,i))); s6 = num2str(proname(well(5,i))); legend(s1,s2,s3,s4,s5,s6); Title(strcat('注入井:',num2str(injname(i)))); s1 = char('z_'); s1 = strcat(s1,num2str(injname(i))); s1 =strcat(s1,'.png'); % s1 =strcat(char(injname(i)),'.png'); print(gcf,'-dpng',s1) close(figure(gcf)) ; end %成果图 %画井位,写井位名称 figure(size(well,2) + 1); plot(cdpro(:,1),cdpro(:,2),'ro','MarkerFaceColor','r');hold on; text(cdpro(:,1)+5,cdpro(:,2)+5, num2str(procdname)); hold on; plot(cdinj(:,1),cdinj(:,2),'bo','MarkerFaceColor','b');hold on; text(cdinj(:,1)+5,cdinj(:,2)+5, num2str(injcdname)); hold on; mindis = 500; for i=1:size(well,2) plot_nada(cdinj(i,:),cdpro(well(1,i),:),nadaout(1,i),mindis);hold on; plot_nada(cdinj(i,:),cdpro(well(2,i),:),nadaout(2,i),mindis);hold on; plot_nada(cdinj(i,:),cdpro(well(3,i),:),nadaout(3,i),mindis);hold on; plot_nada(cdinj(i,:),cdpro(well(4,i),:),nadaout(4,i),mindis);hold on; plot_nada(cdinj(i,:),cdpro(well(5,i),:),nadaout(5,i),mindis);hold on; plot_nada(cdinj(i,:),cdpro(well(6,i),:),nadaout(6,i),mindis);hold on; plot_nada(cdinj(i,:),cdpro(well(7,i),:),nadaout(7,i),mindis);hold on; plot_nada(cdinj(i,:),cdpro(well(8,i),:),nadaout(8,i),mindis);hold on; plot_nada(cdinj(i,:),cdpro(well(9,i),:),nadaout(9,i),mindis);hold on; plot_nada(cdinj(i,:),cdpro(well(10,i),:),nadaout(10,i),mindis);hold on; end axis square; print(gcf,'-dpng','成果图.png'); nadaout end %注入点坐标,生产井坐标,连通系数(0-1),三角形高度(最小距离的一半) function plot_nada(injpos,propos,nada,heigh) if nada > 0.001 distmp = norm(injpos-propos); fdk = nada*heigh/(distmp - nada*heigh); B = (injpos + fdk*propos )/(1+fdk); l = nada * heigh * tan(nada/2); a = injpos(1); b = injpos(2); m = B(1); n = B(2); C1x = m - l*(a-m)/sqrt((a - m)^2 + (b - n)^2); C2x = m + l*(a-m)/sqrt((a - m)^2 + (b - n)^2);; C1y = n - (b - n)*(C1x - m)/(a-m); C2y = n - (b - n)*(C2x - m)/(a-m); fill([a C1x C2x a],[b C1y C2y b],'r'); end end 我不太懂matlab帮我仔细分析一下发你的这串代码每一步 函数的调用等等 我是小白
09-16
<think> 我们有一个MATLAB函数`main`,它执行了一系列操作,包括数据处理、灰色关联分析、拟合以及绘图。下面我将逐段分析代码,并解释每个部分的功能和函数调用。 ### 1. 初始化和数据读取 ```matlab function main() %%%%%%%%%%%%%%%%%%%%%%%-------注入与产出数据处理-------%%%%%%%%%%%%%%%%%%%%%% close all; clear; clc; ``` - `close all`: 关闭所有图形窗口。 - `clear`: 清除工作区变量。 - `clc`: 清除命令窗口。 ```matlab %形成生产井数据 [num,txt]=xlsread('pro.xls'); proname = num(:,1); %n*1---井名的列向量 num = num(:,2:end); %num(n,:)为第n口井在各时间点上的数据,行为井 ``` - `xlsread('pro.xls')`: 从Excel文件`pro.xls`中读取数据。`num`是数值数据,`txt`是文本数据。 - `proname = num(:,1)`: 提取第一列作为生产井的井名(列向量)。 - `num = num(:,2:end)`: 提取从第二列到最后一列的数据,即各时间点上的生产数据(每行代表一口井,每列代表一个时间点)。 ```matlab %num = num'; [hNum,lNum] = size(num); for i=1:2:lNum pro1(:,(1+i)/2) = num(:,i) + num(:,i+1); %产液 pro1_hsl(:,(1+i)/2) = num(:,i+1)./(num(:,i) + num(:,i+1)+0.00001*ones(length(num(:,i+1)),1)); %含水率 end ``` - 注意:原代码中`num = num';`被注释掉了,所以`num`的行是井,列是时间点(每个月两个数据点?)。 - `size(num)`: 获取`num`矩阵的大小,`hNum`是行数(井的数量),`lNum`是列数(时间点数量)。 - 循环`i=1:2:lNum`: 每次取两列(相邻两个月)进行处理。 - `pro1(:, (1+i)/2) = num(:,i) + num(:,i+1)`: 将相邻两个月的产油量和产水量相加,得到产液量(即总产量)。注意:`(1+i)/2`会生成1, 1.5, 2, ...,但MATLAB下标只能是整数,这里实际上会取整(向下取整?)或者报错?实际上,当`i`为奇数时,`(1+i)/2`为整数(1,2,3,...)。 - `pro1_hsl(:, (1+i)/2) = num(:,i+1)./(...)`: 计算含水率(产水量/产液量)。为了避免除以0,分母加了一个很小的数(0.00001)。 ```matlab %%%%形成注入数据 [num,txt]=xlsread('inj.xls'); injname = num(2:end,1)'; %n*1---井名的行向量 num = num'; inj1=num(:,2:end); %inj1(:,n)为第n口井在各时间点上的数据,行为时间 ``` - 读取注入井数据文件`inj.xls`。 - `injname = num(2:end,1)'`: 第一列(从第二行开始)作为注入井名称,并转置为行向量。 - `num = num'`: 转置整个矩阵。 - `inj1 = num(:,2:end)`: 去掉第一列(井名),剩下的数据是各时间点的注入量。此时,`inj1`的每一列代表一口注入井,每一行代表一个时间点。 ```matlab %提取计算数据,3个月为1组 pro1 = pro1'; pro1_hsl = pro1_hsl'; for i=1:3:size(pro1,1) pro((2+i)/3,:) = pro1(i,:)+pro1(i+1,:)+pro1(i+2,:); pro_hsl(:,(2+i)/3) = (pro1_hsl(i,:)+pro1_hsl(i+1,:)+pro1_hsl(i+2,:))./3; %含水率 inj((2+i)/3,:) = inj1(i,:)+inj1(i+1,:)+inj1(i+2,:); end ``` - 将生产井的产液量和含水率转置(现在行是时间,列是井)。 - 循环`i=1:3:size(pro1,1)`: 每3个月(三个时间点)进行累加(产液量和注入量)或平均(含水率)。 - `pro((2+i)/3,:) = ...`: 累加三个月的产液量,形成新的时间段数据(季度数据)。 - `pro_hsl(:, (2+i)/3) = ...`: 取三个月的含水率平均值。 - `inj((2+i)/3,:) = ...`: 累加三个月的注入量。 ### 2. 井位坐标处理 ```matlab [cdpro,tmp] = xlsread('coord_pro.xls'); %cdpro(n,:)--第n口井xy坐标 procdname=cdpro(:,1); %procdname列井名 [cdinj,tmp] = xlsread('coord_inj.xls');%cdinj(n,:)--第n口井xy坐标, injcdname = cdinj(:,1); %列井名 ``` - 读取生产井和注入井的坐标文件。 - 提取井名和坐标。 ```matlab %计算注入井和各生产井之间的距离 for i = 1:size(cdinj,1) for j=1:size(cdpro,1) inj_pro_dis(j,i) = norm(cdpro(j,:)-cdinj(i,:)); end end ``` - 双重循环计算每口注入井到每口生产井的欧氏距离(`norm`函数)。 - `inj_pro_dis`矩阵:行对应生产井,列对应注入井。 ```matlab for i=1:size(inj_pro_dis,2) [y I]=sort(inj_pro_dis(:,i),'ascend'); dis_sort(:,i)=I; end ``` - 对每口注入井(每列),将生产井按照距离从小到大排序,`I`是排序后的索引(即生产井的序号)。 - `dis_sort`矩阵:每列对应一口注入井,存储按距离从小到大排序的生产井索引。 ### 3. 灰色关联度分析 ```matlab xi=pro'; [rows,cols]=size(xi); p= 0.3 %含水率波动太小 ``` - 这里选择使用产液量(`pro`)作为分析数据(因为注释了含水率)。但注意前面代码中`pro`是季度产液量(时间×井),转置后`xi`是井×时间。 - `rows`是生产井数量,`cols`是时间段数量。 - `p`是灰色关联分析中的分辨系数。 ```matlab for k = 1:size(inj,2) x0 = inj(:,k)'; %母数据(注入井k在每个时间段的注入量) %求差值 for i = 1:rows deta0i(i,:)=abs(xi(i,:) - x0); end detamax = max(max(deta0i)); detamin = min(min(deta0i)); %得到最大最小值 %求灰色关联系数 for i = 1:rows %rows个油井 for j = 1:cols kc0i(i,j) = (detamin + p*detamax)/(deta0i(i,j)+p*detamax); end end out(:,k) = mean(kc0i,2); ``` - 对每口注入井(`k`从1到注入井数量): - `x0`为该注入井在所有时间段的注入量(行向量)。 - 计算每个生产井(`xi(i,:)`)与注入井`k`的绝对差值`deta0i`。 - 计算整个差值矩阵的最大值`detamax`和最小值`detamin`。 - 计算灰色关联系数矩阵`kc0i`(每个元素对应一个时间点上一个生产井与注入井的关联程度)。 - 对每个生产井,计算关联系数在时间上的平均值`out(:,k)`(列向量)。 ```matlab %井距离限制 for i = 1:rows if inj_pro_dis(i,k) > inj_pro_dis(dis_sort(12,k),k) out(i,k) = out(i,k) - 1; end % if(size(find(xi(i,:)<=0.01),2) > size(xi,2)*0.7) %去掉很多数据为0的井 % out(i,k) = out(i,k) - 2; % end end end ``` - 对每口注入井的关联度进行距离惩罚:如果生产井`i`到注入井`k`的距离大于该注入井对应的第12近的生产井的距离(即`dis_sort(12,k)`对应的距离),则关联度减去1(降低关联度)。 - 注释掉的部分:如果某个生产井在超过70%的时间段内产液量接近于0(<=0.01),则关联度再减去2(这里未使用)。 ```matlab for i=1:size(out,2) [y I]=sort(out(:,i),'descend'); well(:,i)=I; end ``` - 对每口注入井,根据调整后的关联度`out(:,i)`从大到小排序,得到关联度最高的生产井索引(存储在`well`矩阵中,每列对应一口注入井,按关联度从高到低排列生产井索引)。 ### 4. 拟合(计算连通系数和延迟) ```matlab nadaxls = zeros(size(proname,2),size(injname,2)); ``` - 初始化`nadaxls`矩阵(生产井数量×注入井数量),用于存储连通系数。 ```matlab for i = 1:size(inj,2) %注入井 pron = [pro(:,well(1,i)) pro(:,well(2,i)) pro(:,well(3,i)) pro(:,well(4,i)) pro(:,well(5,i)) ..., pro(:,well(6,i)) pro(:,well(7,i)) pro(:,well(8,i)) pro(:,well(9,i)) pro(:,well(10,i))]; thiswell = [proname(well(1,i)) proname(well(2,i)) proname(well(3,i)) proname(well(4,i)) proname(well(5,i)) ..., proname(well(6,i)) proname(well(7,i)) proname(well(8,i)) proname(well(9,i)) proname(well(10,i))]; j = 1; injn = inj(:,i); while(1) if sum(pron(j,:) < 0.01) == size(pron,2) pron(j ,:) = []; injn(j ,:) = []; j = j-1; end j = j+1; if(j == size(pron,1)) break end end [nadaout(:,i),dout(:,i)] = cal_nada(pron,injn,i,thiswell); i for kk = 1:10 if (nadaout(kk,i) < 0.01) nadaout(kk,i) = 0; end nadaxls(well(kk,i),i) = nadaout(kk,i); delayxls(well(kk,i),i) = dout(kk,i); end end ``` - 对每口注入井`i`: - `pron`:提取关联度排名前10的生产井的产液量(按季度),每列是一个生产井,每行是一个时间段(季度)。 - `thiswell`:这10口生产井的井名。 - `injn`:当前注入井`i`的注入量(按季度)。 - 循环去除产液量全为0(接近于0)的时间段(行):如果某一行(时间段)所有生产井的产液量都小于0.01,则删除该行(同时删除注入量的对应行)。 - 调用函数`cal_nada(pron, injn, i, thiswell)`,返回两个向量: - `nadaout(:,i)`: 10口生产井的连通系数(向量)。 - `dout(:,i)`: 10口生产井的延迟(向量)。 - 将连通系数和延迟分别存储到矩阵`nadaxls`和`delayxls`中(注意索引:`well(kk,i)`是第`kk`个关联的生产井的全局索引)。 ### 5. 保存结果 ```matlab dlmwrite('xlsnada',nadaxls); dlmwrite('xlsdelay',delayxls); dlmwrite('xlsnada8',nadaout); dlmwrite('xlsdelay8',dout); dlmwrite('nadaout',nadaout); dlmwrite('nadout',dout); dlmwrite('bbb',nadaxls); ``` - 使用`dlmwrite`将矩阵写入文本文件(默认分隔符为逗号)。 ### 6. 绘图 ```matlab for i=1:size(well,2) figure(i); plot(inj1(:,i),'bv-','LineWidth',2);hold on; plot(pro1(:,well(1,i)),'r-','LineWidth',1);hold on; ... % 类似地画出其余5口生产井的数据 % 添加图例 s1 = num2str(injname(i)); ... % 注入井名称 ... % 生产井名称 legend(s1,s2,s3,s4,s5,s6); Title(strcat('注入井:',num2str(injname(i)))); ... % 保存图片 end ``` - 为每口注入井绘制一张图:注入量和关联度最高的5口生产井的产液量(原始月度数据)随时间变化的曲线。 ```matlab %成果图 figure(size(well,2) + 1); plot(cdpro(:,1),cdpro(:,2),'ro','MarkerFaceColor','r');hold on; ... % 标注生产井名称 plot(cdinj(:,1),cdinj(:,2),'bo','MarkerFaceColor','b');hold on; ... % 标注注入井名称 mindis = 500; for i=1:size(well,2) ... % 绘制注入井到生产井的连线(三角形),其宽度代表连通系数 end axis square; print(gcf,'-dpng','成果图.png'); ``` - 绘制所有井的坐标图(生产井为红色,注入井为蓝色),并标注名称。 - 对每口注入井,为其关联度前10的生产井绘制从注入井到生产井的三角形(表示连通性),三角形的大小由连通系数`nadaout`决定(通过函数`plot_nada`实现)。 ### 7. 自定义函数`plot_nada` ```matlab function plot_nada(injpos,propos,nada,heigh) if nada > 0.001 ... % 计算三角形的位置并绘制填充三角形 end end ``` - 参数:注入井位置`injpos`,生产井位置`propos`,连通系数`nada`,基准高度`heigh`(500)。 - 当连通系数大于0.001时,计算一个三角形(以注入井为顶点,底边中点位于注入井到生产井的连线上,且底边宽度与连通系数成正比),并用红色填充。 ### 总结 该代码主要功能: 1. **数据处理**:从Excel文件中读取生产井和注入井的月度数据,并聚合成季度数据。 2. **井位距离计算**:计算注入井与生产井之间的欧氏距离,并排序。 3. **灰色关联分析**:计算每口注入井与各生产井的关联度,并考虑距离惩罚。 4. **拟合**:对每口注入井关联度最高的10口生产井,调用`cal_nada`函数计算连通系数和延迟时间。 5. **绘图**: - 绘制每口注入井及其关联生产井的产液量曲线。 - 绘制井位分布图,并用三角形表示注入井与生产井之间的连通性(三角形大小表示连通系数)。 ### 注意 - 代码中调用了自定义函数`cal_nada`,但在提供的代码中未给出其实现。 - 代码中的`pro1`和`pro1_hsl`等变量在循环后未被清除,可能会占用较多内存。 - 在去除全零时间段的循环中,使用`while`循环并动态删除行,同时调整索引,需要小心。 ### 相关问题 1. 灰色关联分析中的分辨系数$p$如何影响分析结果?[^1] 2. 在计算灰色关联系数时,为什么需要加入一个很小的常数(0.00001)?[^1] 3. 如何理解`plot_nada`函数中绘制的三角形?其几何参数如何反映连通系数?[^1] </think> 以下是对您提供的MATLAB代码的逐行详细分析,包括函数调用和执行逻辑的解释。代码主要实现油田生产数据分析,包括数据处理、灰色关联分析、连通系数计算和可视化。 --- ### **1. 初始化和数据加载** ```matlab function main() close all; clear; clc; ``` - `close all`:关闭所有图形窗口 - `clear`:清除工作区变量 - `clc`:清除命令窗口内容 - `function main()`:定义主函数入口 ```matlab [num,txt]=xlsread('pro.xls'); proname = num(:,1); % 生产井名称(列向量) num = num(:,2:end); % 生产数据矩阵(井×时间点) ``` - `xlsread('pro.xls')`:读取生产井Excel文件 - `num`:数值数据 - `txt`:文本数据(未使用) - `proname`:提取第一列作为井名 - `num(:,2:end)`:保留生产数据(移除井名列) ```matlab [hNum,lNum] = size(num); for i=1:2:lNum pro1(:,(1+i)/2) = num(:,i) + num(:,i+1); % 产液量计算 pro1_hsl(:,(1+i)/2) = num(:,i+1)./(num(:,i) + num(:,i+1)+0.00001*ones(...)); % 含水率计算 end ``` 1. `size(num)`:获取数据矩阵维度 2. 循环处理每两个月的数据: - **产液量**:相邻两月数据相加 - **含水率**:产水量/(产油量+产水量),避免除以0加小常数`0.00001` - `ones(length(...),1)`:生成全1向量用于广播计算 --- ### **2. 注入数据处理** ```matlab [num,txt]=xlsread('inj.xls'); injname = num(2:end,1)'; % 注入井名称(行向量) num = num'; inj1 = num(:,2:end); % 注入数据(时间×井) ``` - 读取注入井数据并转置 - `inj1`:注入量数据矩阵,每列代表一口注入井 ```matlab pro1 = pro1'; pro1_hsl = pro1_hsl'; for i=1:3:size(pro1,1) pro((2+i)/3,:) = sum(pro1(i:i+2,:),1); % 季度产液量 pro_hsl(:,(2+i)/3) = mean(pro1_hsl(i:i+2,:)); % 季度平均含水率 inj((2+i)/3,:) = sum(inj1(i:i+2,:),1); % 季度注入量 end ``` - 数据按季度(3个月)聚合: - **季度产液量**:三个月产液量之和 - **季度含水率**:三个月平均值 - **季度注入量**:三个月注入量之和 - `sum(...,1)`:沿行方向求和 - `mean(...)`:沿行方向求平均 --- ### **3. 井位坐标处理** ```matlab [cdpro,tmp] = xlsread('coord_pro.xls'); % 生产井坐标 procdname = cdpro(:,1); % 生产井名 [cdinj,tmp] = xlsread('coord_inj.xls'); % 注入井坐标 injcdname = cdinj(:,1); % 注入井名 ``` - 读取井位坐标文件 - 提取井名和坐标数据 ```matlab for i = 1:size(cdinj,1) for j=1:size(cdpro,1) inj_pro_dis(j,i) = norm(cdpro(j,:)-cdinj(i,:)); % 欧氏距离计算 end end ``` - 计算所有注入井-生产井对的欧氏距离 - `norm(A-B)`:计算向量A和B的欧氏距离 $$ \| \mathbf{A} - \mathbf{B} \|_2 $$ ```matlab for i=1:size(inj_pro_dis,2) [y,I] = sort(inj_pro_dis(:,i),'ascend'); dis_sort(:,i) = I; % 距离排序索引 end ``` - 对每口注入井,将生产井按距离升序排序 - `sort(...,'ascend')`:升序排序,返回排序索引 `I` --- ### **4. 灰色关联分析** ```matlab xi = pro'; [rows,cols] = size(xi); p = 0.3; for k = 1:size(inj,2) x0 = inj(:,k)'; % 注入数据作为母序列 for i = 1:rows deta0i(i,:) = abs(xi(i,:) - x0); % 绝对差值 end detamax = max(max(deta0i)); % 最大差值 detamin = min(min(deta0i)); % 最小差值 ``` - 灰色关联分析核心步骤: 1. 母序列 `x0`:注入井数据 2. 子序列 `xi`:生产井数据 3. 计算绝对差值矩阵 $$ \Delta_i(k) = |x_0(k) - x_i(k)| $$ ```matlab for i = 1:rows for j = 1:cols kc0i(i,j) = (detamin + p*detamax)/(deta0i(i,j) + p*detamax); % 关联系数 end end out(:,k) = mean(kc0i,2); % 平均关联度 ``` - **关联系数计算**: $$ \gamma_i(k) = \frac{\Delta_{\min} + \rho \Delta_{\max}}{\Delta_i(k) + \rho \Delta_{\max}} $$ - $\rho=0.3$ 为分辨系数 - `mean(kc0i,2)`:计算每口生产井的平均关联度 ```matlab for i = 1:rows if inj_pro_dis(i,k) > inj_pro_dis(dis_sort(12,k),k) out(i,k) = out(i,k) - 1; % 距离惩罚 end end end ``` - **距离惩罚机制**:关联度排名12之后的生产井关联度减1 - 筛选出与注入井关联度最高的生产井 --- ### **5. 连通系数计算** ```matlab nadaxls = zeros(size(proname,2), size(injname,2)); for i = 1:size(inj,2) pron = [pro(:, well(1:10,i))]; % 提取Top10生产井数据 thiswell = proname(well(1:10,i)); % 井名 injn = inj(:,i); % 当前注入井数据 % 清除无效数据(产量<0.01) j = 1; while j <= size(pron,1) if all(pron(j,:) < 0.01) pron(j,:) = []; injn(j) = []; else j = j+1; end end [nadaout(:,i), dout(:,i)] = cal_nada(pron, injn, i, thiswell); % 核心拟合函数 end ``` - **数据清洗**:移除产量接近0的时间段 - **核心拟合**:调用 `cal_nada()` 函数计算: - `nadaout`:连通系数向量 - `dout`:延迟时间向量 - 结果存储到矩阵 `nadaxls` 和 `delayxls` --- ### **6. 结果输出与可视化** ```matlab dlmwrite('xlsnada', nadaxls); % 写入连通系数 dlmwrite('xlsdelay', delayxls); % 写入延迟时间 for i=1:size(well,2) figure(i); plot(inj1(:,i), 'bv-', 'LineWidth',2); hold on; plot(pro1(:,well(1,i)), 'r-', 'LineWidth',1); ... % 绘制Top5生产井曲线 legend(injname(i), proname(well(1:5,i))); title(['注入井:', num2str(injname(i))]); print(gcf, '-dpng', ['z_', num2str(injname(i)), '.png']); end ``` - **文件输出**:`dlmwrite()` 将结果写入文本文件 - **单井可视化**:对每口注入井绘制其与Top5生产井的产量/注入量曲线 - `plot()`:标准绘图函数 - `print()`:保存为PNG图像 ```matlab figure(size(well,2)+1); plot(cdpro(:,1), cdpro(:,2), 'ro', 'MarkerFaceColor','r'); % 生产井位置 text(cdpro(:,1)+5, cdpro(:,2)+5, num2str(procdname)); plot(cdinj(:,1), cdinj(:,2), 'bo', 'MarkerFaceColor','b'); % 注入井位置 text(cdinj(:,1)+5, cdinj(:,2)+5, num2str(injcdname)); mindis = 500; for i=1:size(well,2) for k=1:10 plot_nada(cdinj(i,:), cdpro(well(k,i),:), nadaout(k,i), mindis); % 绘制连通线 end end print(gcf, '-dpng', '成果图.png'); ``` - **井位分布图**: - 红色圆圈:生产井位置 - 蓝色圆圈:注入井位置 - **连通关系可视化**:调用 `plot_nada()` 绘制注入井-生产井的连通三角形 - 三角形大小表示连通系数大小 --- ### **7. 自定义函数分析** #### **plot_nada() 函数** ```matlab function plot_nada(injpos, propos, nada, heigh) if nada > 0.001 distmp = norm(injpos - propos); % 计算井间距离 fdk = nada*heigh/(distmp - nada*heigh); % 比例因子 B = (injpos + fdk*propos)/(1+fdk); % 三角形顶点计算 % 三角形坐标计算 l = nada * heigh * tan(nada/2); a = injpos(1); b = injpos(2); m = B(1); n = B(2); C1x = m - l*(a-m)/norm([a-m, b-n]); ... % 类似计算其他顶点 fill([a C1x C2x a], [b C1y C2y b], 'r'); % 绘制填充三角形 end end ``` - **功能**:绘制表示井间连通性的三角形 - **输入参数**: - `injpos`:注入井坐标 - `propos`:生产井坐标 - `nada`:连通系数 - `heigh`:基准高度(500) - **关键计算**: 1. 三角形顶点位置基于连通系数动态计算 2. `fill()`:绘制红色填充三角形,面积正比于连通系数 #### **cal_nada() 函数** - **未提供实现**:但从上下文推断其功能为: - 输入:生产井产量矩阵 `pron`,注入井数据 `injn` - 输出:连通系数向量 `nadaout`,延迟时间向量 `dout` - 可能算法:时间序列相关性分析或最小二乘拟合 --- ### **代码总结** 1. **数据流**: ```mermaid graph LR A[原始Excel数据] --> B[季度聚合] B --> C[灰色关联分析] C --> D[连通系数计算] D --> E[可视化输出] ``` 2. **核心算法**: - 灰色关联分析评估井间关系 - 基于地理距离的惩罚机制 - 连通系数的空间可视化 3. **关键技术点**: - 时间序列数据聚合(月→季度) - 矩阵运算优化循环(`mean()`, `sum()`) - 基于欧氏距离的空间分析 - 动态几何图形生成 --- ### **相关问题** 1. 灰色关联分析中分辨系数$ρ$的选择如何影响井间关联度排序结果?[^1] 2. 在计算含水率时加入小常数$0.00001$在数值稳定性中的作用是什么?[^1] 3. `plot_nada`函数生成的三角形面积如何量化表示井间连通性?[^1] 4. 如何扩展此代码处理大规模油田(>1000口井)的数据?[^2][^3] 5. 时间延迟$dout$的计算可能采用哪些时间序列分析方法?[^4] [^1]: 参考灰色系统理论和数值计算方法 [^2]: 参考UKF滤波在大规模系统中的应用 [^3]: 参考交互式多模型(IMM)滤波算法 [^4]: 参考自适应IMM算法中的协方差更新
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值