这说明你在求矩阵时,产生奇异了,我想是你取值太靠近了,这样很容易产生奇异值
你看看你的Z:
Z =
NaN NaN NaN NaN NaN NaN -Inf
NaN NaN NaN NaN NaN NaN -Inf
NaN NaN NaN NaN NaN NaN -Inf
NaN NaN NaN NaN NaN NaN -Inf
NaN NaN NaN NaN NaN NaN -Inf
NaN NaN NaN NaN NaN NaN -Inf
NaN NaN NaN NaN NaN NaN -Inf
把这句改了一下也还是不行,显示矩阵的秩为1,y=09:01:12;
是你取的值太靠近了。
因为你引用gcol[1:]的时候index没有变化,1,2,3,4对应的还是1,3,5,7。只是少了row 0 而已这样你用gcol[1:] - gcol[:]的时候,相减的并不是你想象的, pandas会找相同的index做运算。所以1,2,3,4位置对应的值都一长肌拜可之玖瓣雪抱磨样,减完就是0。row 0位置没有可以减的,就是NaN。所以最后你得到Nan, 0,0,0,0 使用shift可以把value沿着index往下Shift。
说明
这个问题和另外两个问题(编号2051722037141864067、1638082848257894860)基本上是重复的,我已经在那两个问题做了回答,主要原因是匿名函数f0在x比较大、s比较小的情况下会出现非数NaN,导致计算失败。更具体的分析与解决方法这里不再重复,感兴趣的请自行查阅(因度娘经常抽风,就不贴链接了,把编号的数字复制替换本问题的地址中question后面的那一串数字即可)。
这里再对两个问题做进一步探讨:一是对出现NaN的原因做更深入分析,二是把积分下限换成01的误差分析。
1、结果中出现NaN的原因
之前分析过(参见问题2051722037141864067),之所以不能画图,归根到底是由于f0在某些条件下计算结果出现NaN引起的,而NaN又是由于指数项为0、Bessel函数为无穷大导致的。
■ 对于指数函数exp(-x),在什么条件下结果为0?
负指数函数是x的减函数,从数学的角度来说,函数值会逐渐衰减趋近于0,但只要x是有限值,函数值就不真正为0。但从数值在计算机内的表示来说,双精度浮点数只有8个字节,其表示精度与范围都是有限的,可以判断,x为某个有限值的时候,函数值就会小于最小的正浮点数,也就是数值意义上0。
最小的正浮点数可以用realmin获得,但请注意,这个是所谓规格化(normalized)浮点数,而不是最小的浮点数,最小的浮点数是eps(realmin)(或epsrealmin):
>> realminans =
2225073858507201e-308
>> eps(realmin)
ans =
4940656458412465e-324
所谓normalized,是指大于该浮点数的运算能够保证精度,一旦小于realmin,被称为IEEE "denormal",不能再保证运算精度。例如:
>> eps(realmin)/2ans =
0
>> eps(realmin)/199
ans =
4940656458412465e-324
我们看到,这个最小的浮点数除以199仍然等于其自身,除以2则等于0。事实上,这个数的浮点数表达只有最后一个bit是1,其它63bit都是0,一旦除以2或更大的数,就会得到全0的八个字节,也就是0。
了解了最小的浮点数,也就可以知道使得exp(-x)数值上达到0的x值了:
>> x=-log(eps(realmin))+log(2)x =
7451332
>> exp(-x)
ans =
49407e-324
>> exp(-7451333)
ans =
0
也就是说,这个数稍大于745。
■ Bessel函数什么条件下为无穷大?
这个有点遗憾,由于Bessel函数不像exp那样有逆函数可用,使得besseli(0,x)为无穷大的x我只能通过试探大致确定在700-701之间:
>> besseli(0,700)ans =
15296e+302
>> besseli(0,701)
ans =
Inf
当然,可以通过进一步的试探确定更多的有效数字:
>> besseli(0,7009217936944459)ans =
38426e+302
>> besseli(0,700921793694446)
ans =
Inf
■ 函数避免出现NaN的条件
指数项包括两部分,仅以其中一项为例(未包含负号):
ezplot(@(v)(log(v) - u)^2/(2d0),[0 01])可以看到,在v比较小时,仅此一项就会让负指数函数的值为0。另外一项对应的指数也是负数,对应的函数值小于1。可以通过下面的方法大致看到
ezmesh(@(v,x) -((log(v) - u)^2/(2d0))-(k +1)x^2/v^2,[0 01 0 15])zlim([-750 0])
view(0,90)
空白区域即意味着指数小于-750,也就是函数值为0。可见,指数项除了在小部分区域外,大多数条件下的函数值为0,这样,为了避免出现0Inf,重点在于防止Bessel函数出现无穷大的值。而即使指数部分不为0,一旦Bessel函数值为Inf,两项相乘的值为Inf,计算结果同样没有意义。
看一下Bessel函数的变量:
ezplot(@(v,x) 2xsqrt(k(k+1))/v - 700,[0 01 0 50])axis auto
图中曲线的含义是,当v取某个值的时候,x只有小于特定值,Bessel函数才为有限值。这个值大约是对应v=001,x=404;v=01,x=404,也就是说,对于v=001,只能计算大约x<404范围的Bessel函数,v=01时,可计算范围大约是x<404。
这个结论和之前的分析吻合。另一方面,我们可以看到,如果只需要画x=0~15区间的积分函数,可以取积分下限为004。
2、把积分下限换成01的误差分析
按照问题1638082848257894860的分析,把积分下限进行微调成01,对于大部分的函数值没有影响。现在具体看看误差有多大。
由于只是对积分限进行微调,所以需要考虑的只是被积变量v在0~01区间f0函数的情况。这里按照sigma=1来分析(如果按照本题的s分析,几乎没有误差,这一点也可以在问题1638082848257894860里面的曲线看到)。
画出x取不同值的f0-v曲线:
ezplot(@(v)f0(v,0),[0 01])hold on
ezplot(@(v)f0(v,001),[0 01])
ezplot(@(v)f0(v,005),[0 01])
ezplot(@(v)f0(v,01),[0 01])
axis auto
可以看到,x=0对应的曲线值是最大的(应该可以从理论上证明),但最大值也是有界的。对积分下限进行微调导致的误差不会超过这部分积分再乘一个相应的系数。
限于时间精力,这部分的分析未能进一步深入。写了也没几个人看,就先这样吧。
最后,对积分下限取001和01的误差进行比较:
x = 0:001:05;df = arrayfun(@(x)integral(@(v)f0(v,x),001,inf),x) - arrayfun(@(x)integral(@(v)f0(v,x),01,inf),x);
f = (2(k+1)exp(-k)xdf)/(sqrt(2pid0));
plot(x,f,'r');
这也和之前分析的吻合,即只在x比较小的区间(大约02)才有一定误差。而取0001和001的误差更小:
结束语
花费好几个小时写的分析,很大程度上和解决楼主所提问题本身已经没有太大关系,只是为了探究使用MATLAB可能出现的误差或异常现象的深层原因,以便在以后的应用中加以注意。
在此,向楼主提个请求,能否告知这个积分函数的应用背景?花了这么多时间研究这个问题,虽然只是出于个人的爱好,但我把这些拿出来分享的时候,希望能够知道这究竟是哪个领域的问题,谢谢。
可用[x,y,z]=sphere(30);z1=z;z1(4:6,:)=nan;surf(x,y,z,z1);检验一下,只有三个条带没有颜色露出了其它颜色,说明的确只是切了3行。
以上就是关于用matlab画z的图。怎么提示Warning: Matrix is singular to working precision.全部的内容,包括:用matlab画z的图。怎么提示Warning: Matrix is singular to working precision.、python dataframe提取index合并至列、matlab画积分函数曲线等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)