⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gridfit.m

📁 用Matlab语言实现的三维散列数据拟合
💻 M
📖 第 1 页 / 共 3 页
字号:
if length(xnodes)==1  xnodes = linspace(xmin,xmax,xnodes)';  xnodes(end) = xmax; % make sure it hits the maxendif length(ynodes)==1  ynodes = linspace(ymin,ymax,ynodes)';  ynodes(end) = ymax; % make sure it hits the maxendxnodes=xnodes(:);ynodes=ynodes(:);dx = diff(xnodes);dy = diff(ynodes);nx = length(xnodes);ny = length(ynodes);ngrid = nx*ny;% set the scaling if autoscale was onif strcmpi(params.autoscale,'on')  params.xscale = mean(dx);  params.yscale = mean(dy);  params.autoscale = 'off';end% check to see if any tiling is necessaryif (params.tilesize < max(nx,ny))  % split it into smaller tiles. compute zgrid and ygrid  % at the very end if requested  zgrid = tiled_gridfit(x,y,z,xnodes,ynodes,params);else  % its a single tile.    % mask must be either an empty array, or a boolean  % aray of the same size as the final grid.  nmask = size(params.mask);  if ~isempty(params.mask) && ((nmask(2)~=nx) || (nmask(1)~=ny))    if ((nmask(2)==ny) || (nmask(1)==nx))      error 'Mask array is probably transposed from proper orientation.'    else      error 'Mask array must be the same size as the final grid.'    end  end  if ~isempty(params.mask)    params.maskflag = 1;  else    params.maskflag = 0;  end  % default for maxiter?  if isempty(params.maxiter)    params.maxiter = min(10000,nx*ny);  end  % check lengths of the data  n = length(x);  if (length(y)~=n) || (length(z)~=n)    error 'Data vectors are incompatible in size.'  end  if n<3    error 'Insufficient data for surface estimation.'  end  % verify the nodes are distinct  if any(diff(xnodes)<=0) || any(diff(ynodes)<=0)    error 'xnodes and ynodes must be monotone increasing'  end  % do we need to tweak the first or last node in x or y?  if xmin<xnodes(1)    switch params.extend      case 'always'        xnodes(1) = xmin;      case 'warning'        warning(['xnodes(1) was decreased by: ',num2str(xnodes(1)-xmin),', new node = ',num2str(xmin)])        xnodes(1) = xmin;      case 'never'        error(['Some x (',num2str(xmin),') falls below xnodes(1) by: ',num2str(xnodes(1)-xmin)])    end  end  if xmax>xnodes(end)    switch params.extend      case 'always'        xnodes(end) = xmax;      case 'warning'        warning(['xnodes(end) was increased by: ',num2str(xmax-xnodes(end)),', new node = ',num2str(xmax)])        xnodes(end) = xmax;      case 'never'        error(['Some x (',num2str(xmax),') falls above xnodes(end) by: ',num2str(xmax-xnodes(end))])    end  end  if ymin<ynodes(1)    switch params.extend      case 'always'        ynodes(1) = ymin;      case 'warning'        warning(['ynodes(1) was decreased by: ',num2str(ynodes(1)-ymin),', new node = ',num2str(ymin)])        ynodes(1) = ymin;      case 'never'        error(['Some y (',num2str(ymin),') falls below ynodes(1) by: ',num2str(ynodes(1)-ymin)])    end  end  if ymax>ynodes(end)    switch params.extend      case 'always'        ynodes(end) = ymax;      case 'warning'        warning(['ynodes(end) was increased by: ',num2str(ymax-ynodes(end)),', new node = ',num2str(ymax)])        ynodes(end) = ymax;      case 'never'        error(['Some y (',num2str(ymax),') falls above ynodes(end) by: ',num2str(ymax-ynodes(end))])    end  end  % determine which cell in the array each point lies in  [junk,indx] = histc(x,xnodes); %#ok  [junk,indy] = histc(y,ynodes); %#ok  % any point falling at the last node is taken to be  % inside the last cell in x or y.  k=(indx==nx);  indx(k)=indx(k)-1;  k=(indy==ny);  indy(k)=indy(k)-1;  ind = indy + ny*(indx-1);  % Do we have a mask to apply?  if params.maskflag    % if we do, then we need to ensure that every    % cell with at least one data point also has at    % least all of its corners unmasked.    params.mask(ind) = 1;    params.mask(ind+1) = 1;    params.mask(ind+ny) = 1;    params.mask(ind+ny+1) = 1;  end  % interpolation equations for each point  tx = min(1,max(0,(x - xnodes(indx))./dx(indx)));  ty = min(1,max(0,(y - ynodes(indy))./dy(indy)));  % Future enhancement: add cubic interpolant  switch params.interp    case 'triangle'      % linear interpolation inside each triangle      k = (tx > ty);      L = ones(n,1);      L(k) = ny;      t1 = min(tx,ty);      t2 = max(tx,ty);      A = sparse(repmat((1:n)',1,3),[ind,ind+ny+1,ind+L], ...        [1-t2,t1,t2-t1],n,ngrid);    case 'nearest'      % nearest neighbor interpolation in a cell      k = round(1-ty) + round(1-tx)*ny;      A = sparse((1:n)',ind+k,ones(n,1),n,ngrid);    case 'bilinear'      % bilinear interpolation in a cell      A = sparse(repmat((1:n)',1,4),[ind,ind+1,ind+ny,ind+ny+1], ...        [(1-tx).*(1-ty), (1-tx).*ty, tx.*(1-ty), tx.*ty], ...        n,ngrid);  end  rhs = z;  % Build regularizer. Add del^4 regularizer one day.  switch params.regularizer    case 'springs'      % zero "rest length" springs      [i,j] = meshgrid(1:nx,1:(ny-1));      ind = j(:) + ny*(i(:)-1);      m = nx*(ny-1);      stiffness = 1./(dy/params.yscale);      Areg = sparse(repmat((1:m)',1,2),[ind,ind+1], ...        stiffness(j(:))*[-1 1],m,ngrid);      [i,j] = meshgrid(1:(nx-1),1:ny);      ind = j(:) + ny*(i(:)-1);      m = (nx-1)*ny;      stiffness = 1./(dx/params.xscale);      Areg = [Areg;sparse(repmat((1:m)',1,2),[ind,ind+ny], ...        stiffness(i(:))*[-1 1],m,ngrid)];      [i,j] = meshgrid(1:(nx-1),1:(ny-1));      ind = j(:) + ny*(i(:)-1);      m = (nx-1)*(ny-1);      stiffness = 1./sqrt((dx(i(:))/params.xscale).^2 + ...        (dy(j(:))/params.yscale).^2);            Areg = [Areg;sparse(repmat((1:m)',1,2),[ind,ind+ny+1], ...        stiffness*[-1 1],m,ngrid)];      Areg = [Areg;sparse(repmat((1:m)',1,2),[ind+1,ind+ny], ...        stiffness*[-1 1],m,ngrid)];    case {'diffusion' 'laplacian'}      % thermal diffusion using Laplacian (del^2)      [i,j] = meshgrid(1:nx,2:(ny-1));      ind = j(:) + ny*(i(:)-1);      dy1 = dy(j(:)-1)/params.yscale;      dy2 = dy(j(:))/params.yscale;      Areg = sparse(repmat(ind,1,3),[ind-1,ind,ind+1], ...        [-2./(dy1.*(dy1+dy2)), 2./(dy1.*dy2), ...        -2./(dy2.*(dy1+dy2))],ngrid,ngrid);      [i,j] = meshgrid(2:(nx-1),1:ny);      ind = j(:) + ny*(i(:)-1);      dx1 = dx(i(:)-1)/params.xscale;      dx2 = dx(i(:))/params.xscale;      Areg = Areg + sparse(repmat(ind,1,3),[ind-ny,ind,ind+ny], ...        [-2./(dx1.*(dx1+dx2)), 2./(dx1.*dx2), ...        -2./(dx2.*(dx1+dx2))],ngrid,ngrid);    case 'gradient'      % Subtly different from the Laplacian. A point for future      % enhancement is to do it better for the triangle interpolation      % case.      [i,j] = meshgrid(1:nx,2:(ny-1));      ind = j(:) + ny*(i(:)-1);      dy1 = dy(j(:)-1)/params.yscale;      dy2 = dy(j(:))/params.yscale;      Areg = sparse(repmat(ind,1,3),[ind-1,ind,ind+1], ...        [-2./(dy1.*(dy1+dy2)), 2./(dy1.*dy2), ...        -2./(dy2.*(dy1+dy2))],ngrid,ngrid);      [i,j] = meshgrid(2:(nx-1),1:ny);      ind = j(:) + ny*(i(:)-1);      dx1 = dx(i(:)-1)/params.xscale;      dx2 = dx(i(:))/params.xscale;      Areg = [Areg;sparse(repmat(ind,1,3),[ind-ny,ind,ind+ny], ...        [-2./(dx1.*(dx1+dx2)), 2./(dx1.*dx2), ...        -2./(dx2.*(dx1+dx2))],ngrid,ngrid)];  end  nreg = size(Areg,1);  % Append the regularizer to the interpolation equations,  % scaling the problem first. Use the 1-norm for speed.  NA = norm(A,1);  NR = norm(Areg,1);  A = [A;Areg*(params.smoothness*NA/NR)];  rhs = [rhs;zeros(nreg,1)];  % do we have a mask to apply?  if params.maskflag    unmasked = find(params.mask);  end  % solve the full system, with regularizer attached  switch params.solver    case {'\' 'backslash'}      if params.maskflag        % there is a mask to use        % permute for minimum fill in for R (in the QR)        p = colamd(A(:,unmasked));        zgrid=nan(ny,nx);        zgrid(unmasked(p)) = A(:,unmasked(p))\rhs;      else        % permute for minimum fill in for R (in the QR)        p = colamd(A);        zgrid=zeros(ny,nx);        zgrid(p) = A(:,p)\rhs;      end    case 'normal'      % The normal equations, solved with \. Can be fast      % for huge numbers of data points.      if params.maskflag        % there is a mask to use        % Permute for minimum fill-in for \ (in chol)        APA = A(:,unmasked)'*A(:,unmasked);        p = symamd(APA);        zgrid=nan(ny,nx);        zgrid(unmasked(p)) = APA(p,p)\(A(:,unmasked(p))'*rhs);      else        % Permute for minimum fill-in for \ (in chol)        APA = A'*A;        p = symamd(APA);        zgrid=zeros(ny,nx);        zgrid(p) = APA(p,p)\(A(:,p)'*rhs);      end    case 'symmlq'      % iterative solver - symmlq - requires a symmetric matrix,      % so use it to solve the normal equations. No preconditioner.      tol = abs(max(z)-min(z))*1.e-13;      if params.maskflag        % there is a mask to use        zgrid=nan(ny,nx);        [zgrid(unmasked),flag] = symmlq(A(:,unmasked)'*A(:,unmasked), ...          A(:,unmasked)'*rhs,tol,params.maxiter);      else        [zgrid,flag] = symmlq(A'*A,A'*rhs,tol,params.maxiter);        zgrid = reshape(zgrid,ny,nx);      end      % display a warning if convergence problems      switch flag        case 0          % no problems with convergence        case 1          % SYMMLQ iterated MAXIT times but did not converge.          warning(['Symmlq performed ',num2str(params.maxiter), ...            ' iterations but did not converge.'])        case 3          % SYMMLQ stagnated, successive iterates were the same          warning 'Symmlq stagnated without apparent convergence.'        otherwise          warning(['One of the scalar quantities calculated in',...            ' symmlq was too small or too large to continue computing.'])      end    case 'lsqr'      % iterative solver - lsqr. No preconditioner here.      tol = abs(max(z)-min(z))*1.e-13;      if params.maskflag        % there is a mask to use        zgrid=nan(ny,nx);        [zgrid(unmasked),flag] = lsqr(A(:,unmasked),rhs,tol,params.maxiter);      else        [zgrid,flag] = lsqr(A,rhs,tol,params.maxiter);        zgrid = reshape(zgrid,ny,nx);      end      % display a warning if convergence problems      switch flag        case 0          % no problems with convergence        case 1          % lsqr iterated MAXIT times but did not converge.          warning(['Lsqr performed ',num2str(params.maxiter), ...            ' iterations but did not converge.'])        case 3          % lsqr stagnated, successive iterates were the same          warning 'Lsqr stagnated without apparent convergence.'        case 4          warning(['One of the scalar quantities calculated in',...            ' LSQR was too small or too large to continue computing.'])

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -