您的位置:首页 > 编程语言 > MATLAB

matlab读取大量文件及MATLAB处理变参数多元非线性方程组

2017-04-07 11:53 393 查看


关于MATLAB读取大量文件及MATLAB处理变参数多元非线性方程组

循环读取大量文件

前段时间用MATLAB处理txt文件时遇到了一个问题,由于txt文件太多因此需要做成循环来依次处理500(实际上有5000多个)多个txt文件。最主要的问题是fopen的参数是不能含有变量的而且它又不能一次性处理多个文件。所以要想循环处理多个txt文件还是必须在文件名上进行改变。

另外首先txt文件名必须是连续的能循环读取的,所以首先使用好压对500多个txt文件进行批量命名,这样有助循环:



对于含变量的文件名此处提出的方法是用字符串数组来解决。

如下代码:

clear all;
a=3;
b=1;
testTime=[];
startTime1=[];
startAE1=[];
for c=100:1746
file_name=[num2str(a) '_' num2str(b)'_' num2str(c)'.txt'];%×¢ÒâÖмäÓпոñ
fileOut=fopen(file_name);
y=[];
line=0;
while ~feof(fileOut)
   tLine=fgetl(fileOut);
   line=line+1;
   if line==11
   testTime=[testTimestr2double(tLine(18:33))];
   end
   if line==12
     continue;
   end
   if double(tLine(2))>=48&&double(tLine(2))<=57
      %fprintf(fileIn,'%s\r\n',tLine);
      y=[y str2double(tLine)];
      continue;
  end
 
end
如上第8行代码:file_name=[num2str(a) '_' num2str(b)'_' num2str(c)'.txt'];
file_name=[]是一个字符数组,其中一个字符元素都用’’括起来,每个元素之间用空格或,隔开,在matlab中执行上语句可以得到如下结果:



如上图所示,输出的结果file_name就成了完整的文件名,此时在file_name生成的语句中虽然带了变参数,但是生成后file_name中就不含变参数了而是一个成熟的字符串,然后带入fopen()中便可实现对文件名进行改变,从而循环处理多个不同文件。

处理变参数多元非线性方程组

Matlab处理方程组一般用两个函数fsolve和solve,使用fsolve来求解非线性方程(组),描述形式有好几种,但都大同小异。举个例子,[x,fal]=fsolve('function',x0,opt),在这种函数描述中,左边为输出项,分别为目标值和目标函数值,右边括号里分别为函数文件名,假设为funcion,给定初值x0,和优化参数opt,至于opt,可以具体参阅optimset函数,不是很难懂。fsolve是采用最小二乘法来求解非线性方程组如下例子:

%建立函数
function q=myfun(x)
q(1)=x(1)-0.6*sin(x(1))-0.3*cos(x(2));
q(2)=x(2)-0.6*cos(x(1))+0.3*sin(x(2));
%求解函数
% 取初值
x0=[5;5];
options=optimset('Display','off');
x=fsolve(@(x)myfun(x),x0,options);
x1=x(1)
y1=x(2)
运行结果如下:



而采用solve的运行结果如下:



我们可以看到fsolve与solve都可以解除数值解,而实际上solve一般解出为符号解。

现在来看用fsolve解变参数的非线性方程这里变参数是a,b:

function q=myfun(x,a,b)
%定义变参a,b
q(1)=x(1)^2+x(2)^2-a;
q(2)=(x(1)-1)^2+x(2)^2-b;
%解方程
% 设置初值
x0=[5;5];
a=1;
b=1;
options=optimset('Display','off');
x=fsolve(@(x)myfun(x,a,b),x0,options)
x1=x(1)
y1=x(2)
运行结果:



可以看出用fsolve解该方程只得到了一个最优解,而实际上该方程是两个圆相交,所以有两个解。这个最优解的获取是依靠初始值而来的,当初始值给定为x0=[5,-5]时可以取得另一个解。我们再来看看用solve解的结果:



虽然solve得到的是符号解(sym)但是它得到了完整的两个解。虽然在此处说明了solve相对于fsolve在求取有多解方程组中的优势,一个是不用设置初始值,且解不依赖于初始值,二是可以求出完整的解。

但是solve相对于fslove有一个很大的缺点,就是其不能应用于变参数的方程组。因为solve()中的参数是一组方程且类型是字符串,所以不可能带有变参。那么当我们需要解出带有变参数的完整解时该怎么用solve实现呢?这个时候可以用上面含有变参数文件名的方法。即使先用用字符串数组生成方程字符串数组,然后把字符串带入solve中。例如下代码:

%解含变参数的非线性方程组
for i=1:n
    M=(Time1(i)*4500)^2;
    N=(Time2(i)*4500)^2;
    K=(Time3(i)*4500)^2;
    F1=['(x-5)^2+(y-0)^2+(z-7)^2=' num2str(M)];
    F2=['(x-10)^2+(y-6)^2+(z-2)^2=' num2str(N)];
    F3=['(x-0)^2+(y-5)^2+(z-8)^2=' num2str(K)];
    [x,y,z]=solve(F1,F2,F3);
    [k b]=size(x);
    for j=1:k      inter(j)=abs((x(j)-3)^2+(y(j)-10)^2+(z(j)-5)^2-(Time4(i)*4500)^2);
        inter4(j)=subs(inter(j));
 inter(j)=abs((x(j)-5)^2+(y(j)-5)^2+(z(j)-0)^2-(Time5(i)*4500)^2);
        inter5(j)=subs(inter(j));
  inter(j)=abs((x(j)-5)^2+(y(j)-4)^2+(z(j)-10)^2-(Time6(i)*4500)^2);
        inter6(j)=subs(inter(j));
        inter1(j)=var([inter4(j) inter5(j) inter6(j)]);
    end
    min=inter1(1);
    Imin=1;
    for j=1:k
        ifinter1(j)<min&&subs(x(j))>0&&subs(y(j))>0&&subs(z(j))>0
            min=inter1(j);
            Imin=j;
        end
    end
    a=subs(x(Imin));
    b=subs(y(Imin));
    c=subs(z(Imin));
    ifa>=0&&a<=10&&b>=0&&b<=10&&c>=0&&c<=10
        X=[X a];
        Y=[Y b];
        Z=[Z c];
    end
end
如上代码6,7,8行,都是使用了字符串数组的方式来生成方程的。然后在第9行带入了solve中解出完整解。但是需要注意的是,由solve解出的值都是符号解,所以在进行数值运算都要转化为数值解,这里采用的是subs()函数将符号解转化为了数值解。这里我们给出一个简单的例子:

a=1;
b=1;
F1=['x^2+y^2-',num2str(a),'=0'];
F2=['(x-1)^2+y^2-',num2str(b),'=0'];
[x,y]=solve(F1,F2)
运行结果:



以上基本就是关于matlab读取大量文件及matlab处理变参数多元非线性方程的内容。

若有需改进或不足之处,请多多指教。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息