繁体   English   中英

Python中的数学域错误

[英]Math domain error in Python

该程序适用于将变量“ n”的值设置为4的情况,如以下代码所示:

from __future__ import division
from numpy import zeros
import numpy as np
import matplotlib.pyplot as plt

from numpy.linalg import linalg
import math


def getA(kappa):
    matrix = zeros((n, n), float)
    for i in range(n):
        for j in range(n):
            matrix[i][j] = 2*math.cos((2*math.pi/n)*(abs(j-i))*kappa)
    return matrix


def getF(csi, a):
    csiInv = linalg.inv(csi)
    valueF = np.dot(csiInv, a)
    valueF = np.dot(valueF, csiInv)
    valueF = np.dot(valueF, a)
    traceF = valueF.trace()
    return 0.5 * traceF


def getG(csi, f, a):
    csiInv = linalg.inv(csi)
    valueG = np.dot(csiInv, a)
    valueG = np.dot(valueG, csiInv)
    valueG = valueG / (2 * f)
    return valueG


def getE(g, k):
    #m = 10 ^ -6
    #kinv = linalg.inv(k + np.eye(k.shape[1])*m)
    kinv = linalg.inv(k)
    #kinv = linalg.pinv(k)
    ktrans = k.transpose()
    #ktransinv = linalg.pinv(ktrans)
    #ktransinv = linalg.inv(ktrans + np.eye(ktrans.shape[1])*m)
    ktransinv = linalg.inv(ktrans)
    e = np.dot(ktransinv,g)
    e = np.dot(e, kinv)
    return e

def getW(k, a, e):
    ktrans = k.transpose()
    w = np.dot(k, a)
    w = np.dot(w, ktrans)
    w = np.dot(w, e)
    valuew = w.trace()
    return valuew

def getV(csi, e, e2, k):
    v = np.dot(csi, k)
    v = np.dot(v, e)
    v = np.dot(v, k)
    v = np.dot(v, csi)
    v = np.dot(v,  k)
    v = np.dot(v, e2)
    v = np.dot(v, k)
    traceV = v.trace()
    return traceV


handle_2 = open("test.txt", "w")

n = 4


power_spectrum_k = np.zeros(n, float)
for i in range(n):
    power = math.exp(-(2*math.pi*i/n)*(2*math.pi*i/n))
    power_spectrum_k[i] = power

# ora posso chiamare l'anti-trasformata
inverse_transform = np.fft.ifft(power_spectrum_k)
print 'inverse_transform:', inverse_transform
CSI = zeros((n, n))
for i in range(n):
    for j in range(n):
        CSI[i][j] = inverse_transform[abs(i-j)]


betaArray = zeros(n, float)
WabArray = zeros((6, n), float)
correlation = zeros((6, 6), float)

list = [1, 2, 3, 4, 5, 6]

K = zeros((n, n), float)
for i in range(n):
    for j in range(i+1):
        i_shifted = i + 2
        j_shifted = j + 1
        print "###############################"
        print i_shifted
        print j

        component1 = ((3.0*70.0*70.0*0.3)/(2.0*300000.0*300000.0))
        component2 = ((j_shifted*(i_shifted-j_shifted))/(i_shifted))
        component3 = (1.0+(70.0/300000.0)*j_shifted)

        print component1
        print component2
        print component3

        K[i][j] = component1*component2*component3

#print 'DetK:', np.linalg.det(K)
print 'K:\n', K

counter = 0

for alpha in list:
    counter2 = 0
    Aa = getA(alpha)
    Faa = getF(CSI, Aa)
    Ga = getG(CSI, Faa, Aa)
    Ea = getE(Ga, K)
    #print 'Ea:', Ea
    V_alphaalpha = getV(CSI, Ea, Ea, K)
    for beta in xrange(n):
            Ab = getA(beta + 1)
            #print "Calling getW with K=", K, "\n Ab=", Ab, "\nEa=", Ea
            W_ab = getW(K, Ab, Ea)
            #print "\nGot W_ab=", W_ab
            betaArray[beta] = beta + 1
            WabArray[counter][beta] = W_ab
            output_string = " {0} {1} \n".format(str(beta + 1), str(W_ab))
            handle_2.write(output_string)
            Fbb = getF(CSI, Ab)
            Gb = getG(CSI, Fbb, Ab)
            Eb = getE(Gb, K)
    #print "Beta array"
    #print betaArray
    #print "Wab array"
    #print WabArray
    for gamma in list:
        Ac = getA(gamma)
        Fcc = getF(CSI, Ac)
        Gc = getG(CSI, Fcc, Ac)
        Ec = getE(Gc, K)
        V_alphagamma = getV(CSI, Ea, Ec, K)
        V_gammagamma = getV(CSI, Ec, Ec, K)
        C_alphagamma = V_alphagamma/(math.sqrt(V_alphaalpha * V_gammagamma))
        correlation[counter][counter2] = C_alphagamma
        counter2 = counter2 + 1
    counter = counter + 1


print 'correlation:\n', correlation
WabArray_all = []
betaArray_all = []
for b in range(0, len(WabArray), 1):
  for n in betaArray:
    betaArray_all.append(n)
  for n in WabArray[b]:
    WabArray_all.append(n)

现在,一旦我得到n = 5并且任何其他大于4的值,我就会收到错误:

line 148, in <module>
    C_alphagamma = V_alphagamma/(math.sqrt(V_alphaalpha * V_gammagamma))
ValueError: math domain error

由于我执行负值的平方根,因此我将其解释为数学错误。 但是,我无法理解错误的确切位置,因为我无法理解为什么将4更改为5会有所不同。 有谁知道出什么问题了吗?

math.sqrt无法计算负平方根

>>> math.sqrt(-1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: math domain error

如果这是有效的复数数学,请从cmath导入sqrt

>>> cmath.sqrt(-1)
1j

如果不了解算法原理,很难说问题出在哪里。 您将不得不进行更多调查。 恕我直言,您应该尝试转储值以更好地理解问题,但是只有在出现问题时才可以避免输出过多。 就像是 :

try:
    C_alphagamma = V_alphagamma/(math.sqrt(V_alphaalpha * V_gammagamma))
except ValueError as e:
    print alpha, Aa, Faa, Ga, Ea, V_alphaalpha
    print gamma, Ac, Fcc, Gc, Ec, V_alphagamma, V_gammagamma
    raise e

这只是一个想法,其他值可能更相关

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM