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) %定義變參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處理變引數多元非線性方程的內容。
若有需改進或不足之處,請多多指教。