문제

나는 부유물로 많은 정밀도를 잃고있는 것 같습니다.

예를 들어 매트릭스를 해결해야합니다.

4.0x -2.0y 1.0z =11.0
1.0x +5.0y -3.0z =-6.0
2.0x +2.0y +5.0z =7.0

이것은 텍스트 파일에서 행렬을 가져 오기 위해 사용하는 코드입니다.

f = open('gauss.dat')
lines =  f.readlines()
f.close()

j=0
for line in lines:
    bits = string.split(line, ',')
    s=[]
    for i in range(len(bits)):
        if (i!= len(bits)-1):
            s.append(float(bits[i]))
            #print s[i]
    b.append(s)
    y.append(float(bits[len(bits)-1]))

x, y 및 z의 방정식을 재 배열해야하므로 Gauss-Seidel을 사용하여 해결해야합니다.

x=(11+2y-1z)/4
y=(-6-x+3z)/5
z=(7-2x-2y)/7

다음은 방정식을 재 배열하는 데 사용하는 코드입니다. b 계수의 매트릭스입니다 y 답변 벡터입니다.

def equations(b,y):
    i=0
    eqn=[]
    row=[]
    while(i<len(b)):
        j=0
        row=[]
        while(j<len(b)):
            if(i==j):
                row.append(y[i]/b[i][i])
            else:
                row.append(-b[i][j]/b[i][i])
            j=j+1
        eqn.append(row)
        i=i+1
    return eqn

그러나 내가 돌아 오는 대답은 소수점 자리와 정확하지 않습니다.

예를 들어, 위에서 두 번째 방정식을 재정렬하면 다음을 받아야합니다.

y=-1.2-.2x+.6z

내가 얻는 것은 :

y=-1.2-0.20000000000000001x+0.59999999999999998z

이것은 큰 문제처럼 보이지 않을 수도 있지만 숫자를 매우 높은 전력으로 올리면 오류가 상당히 큽니다. 이것에 대한 방법이 있습니까? 나는 시도했다 Decimal 수업은하지만 힘과 잘 작동하지 않습니다 (즉, Decimal(x)**2).

어떤 아이디어?

도움이 되었습니까?

해결책

나는 당신을 도울 수있는 소수점 클래스에 충분히 익숙하지 않지만, 당신의 문제는 소수점 분수가 종종 이진에 정확하게 표현 될 수 없기 때문에, 당신이보고있는 것은 가장 가까운 근사치입니다. 특별 수업을 사용하지 않고이 문제를 피할 수있는 방법은 없습니다 (아마도 10 진수 등).

EDIT: 소수점 클래스가 당신을 위해 제대로 작동하지 않는 것은 어떻습니까? 플로트가 아닌 줄로 시작하는 한 힘은 잘 작동하는 것 같습니다.

>>> import decimal
>>> print(decimal.Decimal("1.2") ** 2)
1.44

그만큼 모듈 문서 의 필요성과 사용법을 설명합니다 decimal.Decimal 분명히, 당신은 아직 없다면 그것을 확인해야합니다.

다른 팁

IEEE 부동 소수점은 소수점이 아닌 이진입니다. 정확히 0.1 인 고정 길이 이진 분획은 없거나 그 중 어느 것도 없다. 소수점에서 1/3과 같은 반복 분획입니다.

읽어주세요 모든 컴퓨터 과학자가 부동 소수점 산술에 대해 알아야 할 것

소수점 클래스 외에 다른 옵션은 다음과 같습니다

  • 공통 LISP 사용 또는 파이썬 2.6 또는 정확한 합리적인 다른 언어

  • 예를 들어, 복식을 닫는 합리적으로 변환합니다. frap

첫째, 입력을 많이 단순화 할 수 있습니다. 파일을 읽고 구문 분석 할 필요가 없습니다. 파이썬 표기법으로 객체를 선언 할 수 있습니다. 파일을 평가하십시오.

