2013-10-01 22 views
2

我有一些實驗數據和理想模型,我想嘗試和擬合。我用模型製作了功能文件 - 代碼如下所示將模型擬合到matlab中的數據

function [ Q,P ] = RodFit(k,C) 
% Function file for the theoretical scattering from a Rod 
% R = radius, L = length 

R = 10; % radius in Å 
L = 1000; % length in Å 
Q = 0.001:0.0001:0.5; 

fun = @(x) ( (2.*besselj(1,Q.*R.*sin(x)))./... 
      (Q.*R.*sin(x)).*... 
      (sin(Q.*L.*cos(x)./2))./... 
      (Q.*L.*cos(x)./2)... 
      ).^2.*sin(x); 

P = (integral(fun,0,pi/2,'ArrayValued',true))*k+C; 

end 

其中Q是x值,P是y值。我可以從matlab命令行中調用該函數,它可以正常工作,例如[Q,P] = RodFit(1,0.001)給我一個結果,我可以使用plot(Q,P)

但我無法確定如何找到最適合某些實驗數據。理想情況下,我想使用優化工具箱和lsqcurvefit,因爲我也可以優化R和L參數。但我不知道如何將(x,y)數據傳遞給lsqcurvefit。我已經用下面的代碼試圖它,但它不工作

File = 30; % the specific observation you want to fit the model to 
ydata = DataFiles{1,File}.data(:,2)'; 
% RAdius = linspace(10,1000,length(ydata)); 
% LEngth = linspace(100,10000,length(ydata)); 
Multiplier = linspace(1e-3,1e3,length(ydata)); 
Constant = linspace(0,1,length(ydata)); 
xdata = [Multiplier; Constant]; % RAdius; LEngth; 
L = lsqcurvefit(@RodFit,[1;0],xdata,ydata); 

它給我的錯誤消息:

Error using * 
Inner matrix dimensions must agree. 
Error in RodFit (line 15) 
P = (integral(fun,0,pi/2,'ArrayValued',true))*k+C; 
Error in lsqcurvefit (line 199) 
     initVals.F = feval(funfcn_x_xdata{3},xCurrent,XDATA,varargin{:}); 
Caused by: 
Failure in initial user-supplied objective function evaluation. LSQCURVEFIT cannot  continue. 

我試圖ⅰ)使所有的向量/矩陣相同的長度和ii)而是嘗試使用.*。沒有任何作品,我給出了相同的錯誤信息

任何形式的幫助將不勝感激,無論是建議調用什麼方法應該使用,建議我的代碼或第三方。

編輯回答Osmoses: 非常好的一點,但我不認爲這是問題所在。剛剛檢查了所有的向量/矩陣的規模,他們應該是好的

>> size(Q) 
ans = 
     1  1780 

>> size(P) 
ans = 
     1  1780 

>> size(xdata) 
ans = 
     2  1780 

>> size([1;0.001]) - the initial guess/start point for xdata (x0) 
ans = 
     2  1 

>> size(ydata) 
ans = 
     1  1780 

UPDATE

我想我已經發現的問題。當我直接指定輸入時,函數RodFit可以正常工作。 [Q,P] = RodFit(1,0.001);

但是,如果我定義X0作爲x0 = [1,0.001]我無法通過x0至功能

>> x0 = [1;0.001] 

x0 = 

1.0000 
0.0010 

>> RodFit(x0); 
Error using * 
Inner matrix dimensions must agree. 

Error in RodFit (line 15) 
P = (integral(fun,0,pi/2,'ArrayValued',true))*k+C; 

同樣的情況,如果我使用x0 = [1,0.001] 清楚,MATLAB是解釋X0作爲輸入僅k並嘗試多重一個長度矢量(ydata)和長度矢量(x0)明顯失敗。

所以我的問題是,我需要的代碼,以便lsqcurvefit瞭解到,外部數據和X0的第一列是k變量和外部數據的第二列和X0是C變量。根據文檔 - Passing Matrix Arguments - 我應該能夠將x0作爲矩陣傳遞給解算器。解算器也應該以x0格式傳遞xdata。

回答

0

你有沒有試過(有時候是錯誤)看你的輸入數據的方向(例如,如果xdata & ydata都是行/列向量?)。除此之外,你的代碼看起來應該起作用。

0

我已經能夠解決一些問題。我的代碼中的一個錯誤是,目標函數沒有使用向量變量,而是使用了兩個變量 - k和C.與上面的代碼改變代碼以接受的載體解決了這個問題

function [ Q,P ] = RodFit(X) 
% Function file for the theoretical scattering from a Rod 
% R = radius, L = length 

% Q = 0.001:0.0001:0.5; 
Q = linspace(0.11198,4.46904,1780); 
fun = @(x) ( (2.*besselj(1,Q.*R.*sin(x)))./... 
      (Q.*R.*sin(x)).*... 
      (sin(Q.*L.*cos(x)./2))./... 
      (Q.*L.*cos(x)./2)... 
      ).^2.*sin(x); 

P = (integral(fun,0,pi/2,'ArrayValued',true))*X(1)+X(2); 

,我可以定義爲X0 x0 = [1 0.001];,並傳遞到RodFit和得到的結果。我也可以將xdata傳入函數並得到一個結果,例如[Q,P] = RodFit(xdata(2,:));

請注意,我已經改變了所有矢量的方向,使他們現在行向量和擴展數據有大小size(xdata) = 1780 2

所以我想我已經完全解決了這個問題,但我仍然會碰到的問題,當我運行lsqcurvefit 。我得到的錯誤信息

Error using RodFit 
Too many input arguments. 

Error in lsqcurvefit (line 199) 
     initVals.F = feval(funfcn_x_xdata{3},xCurrent,XDATA,varargin{:}); 

Caused by: 
Failure in initial user-supplied objective function evaluation. LSQCURVEFIT cannot  continue. 

我不知道爲什麼 - 沒有任何人有關於爲什麼Rodfit臨危許多輸入參數,當我打電話lsqcurvefit但不是當我運行使用外部數據的函數手冊有任何想法?