1. 程式人生 > >matlab讀取大量檔案及MATLAB處理變引數多元非線性方程組

matlab讀取大量檔案及MATLAB處理變引數多元非線性方程組

關於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) %定義變參ab

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處理變引數多元非線性方程的內容。

若有需改進或不足之處,請多多指教。