Python和Mathematica之间的极小数乘法差异

时间:2019-04-25 22:18:32

标签: python wolfram-mathematica numeric pyfits

第一次使用StackOverflow :),在我的代码上,我有很多非常小的数字,它们彼此相乘,与Mathematica结果(使用相同的代码)相比,错误位于小数点后第四位 >(大约0.02%),即使对于float64精度,也不希望(我也尝试过使用float128精度)。我已经已经尝试使用Decimal lib来实现任意精度。

在某些行上,我有这个等式(出现差异的地方):

(cms0abfactorlist [idxlp1m] * cl [l] + cps0abfactorlist [idxlm] * cl [l + 1])

其中cms0abfactorlist [idxlp1m]大约为0.2〜1,cls [l]大约为10 ^ -16 (似乎不小,但我遇到了问题)。 / p>

cms0abfactorlist和cps0abfactorlist元素由以下内容给出:(l + 2) sqrt((((l + m)(lm))/(4 * l * l-1))其中idxlp1m idxlm给出预先计算的数组的位置。

问题是,我在Mathematica上具有相同的代码,cms0abfactorlist,cps0abfactorlist和cl在两者(python和Mathematica)上相等,我已经对其进行了测试。但是方程式(cms0abfactorlist [idxlp1m] * cl [l] + cps0abfactorlist [idxlm] * cl [l + 1])给出的结果几乎没有差异,约为0.02%。我已经尝试过强制dtype ='float128'数字精度,但问题仍然存在。一个提示是,差异仅取决于'l',而不取决于'm'。这似乎与仅取决于l 的cl [l] 相乘有关。

有人可以帮我吗?谢谢。

代码的重要部分是(我尝试了并行化和不并行化):

import pyfits
import healpy as hp
import numpy as np
import time
import pymp
from math import sqrt

start_time = time.time()
print('Starting')

threads=16
lmax=2002
lmax=int(lmax+1)

########## IMPORTING DATA ##########
alm=pyfits.open('alm.fits')
almimag=np.array(alm[1].data['IMAG'])
almreal=np.array(alm[1].data['REAL'])
almreal=list(almreal)
almimag=list(almimag)
cl=np.array((pyfits.open('cl.fits'))[1].data['TEMPERATURE'],dtype='float64')
#mastermatrix=1;
#gaussianbeam
#noise
#<f>ab,<f>dopp e <f>abdopp==<f>ab+<f>dopp (import or generate)

########## DEFINING FUNCTIONS ##########

def almf( l, m ):
    ellement=almlist[(l*(l+1))+m]
    return ellement;
def almfconjugate( l, m ):
    ellement=almlistconjugate[(l*(l+1))+m]
    return ellement;
def cps0factor( l, m):
    return sqrt(((l+1+m)*(l+1-m))/((4*(l+1)*(l+1)-1)))
def cms0factor( l, m):
    return -1*sqrt(((l+m)*(l-m))/(4*l*l-1))
def cps1factor( l, m):
    return -1*sqrt(((l+2+m)*(l+m+1))/((4*(l+1)*(l+1)-1)*(2)))
def cms1factor( l, m):
    return -1*sqrt(((l+m-1)*(l+m))/((4*l*l-1)*(2)))

########## CALCULATING c+ AND c- ##########

cps0abfactorlist=pymp.shared.array((hp.Alm.getsize(lmax=lmaxalm)*2-lmaxalm,), dtype='float64')
cms0abfactorlist=pymp.shared.array((hp.Alm.getsize(lmax=lmaxalm)*2-lmaxalm,), dtype='float64')
cps0doppfactorlist=pymp.shared.array((hp.Alm.getsize(lmax=lmaxalm)*2-lmaxalm,), dtype='float64')
cms0doppfactorlist=pymp.shared.array((hp.Alm.getsize(lmax=lmaxalm)*2-lmaxalm,), dtype='float64')
with pymp.Parallel(threads) as p:
    for l in p.range(lmaxalm+1):
        idxl=l*(l+1)
        for m in range(-l,l+1):
            idxlm=idxl+m
            cps0=cps0factor( l, m)
            cms0=cms0factor( l, m)
            cps0abfactorlist[idxlm]=(l+2)*cps0
            cms0abfactorlist[idxlm]=(l-1)*cms0
            cps0doppfactorlist[idxlm]=-cps0
            cms0doppfactorlist[idxlm]=cms0

elapsed_time = time.time() - start_time
print('cp and cm generated') 
print(elapsed_time,'secs')  

########## CALCULATING <f> AND <g> (h) ##########

symarraysize=hp.Alm.getsize(lmax=lmax)*2-lmax-2
notsymarraysize=hp.Alm.getsize(lmax=lmax)

hs0ablist=pymp.shared.array((hp.Alm.getsize(lmax=lmax),), dtype='float64')
hs0dopplist=pymp.shared.array((hp.Alm.getsize(lmax=lmax),), dtype='float64')
hs02ablist=pymp.shared.array((hp.Alm.getsize(lmax=lmax),), dtype='float64')
hs02dopplist=pymp.shared.array((hp.Alm.getsize(lmax=lmax),), dtype='float64')

with pymp.Parallel(threads) as p:
    for l in p.range(lmax+1):
        idxl=l*(l+1);idxlp1=(l+1)*(l+2);
        for m in range(1,l):
            idxlm=idxl+m;idxlp1m=idxlp1+m;
            abcoef=(cms0abfactorlist[idxlp1m]*cl[l]+cps0abfactorlist[idxlm]*cl[l+1])
            doppcoef=(cms0doppfactorlist[idxlp1m]*cl[l]+cps0doppfactorlist[idxlm]*cl[l+1])
            hs0ablist[int((idxl/2)+m)]=abcoef
            hs02ablist[int((idxl/2)+m)]=2*abcoef
            hs0dopplist[int((idxl/2)+m)]=doppcoef
            hs02dopplist[int((idxl/2)+m)]=2*doppcoef
        for m in [l]:
            idxlm=idxl+m;idxlp1m=idxlp1+m;
            abcoef=(cms0abfactorlist[idxlp1m]*cl[l]+cps0abfactorlist[idxlm]*cl[l+1])
            doppcoef=(cms0doppfactorlist[idxlp1m]*cl[l]+cps0doppfactorlist[idxlm]*cl[l+1])
            hs0ablist[int((idxl/2)+m)]=abcoef
            hs02ablist[int((idxl/2)+m)]=2*abcoef
            hs0dopplist[int((idxl/2)+m)]=doppcoef
            hs02dopplist[int((idxl/2)+m)]=2*doppcoef
        for m in [0]:
            idxlm=idxl+m;idxlp1m=idxlp1+m;
            hs0ablist[int((idxl/2)+m)]=(cms0abfactorlist[idxlp1m]*cl[l]+cps0abfactorlist[idxlm]*cl[l+1])
            hs02ablist[int((idxl/2)+m)]=(cms0abfactorlist[idxlp1m]*cl[l]+cps0abfactorlist[idxlm]*cl[l+1])
            hs0dopplist[int((idxl/2)+m)]=(cms0doppfactorlist[idxlp1m]*cl[l]+cps0doppfactorlist[idxlm]*cl[l+1])
            hs02dopplist[int((idxl/2)+m)]=(cms0doppfactorlist[idxlp1m]*cl[l]+cps0doppfactorlist[idxlm]*cl[l+1])

0 个答案:

没有答案