注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

东南隅

wantnon的blog

 
 
 

日志

 
 
 
 

meshgrid与ndgrid的原理及实现  

2009-08-19 01:08:51|  分类: matlab |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

[X,Y]=meshgrid(x,y)%得到的X,Y均为二维矩阵,叠合成笛卡尔平面
[X,Y,Z]=meshgrid(x,y,z)%得到的X,Y,Z均为三维矩阵,叠合成笛卡尔立方体
[X1,X2,...,Xn] = ndgrid(x1,x2,...,xn)%得到的X1,X2…Xn均为n维矩阵,叠合成笛卡尔n维立方体
ndgrid是meshgrid的推广,但二者有如下差别:
(下面一段话摘自帮助文档)
The ndgrid function is like meshgrid except that the order of the first two input arguments are switched. That is, the statement
[X1,X2,X3] = ndgrid(x1,x2,x3)
produces the same result as
[X2,X1,X3] = meshgrid(x2,x1,x3)
Because of this, ndgrid is better suited to multidimensional problems that aren't spatially based, while meshgrid is better suited to problems in two- or three-dimensional Cartesian space.
这个在使用时注意。
至于为什么会产生上面差异,可以解释得很清楚:
一般性的ndgrid是与matlab的n维矩阵相一致的(这样实现起来方便),
而meshgrid是为几何(2维或3维)设计的,它不与矩阵保持一致,而是与坐标系保持一致。
而我们知道矩阵与坐标系是不一致的:
矩阵是先定位行,再定位列;而坐标系是先定位X坐标,再定位Y坐标(即先定位列再定位行)。
所以产生了上面差别。
image  
下面分析ndgrid的实现原理:
观察下例:
>> [X,Y]=ndgrid([2,1,3],[7,5])
X =
     2     2
     1     1
     3     3
Y =
     7     5
     7     5
     7     5
可发现如下规律:
X只沿第一维按[2,1,3]变化,而沿第二维无变化;
Y只沿第二维按[7,5]变化,而沿第一维无变化。
(因为矩阵是先定位行再定位列,所以纵向为第一维,横向为第二维)。
由此推知:
[X1,X2,...,Xn] = ndgrid(x1,x2,...,xn)中:
n维矩阵Xi只沿第i维按xi变化,而沿其余各维均无变化。
换句话说:Xi是这样的n维矩阵:
其第i维上的第j层切片
Xi(:,:,…,j,…,:)

=xi(j)*ones(length(x1),length(x2),…,1,…,length(xn))
(其中j和1都是位于第i个位置上)。
知道了这一点,就完全可以自己实现ndgrid的功能了:
以下就是根据上述原理写出的ndgrid的模拟实现myNdgrid:
(可以验证,其与ndgrid输出完全相同)

function varargout=myNdgrid(varargin)
%两种调用方法:
%[X1,X2,X3,...] = myNdgrid(x1,x2,x3,...)
%[X1,X2,...] = myNdgrid(x)
%分别等价于:
%[X1,X2,X3,...] = ndgrid(x1,x2,x3,...)
%[X1,X2,...] = ndgrid(x)

%如果是第二种调用格式,转化成第一种
n=nargin();%维数
if nargin()==1%如果输入参数只有一个
    if nargout()==1%如果输出也只有一个
        varargin{end+1}=varargin{1};%将输入复制成两个,即按二维处理
        n=2;%维数
    else%如果输出有n>=2个
        %将输入复制成与输出个数相同,即按n维处理
        for i=1:nargout()-1
            varargin{end+1}=varargin{1};
        end
        n=length(varargin);%维数
    end
end
%varargin{i}即xi
len=[];%len(i)为xi长度
%填充len
for i=1:n
    len=[len,length(varargin{i})];
end
varargout={};%初始化输出管道
%制作输出量X1~Xn
for i=1:n
    %制作第i个返回值:n维矩阵Xi
    Xi=[];
    for j=1:len(i)
        %填充Xi的第i维上的第j个切片
        %制作命令字符串:
        %'Xi(:,:,…,j,…,:)=varargin{i}(j)*ones(len(1),len(2),…,1,…,len(n));'
        %其中j和i均在第i个位置上
        str='Xi(';
        for k=1:n
            if k==i
                str=[str,'j,'];
            else
                str=[str,':,'];
            end
        end
        str(end)=[];
        str=[str,')=varargin{i}(j)*ones('];
        for k=1:n
            if k==i
                str=[str,'1,'];
            else
                str=[str,'len(',num2str(k),'),'];
            end
        end
        str(end)=[];
        str=[str,');'];
        eval(str);%执行命令
    end%得到Xi
    varargout{end+1}=Xi;%将Xi加入输出管道
end
end

  评论这张
 
阅读(1195)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018