Hello All, > On May 25, 2012, at 9:56 PM, Luis Emiro Linares Garcia wrote: > > > Jack, > > > > Would you mind to share the details about your fitting code in Mathematica?
I have matlab code that does essentially the same: Given data file 3 columns: wavelength [m], Re(N), Im(N) where N - complex refractive index; Fits the data using guess vector and the limits vectors. Only one specific fit function from matlab is used: lsqnonlin. See the code below: _________________________ WBR, Serge _________________________ % Main function: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % ------------------------------------------------------------------ % Fitting of measured dispersion (n,k files) to get Meep dispersion parameters. % ------------------------------------------------------------------ % Parameters: a=1e-6; % Meep unit in [m] NKfile = 'ITO.nk'; % File with wl, n,k % Fit region: wl_l=350; %lower wavelength, [nm] wl_h=1000; %upper wavelength, [nm] only_plot=0; % set to 1 to only plot the fit % Initial fit vector (guess): % Format of guess and low, upper boundaries (lb,ub): % guess: ['constant epsilon' % 'polarization 1 (sigma omega gamma: 3 numbers)' % 'polarization 2' % 'polarisation N' % 'electric conductivity'] guess = [4.4517 ... 2.5012 0.361 0.0274 ... 1.3517 2.4131 0.4832 ... 0.5522 2.1597 0.4142 ... 0.00001]; % Initial fit vector lb = [1 ... 0 0.1 0 ... 0]; % low boundary ub = [20 ... 1000 10 5 ... 0.0001] ; % high --"-- % End of parameters ------------------------------------------------ % ------------------------------------------------------------------ % Calculates p - MEEP dispersion parameters, the same format as guess. % Note: 'guess' is used when 'p' is not exists, so delete 'p' from matlab % variables to start again with 'quess'. % ------------------------------------------------------------------ % ------------------------------------------------------------------ aSi=dlmread(NKfile,'',0,0); % read file with wl, n, k wl=aSi(:,1); wl = wl/a; % change from metres to Meep units wl_l= wl_l/1e9/a; % change from nm to Meep units wl_h= wl_h/1e9/a; for j=1:length(wl) % cut [wl_l:wl_h] range if wl(j)>=wl_l b=j; break end end for j=1:length(wl) if wl(j)>=wl_h wl=wl(b:j); n=aSi(b:j,2); k=aSi(b:j,3); break end end f = 1./wl; %freq = 1/wavelegth N = n + 1i*k; % complex refr. index Eps = N.^2; % complex dielectic permittivity f1 = max(f):((min(f)-max(f))/100):min(f); Eps = interp1(f,Eps,f1,'spline'); ImReRatio = mean(real(Eps))/mean(imag(Eps)); % Im/Re ratio in fit function fcen=(1/wl_l+1/wl_h)/2; % pulse parameters for Meep df=(1/wl_l-1/wl_h); fprintf(';----------------------------------------------------\n'); fprintf('(define-param fcen %f)\n', fcen); fprintf('(define-param df %f)\n', df); fprintf(';----------------------------------------------------\n'); switch length(guess) case {0,1,2,3} disp('Wrong guess length!') otherwise if(not(exist('p','var'))) p = guess; end p = Lorenzian_fit_N_Econd(f1, Eps, p, lb, ub, only_plot, ImReRatio); fprintf(';----------------------------------------------------\n'); fprintf('; fitted "%s" for wl=[%g:%g]*%g [m]\n', NKfile, wl_l, wl_h, a); fprintf('(define TCO (make medium (epsilon %g) (D-conductivity %g)\n',... p(1), p(length(p))); fprintf('\t(E-polarizations\n'); for n=1:((length(p)-2)/3) fprintf('\t\t(make polarizability (sigma %g) (omega %g) (gamma %g))\n',... p(3*(n-1)+1+1), p(3*(n-1)+1+2), p(3*(n-1)+1+3)); end fprintf(')))\n'); fprintf(';----------------------------------------------------\n'); end % Fit function: ----------------------------------------------------------- function [p, fEps] = Lorenzian_fit_N_Econd(freq, epsilon, p, lb, ub, only_plot, ImReRatio) %#codegen %p(1) - epsilon_infinity %p(2),p(5) - Delta epsilon_n : S(n) %p(3),p(6) - rez. freq. : w(n) %p(4),p(7) - extin.gamma : y(n) %p(last) - conductivity : d_cond coder.extrinsic('int2str', 'strcat', 'inline', 'optimset', 'lsqnonlin',... 'fprintf', 'figure', 'plot'); lrntz = (['(1+i*p(' int2str(length(p)) ')./(2*pi*f)).*(p(1)']); lbl = zeros(length(p),1); ubl = zeros(length(p),1); lbl(1) = lb(1); ubl(1) = ub(1); for n=1:((length(p)-2)/3) % if (length(lb) < 3*n) % expand lb to length(p) lbl(3*(n-1)+1+1) = lb(2); % lb(3*(n-1)+1+2) = p(3*(n-1)+1+2); lbl(3*(n-1)+1+2) = lb(3); lbl(3*(n-1)+1+3) = lb(4); % end % if (length(ub) < 3*n) % expand ub to length(p) ubl(3*(n-1)+1+1) = ub(2); % ub(3*(n-1)+1+2) = p(3*(n-1)+1+2)*1.001; ubl(3*(n-1)+1+2) = ub(3); ubl(3*(n-1)+1+3) = ub(4); % end lrntz = strcat(lrntz,'+','p(',int2str(3*(n-1)+1+1),')*p(',... int2str(3*(n-1)+1+2),')^2./(p(',int2str(3*(n-1)+1+2),... ')^2-f.^2-i*f*p(',int2str(3*(n-1)+1+3),'))'); end lbl(end) = lb(end); ubl(end) = ub(end); lrntz = strcat(lrntz,')'); lorentzian=inline(lrntz, 'p','f'); if (not(only_plot)) lrntz = strcat('[real(',lrntz,')-re,',int2str(ImReRatio),'*(imag(',lrntz,')- im)]'); % lrntz = strcat('[real(', lrntz, ')./re-1,imag(', lrntz, ')./im-1]'); fitfunc=inline(lrntz,'p','f','re','im'); options = optimset('MaxFunEvals',100000,'MaxIter',10000); [p,resnorm]=lsqnonlin(fitfunc,p, lbl,ubl, options, freq,real(epsilon),imag(epsilon)); err = resnorm/(2*length(freq))^2; % print the residual at x: sum(fun(x).^2)/(2*npoints)^2. fprintf('ResNorm/(2*Nfreqs)^2=%g\n', err); end f= min(freq):((max(freq)-min(freq))/100):max(freq); Eps = interp1(freq,epsilon,f); ReEps = real(Eps); ImEps = imag(Eps); %ReEps = interp1(freq,real(epsilon),f); %ImEps = interp1(freq,imag(epsilon),f); EpsFit = lorentzian(p,f); maxStd = max(std(Eps-EpsFit)); createfigureEpsFitting(1, f, [ReEps;ImEps.*ImReRatio], ... f, [real(lorentzian(p,f));imag(lorentzian(p,f)).*ImReRatio],... ImReRatio) % Eps createfigureEpsFitting_wl(2, 1./f, [ReEps;ImEps.*ImReRatio], ... 1./f, [real(lorentzian(p,f));imag(lorentzian(p,f)).*ImReRatio],... ImReRatio, maxStd) % Eps figure(3) plot(1./freq,real(sqrt(epsilon)),'bo', 1./f,real(sqrt(lorentzian(p,f))),'b'); hold on plot(1./freq,imag(sqrt(epsilon)),'ro', 1./f,imag(sqrt(lorentzian(p,f))),'r'); hold off ylabel('n & k') xlabel('wavelength') legend('meas n','fit n','meas k','fit k',0) fEps = [f; lorentzian(p,f)].'; %fnk = flipud([f; real(sqrt(lorentzian(p,f))); imag(sqrt(lorentzian(p,f)))].'); end % Plotting functions: ------------------------------------------------------ function createfigureEpsFitting(nFig, X1, YMatrix1, X2, YMatrix2, ImReRatio) % X1: vector of x data % YMATRIX1: matrix of y data % X1: vector of x data % YMATRIX2: matrix of y data % Auto-generated by MATLAB on 04-Apr-2011 11:46:52 % Create figure figure1 = figure(nFig); % Create axes axes1 = axes('Parent',figure1,'YGrid','on','XGrid','on',... 'Units','centimeters','Position',[1.3 1.25 7 7]); box(axes1,'on'); hold(axes1,'all'); % Create multiple lines using matrix input to plot plot1 = plot(X1,YMatrix1,'Parent',axes1,'LineWidth',2,'LineStyle','--'); set(plot1(1),'MarkerSize',5,'Color',[0 0 1],'DisplayName','\Re(\epsilon)'); set(plot1(2),'Color',[1 0 0],'DisplayName',['\Im(\epsilon)*' num2str(ImReRatio)]); % Create multiple lines using matrix input to plot plot2 = plot(X2,YMatrix2,'Parent',axes1,'LineWidth',2); set(plot2(1),'Color',[0 0 1],'DisplayName','fitted \Re(\epsilon)'); set(plot2(2),'Color',[1 0 0],'DisplayName',['fitted \Im(\epsilon)*' num2str(ImReRatio)]); %plot3 = plot(X2,abs(YMatrix2(2,:)-YMatrix1(2,:)),'Parent',axes1,'LineWidth',2); %set(plot3(1),'Color',[0 1 1],'DisplayName','err \Im(\epsilon)'); % Create ylabel ylabel('\Re(\epsilon) and \Im(\epsilon)','FontSize',10); % Create xlabel xlabel('scaled frequency, [1/\mum]','FontSize',10); % Create legend legend1 = legend(axes1,'show'); set(legend1,'Units','centimeters','Position',[1.4 5.6 3.4 2.5],'FontSize',10); % Create textbox annotation(figure1,'textbox',[0.02 0.024 0.1 0.07],... 'String',{'b)'}, 'FontSize',10, 'FitBoxToText','off','LineStyle','none'); hold(axes1, 'off'); function createfigureEpsFitting_wl(nFig, X1, YMatrix1, X2, YMatrix2, ImReRatio, maxStd) % X1: vector of x data % YMATRIX1: matrix of y data % X1: vector of x data % YMATRIX2: matrix of y data % Create figure figure1 = figure(nFig); % Create axes axes1 = axes('Parent',figure1,'YGrid','on','XGrid','on',... 'Units','centimeters','Position',[1.3 1.25 7 7]); box(axes1,'on'); hold(axes1,'all'); % Create multiple lines using matrix input to plot plot1 = plot(X1,YMatrix1,'Parent',axes1,'LineWidth',2,'LineStyle','--'); set(plot1(1),'MarkerSize',5,'Color',[0 0 1],'DisplayName','\Re(\epsilon)'); set(plot1(2),'Color',[1 0 0],'DisplayName',['\Im(\epsilon)*' num2str(ImReRatio)]); % Create multiple lines using matrix input to plot plot2 = plot(X2,YMatrix2,'Parent',axes1,'LineWidth',2); set(plot2(1),'Color',[0 0 1],'DisplayName','fitted \Re(\epsilon)'); set(plot2(2),'Color',[1 0 0],'DisplayName',['fitted \Im(\epsilon)*' num2str(ImReRatio)]); %plot3 = plot(X2,abs(YMatrix2(2,:)-YMatrix1(2,:)),'Parent',axes1,'LineWidth',2); %set(plot3(1),'Color',[0 1 1],'DisplayName','err \Im(\epsilon)'); % Create ylabel ylabel('\Re(\epsilon) and \Im(\epsilon)','FontSize',10); % Create xlabel xlabel('wavelength, [\mum]','FontSize',10); % Create legend legend1 = legend(axes1,'show'); set(legend1,'Units','centimeters','Position',[1.4 5.6 3.4 2.5],'FontSize',10); % Create textbox annotation(figure1,'textbox',[0.02 0.024 0.1 0.07],... 'String',{'b)'}, 'FontSize',10, 'FitBoxToText','on','LineStyle','none'); annotation(figure1,'textbox',[0.12 0.124 0.1 0.07],... 'String',{['max(std)=' num2str(maxStd,3)]}, 'FontSize',10, 'FitBoxToText','on','LineStyle','none'); hold(axes1, 'off'); __________________________ _______________________________________________ meep-discuss mailing list meep-discuss@ab-initio.mit.edu http://ab-initio.mit.edu/cgi-bin/mailman/listinfo/meep-discuss