计算一个确定的积分会导致一个非常复杂的数值表达而不是一个数值

时间:2016-10-14 11:42:03

标签: matlab symbolic-math

我正在尝试计算可见光谱中太阳辐射的百分比。
我的代码是:

h=6.626e-34;  %planck constant
c=3e8;        %speed of light
k=1.38066e-23; %boltzman constant
T1=5777;       %temperature in surface of sun  

syms f

J1 =(2*pi*h/(c^2))*((f^3)/(exp((h*f)/(k*T1))-1)); %planck radiation law

hold on;
ezplot(J1,[0,1.5e15])
a=int(J1,f,0,inf)  %total energy radiated
b=int(J1,f,4e14,8e14) %energy between 400-800Thz (visible radiation spectrum)
Vp = (b/a)*100  %percentage of visible/total radiation 

虽然情节与预期完全一样,意味着我没有完全搞砸了,积分的结果是这样的:

Vp = -1888568826285205004703258735621345426367059580820393216707788800000000000*((73396718487075910602267519716779133887030184268951416015625*log(1 - exp(23642358029674224853515625/7114894705749824515342336)))/205953985278202888163058116890711980917418253877248 - (73396718487075910602267519716779133887030184268951416015625*log(1 - exp(23642358029674224853515625/3557447352874912257671168)))/25744248159775361020382264611338997614677281734656 - (2390487322005187985890576650155251369405251302897930145263671875*polylog(2, exp(23642358029674224853515625/3557447352874912257671168)))/1857466834100924357302864708366291649120175241251782656 + (25952248522181378144831874533777514511468878135769288445192954296875*polylog(3, exp(23642358029674224853515625/3557447352874912257671168)))/67008813354583054015095330308295397033299967000474002915328 - (110058495767576691259417256590823904271799518678985866399923893187011219092083*polylog(4, exp(23642358029674224853515625/3557447352874912257671168)))/1888568826285205004703258735621345426367059580820393216707788800000000 + (2390487322005187985890576650155251369405251302897930145263671875*polylog(2, exp(23642358029674224853515625/7114894705749824515342336)))/7429867336403697429211458833465166596480700965007130624 - (25952248522181378144831874533777514511468878135769288445192954296875*polylog(3, exp(23642358029674224853515625/7114894705749824515342336)))/134017626709166108030190660616590794066599934000948005830656 + (110058495767576691259417256590823904271799518678985866399923893187011219092083*polylog(4, exp(23642358029674224853515625/7114894705749824515342336)))/1888568826285205004703258735621345426367059580820393216707788800000000 + 101409666798338314597227594049400067888200283050537109375/22835963083295358096932575511191922182123945984))/(12228721751952965695490806287869322696866613186553985155547099243001246565787*pi^4)

它只是一个数值表达式(不包含任何常量)但我期待(我试图找到)单个值。
任何想法如何克服这个? 提前致谢

double(Vp) 

返回44.3072,这正是我在寻找的时候

vpa(Vp)

返回44.307238264260285485868531074049 + 1.5008384323384489567473242679822e-35 * i被克服

norm(vpa(Vp))

给出与double(Vp)相同的结果

然而,当我添加更多代码行时:

d=int(J1,f,0,4e14);  %infrared energy
e=int(J1,f,8e14,inf); %ultraviolet energy
Ir = (d/a)*100;  %percentage of infrared radiation
Uv = (e/a)*100;  %percentage of ultraviolet radiation

double(Ir)给出了这个错误:

Error using mupadmex
Error in MuPAD command: DOUBLE cannot convert the input expression into a  double array.

If the input expression contains a symbolic variable, use the VPA function  instead.

Error in sym/double (line 514)
    Xstr = mupadmex('symobj::double', S.s, 0);

Error in symplanckradlaw (line 21)
Infrared=double(Ir)

虽然vpa(Ir)和甚至norm(vpa(Ir))给出了复杂的复杂数值表达式

(abs(7.3340024900713941224341547032249e-56*limit((652255981594442743874468745505068648842285814001516463259648*f^2*polylog(2, exp((3873563939581825*f)/466281739436020499437475332096)))/15004497594028668398955870330625 - (608270107310811468411217054651916403272252179121058584901915330886243977872955782952124416*f*polylog(3, exp((3873563939581825*f)/466281739436020499437475332096)))/58120880811771703455030054556291506586990890625 - f^4/4 + (466281739436020499437475332096*f^3*log(1 - exp((3873563939581825*f)/466281739436020499437475332096)))/3873563939581825 + (283625243683820020974472587101002022201492492463545426687503953676410023626686775978867575742611811818507908158310055936*polylog(4, exp((3873563939581825*f)/466281739436020499437475332096)))/225134948049212098682315198853176286979563186266469146812890625, f == 0, Right) - 146.24549829953781858190522266202 - 2.501397387230748261245540446637e-36*i)^2)^(1/2)

2 个答案:

答案 0 :(得分:3)

您可以使用,double

将其转换为double
Vp_double = double(Vp)

如果要选择精度,也可以使用vpa

Vp_vpa = vpa(Vp)

你得到那个非常长的表达式的原因是因为MATLAB设法找到一个“封闭形式的定积分”。即MATLAB设法找到一个准确计算积分的表达式,没有舍入误差。这并不总是可行的,你会收到一个错误:

  

警告:找不到显式积分。

如果发生这种情况,那么您应该尝试this answer中给出的方法。

答案 1 :(得分:0)

由于某种原因,Matlab能够评估此积分中的限制

a=int(J1,f,0,inf)  

在此积分

中将限制评估为0时出现问题
d=int(J1,f,0,4e14);

并在此积分中限制为无限

e=int(J1,f,8e14,inf);

我通过将0代表非常低的值(1e-45)而不是无限的非常大的(1e22)来解决这个问题。 为了我的目的,我得到了非常好的结果,但我仍然发现matlab可以在一个案例中评估限制但在另一个案例中不能评估相同的限制真的很奇怪。