Matlab 计算重极限探讨

Matlab计算重极限探讨

起因是一位同学做题时产生的疑惑,Matlab计算极限使用的方法是累次极限,那么重极限怎么办,尤其是累次极限并不存在的重极限怎么计算?


我先和老师邮件沟通了一下

Matlab 如何计算重极限?
RT,Matlab目前学的是累次极限,就像如下的代码显示的那样,

syms x y
f=x+y;
limit(limit(f,x,inf),y,2)

那么重极限要如何计算?并没有查到任何相关的资源


老师,你的那个截图我看了,但是重极限和累次极限不相等的时候,matlab没有提供一个解决方法,
比如,在如下情况下,x,y 先后取极限,结果是不同的

syms x y;
f=y*sin(1/x);
lxy=limit(limit(f,x,0),y,0)
lyx=limit(limit(f,y,0),x,0)
%结果
xy =
NaN
lyx = 
0

但是x,y同时取极限时,结果是0。
Matlab本身既然没有提供直接计算二重积分的函数来绕过上边分别去极限的情况,那么除了人工去判断还有没有别的办法?


改进,取右侧或左侧的极限?
limit(y,x,0,'right');

syms x y;
f=y*sin(1/x);
lxy=limit(limit(f,x,0),y,0)
lxry=limit(limit(f,x,0,'left'),y,0)

失败。我发现只要先对x取极限,就会得到一个NaN的非数字的东西,所以得写一个函数去执行逻辑判断然后再去计算极限。

看了书,和同学讨论后,如下解决办法

syms x y;
f=y*sin(1/x);
lxy=limit(limit(f,x,0),y,0);
lyx=limit(limit(f,y,0),x,0);
a=isnumeric(lxy);
b=isnumeric(lyx);

% 打算用case重写一个,但是2016/09/10-13:09:25时想起case只能用数值型不能进行逻辑判断。。。继续用if吧
% 重积分逻辑判断核心代码
if a&b==1 %如果两个累次极限都是数值型的话
    if ife(a,b)==1 %如果两个数值型相等的话;这个ife是我自己写的;
        MVlimit=lxy
    else
        MVlimit='not excist'
    end 
else %至少有一个非数值型的
    if a|b ==1 % 有一个数值型的
        if a==1
            MVlimit=lxy
        else
            MVlimit=lyx
        end 
    else %两个累次极限都不存在
        disp(['方法还未知'])
    end 
end 

写到这里我才意识到这都是错的,因为用isnumeric去判断,返回值都是0,也就是说,这些用syms声明得到的结果,本质上都不是数值型的,要用double进行一下转换,修正一下:
还有一个问题是,如果直接用double,那么再用isnumeric去判断就都是数值型了,所以事情的关键就在于如何正确得到lxy和lyx的类型,难不成来一个if去判断是不是NaN之类的?

lxy,lyx类型判断,引入额外的形参m,n
得到数值型的lxy和lyx后,判断是否等于NaN,分别用m,a去储存逻辑判断结果,

根据上述逻辑判断结果,对a,b赋值

NaN的判断用字符串形式改写以后一切都顺利了。但这种思路是有问题的,会让lxy,lyx的双精度表达式是个非常小的数字,所以还得计算一下其和eps的差距是否是可忽略。eps的方法如下

syms x y;
f=y*sin(1/x)+x*sin(1/y);
limx=0;
limy=0;
lxy=limit(limit(f,x,limx),y,limy);
lyx=limit(limit(f,y,limy),x,limx);
if char(lxy)=='NaN'
    a=0;
else
    a=1;
end 
if char(lyx)=='NaN'
    b=0;
else
    b=1;
end 

% a=isnumeric(double(lxy));
% b=isnumeric(double(lyx));
% 打算用case重写一个,但是2016/09/10-13:09:25时想起case只能用数值型不能进行逻辑判断。。。继续用if吧
% 重极限逻辑判断核心代码
if a&b==1 %如果两个累次极限都是数值型的话
    if  abs(lyx-lxy)<1000*eps%如果两个数值型相等的话;
        MVlimit=lxy
    else
        MVlimit='not exist'
    end 
else %至少有一个非数值型的
    if a|b ==1 % 有一个数值型的
        if a==1
            MVlimit=lxy
        else
            MVlimit=lyx
        end 
    else %两个累次极限都不存在
        lxy=limit(limit(f,x,limx+eps),y,limy+eps);
        lyx=limit(limit(f,y,limy+eps),x,limx+eps);
        numlxy=roundn(double(lxy),10);
        numlyx=roundn(double(lyx),10);
        
        %%
        
        if abs(lxy-numlxy)<1000*eps
            lxy=numlxy;
        else
            disp('Error:bug abs(lxy-numlxy)>1000*eps')
            breakif;
        end
        
        %%
        
        if abs(lyx-numlyx)<1000*eps
            lyx=numlyx;
        else
            disp('Error:bug abs(lyx-numlyx)>1000*eps')
            breakif;
        end
        
        if  abs(lyx-lxy)<1000*eps%如果两个数值型相等的话;
            MVlimit=lxy
        else
            MVlimit='not excist'
        end 
    end 
end

哈哈,运行成功接下来就是琢磨怎么把它变成一个独立函数文件了,现在还不能实现一个真正的函数极限计算,需要现在代码中修改若干的,好在我已经将很多需要输入的量变成了独立的变量2016/09/11-10:27:05

重新思考上述代码,发现检验差的绝对值部分是无用的,因为我限制的保留位数是10位,而检验部分是从13位开始检验的,肯定会得到1的结果。

出于 Just for fun的精神,我会把上边的60余行代码自43行开始,加工一下,来记录我的整个思考过程,主要是在我假象的,使用了eps,两个累次极限不都存在的情况下的处理方式

......

        if abs(lxy-numlxy)<1000*eps
            lxy=numlxy;
            m=1;
        else
            disp('Error:bug abs(lxy-numlxy)>1000*eps')
            m=0;
        end
        
        %%
        
        if abs(lyx-numlyx)<1000*eps
            lyx=numlyx;
            n=1;
        else
            disp('Error:bug abs(lyx-numlyx)>1000*eps')
            n=0;
        end
        
        if m==0&n==0  %经过处理仍然是错误的
            MVlimit='not excist'
        else
            if m==1&n==1
                if  abs(lyx-lxy)<1000*eps%如果两个数值型相等的话;
                    MVlimit=lxy
                else
                    MVlimit='not excist'
                end 
            else
                if m==1
                    MVlimit=lxy
                else 
                    MVlimit=lyx
                end
            end
        end
    end 
end

还要完善的:

  • 做成一个独立的函数文件,直接计算极限,不需要手工调整
  • 压缩代码长度,不用这么长,但当然不是说把中间变量全整合到一块去,而是在保证可读性的前提下,让代码缩短
  • 开始缩短代码之前,我想先,是找出问题发生的地方,比如是x逼近时导致的问题,就在那里下手,在极限值加上eps
  • 可以直接使用含有eps的方式去计算。精简后的代码了,不去判断是不是NaN,不管是什么函数,一律用eps处理,但我对这种方法的严谨性持怀疑的态度
Comments
Write a Comment