b = [
    [4.0, -2.0,  1.0],
    [1.0, +5.0, -3.0],
    [2.0, +2.0, +5.0],
]
y = [ 11.0, -6.0, 7.0 ]

둘째, y = -1.2-0.20000000000000001x+0.59999999999999998Z는 드문 일이 아닙니다. 이진 표기법에는 0.2 또는 0.6에 대한 정확한 표현이 없습니다. 결과적으로 표시된 값은 원래의 정확한 표현이 아닌 원래의 소수점 근사치입니다. 그것들은 거의 모든 종류의 플로팅 포인트 프로세서에 적용됩니다.

파이썬 2.6을 시도 할 수 있습니다 분수 기준 치수. 나이가 많습니다 합리적인 도움이 될 수있는 패키지.

그렇습니다. 부유 식 점수를 전력으로 올리면 오류가 증가합니다. 결과적으로, 그 비트는 대부분 소음이기 때문에 부동 소수점 수의 가장 올바른 위치를 사용하지 않아야합니다.

부동 소수점 번호를 표시 할 때는 소음 비트가 보이지 않도록 적절하게 반올림해야합니다.

>>> a
0.20000000000000001
>>> "%.4f" % (a,)
'0.2000'

이와 같은 작업에 대해서는 10 진수 모듈에 대해 조심해야합니다. 그것의 목적은 실제로 정확한 정밀 수학을 수행하지 않고 유한 한 정밀도로 실제 소수점 숫자 (예 : 인간 부기 관행 일치)를 실제로 다루고 있습니다. 바이너리에있는 것처럼 소수점에서 정확하게 표현할 수없는 숫자가 있으며, 소수점에서 산술을 수행하는 것도 대안보다 훨씬 느립니다.

대신, 정확한 결과를 원한다면 합리적 산술을 사용해야합니다. 이들은 숫자를 분자/분리기 쌍으로 나타내므로 모든 합리적 숫자를 정확하게 나타낼 수 있습니다. 곱셈과 분할 만 사용하는 경우 (비이성적 인 숫자를 초래할 수있는 정사각형 뿌리와 같은 작업 대신) 정밀도를 잃지 않을 것입니다.

다른 사람들이 언급했듯이 Python 2.6은 내장 합리적 유형을 가질 것입니다. 그러나 이것은 실제로 고성능 구현이 아닙니다. gmpy. Calls를 float ()로 gmpy.mpq ()로 바꾸면 코드가 정확한 결과를 제공해야합니다 (디스플레이 목적으로 결과를 플로트로 형식화 할 수 있지만).

다음은 대신 gmpy retations를 사용하는 매트릭스를로드하기 위해 코드의 약간 정렬 된 버전입니다.

def read_matrix(f):
    b,y = [], []
    for line in f:
        bits = line.split(",")
        b.append( map(gmpy.mpq, bits[:-1]) )
        y.append(gmpy.mpq(bits[-1]))
    return b,y

귀하의 질문에 대한 답이 아니라 관련이 있습니다.

#!/usr/bin/env python
from numpy import abs, dot, loadtxt, max
from numpy.linalg import solve

data = loadtxt('gauss.dat', delimiter=',')
a, b = data[:,:-1], data[:,-1:]
x = solve(a, b) # here you may use any method you like instead of `solve`
print(x)
print(max(abs((dot(a, x) - b) / b))) # check solution

예시:

$ cat gauss.dat
4.0, 2.0, 1.0, 11.0
1.0, 5.0, 3.0, 6.0 
2.0, 2.0, 5.0, 7.0

$ python loadtxt_example.py
[[ 2.4]
 [ 0.6]
 [ 0.2]]
0.0

또한 참조하십시오 부동 소수점 오류의 간단한 예는 무엇입니까?, 여기에는 답이 있습니다. 내가주는 것은 실제로 Python을 예제 언어로 사용합니다 ...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top