以下代码我在python中进行了SOR迭代

时间:2018-10-23 14:27:35

标签: python

在以下代码中,我在python中进行了SOR迭代。我似乎得到了错误的输出。当它应该解决系统时,似乎只是输出b数组。我的函数或函数调用有问题吗?这是下面的代码!我不认为我的x值应全为1,也不认为它只需要进行一次迭代!当我为较小的x,b,xo运行此代码时,它起作用了!但我尝试将其用于x的10x10,b的10x1和xo的10x1

import numpy as np 
import math 

x = np.array([[3.0, 1.0, 0., 0., 0., 0., 0., 0., 0., 0.],[1.0, 3.0, 1.0, 0., 0., 0., 0., 0., 0., 0.], [0., 1.0, 3.0, 1.0, 0., 0., 0., 0., 0., 0.], [0., 0, 1.0, 3.0, 1.0, 0., 0., 0., 0., 0.], [0., 0., 0., 1.0, 3.0, 1.0, 0., 0., 0., 0.], [0., 0., 0., 0., 1.0, 3.0, 1.0, 0., 0., 0.], [0., 0., 0., 0., 0., 1.0, 3.0, 1.0, 0., 0.], [0., 0., 0., 0., 0., 0., 1.0, 3.0, 1.0, 0.], [0., 0., 0., 0., 0., 0., 0., 1.0, 3.0, 1.0], [0., 0., 0., 0., 0., 0., 0., 0., 1.0, 3.0]])
b = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0])
x0 = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
tol =  10 ** (-15)
max_iter = 20
w = 1.5

def SOR(A, b, x0, tol, max_iter, w): 
    if (w<=1 or w>2): 
        print('w should be inside [1, 2)'); 
        step = -1; 
        x = float('nan') 
        return 
    n = b.shape 
    x = x0 

    for step in range (1, max_iter): 
        for i in range(n[0]): 
            new_values_sum = np.dot(A[i, 1 : (i - 1)], x[1 : (i - 1)]) 
            for j in range(i + 1, n[0]): 
                old_values_sum = np.dot(A[i, j], x0[j]) 
            x[i] = b[i] - (old_values_sum + new_values_sum) / A[i, i] 
            x[i] = np.dot(x[i], w) + np.dot(x0[i], (1 - w))  

        if (np.linalg.norm(x - x0) < tol): 
            print(step) 
            break 

       x0 = x 


    print("X = {}".format(x)) 
    print("The number of iterations is: {}".format(step)) 
SOR(x, b, x0, tol, max_iter, w)

哪个给出以下输出,这不是我想要的

1
X = [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
The number of iterations is: 1

1 个答案:

答案 0 :(得分:2)

new_values_sum和old_values_sum的索引中有错误。对于old_values_sum,for循环没有意义,因为它只是丢弃旧值。

在此之后的行中有括号错误。

对于终止条件,我认为不检查x和x0之间的范数就足够了。

我提供了一些代码来检查解决方案的有效性。

import numpy as np 
import math 

A = np.array([[3.0, 1.0, 0., 0., 0., 0., 0., 0., 0., 0.],[1.0, 3.0, 1.0, 0., 0., 0., 0., 0., 0., 0.], [0., 1.0, 3.0, 1.0, 0., 0., 0., 0., 0., 0.], [0., 0, 1.0, 3.0, 1.0, 0., 0., 0., 0., 0.], [0., 0., 0., 1.0, 3.0, 1.0, 0., 0., 0., 0.], [0., 0., 0., 0., 1.0, 3.0, 1.0, 0., 0., 0.], [0., 0., 0., 0., 0., 1.0, 3.0, 1.0, 0., 0.], [0., 0., 0., 0., 0., 0., 1.0, 3.0, 1.0, 0.], [0., 0., 0., 0., 0., 0., 0., 1.0, 3.0, 1.0], [0., 0., 0., 0., 0., 0., 0., 0., 1.0, 3.0]])
b = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0])
x0 = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
tol =  10 ** (-15)
max_iter = 20
w = 1.5

def SOR(A, b, x0, tol, max_iter, w): 
    if (w<=1 or w>2): 
        print('w should be inside [1, 2)'); 
        step = -1; 
        x = float('nan') 
        return 
    n = b.shape 
    x = x0 

    for step in range (1, max_iter): 
        for i in range(n[0]): 
            new_values_sum = np.dot(A[i, :i], x[:i])
            old_values_sum = np.dot(A[i, i+1 :], x0[ i+1: ]) 
            x[i] = (b[i] - (old_values_sum + new_values_sum)) / A[i, i] 
            x[i] = np.dot(x[i], w) + np.dot(x0[i], (1 - w))  
        #if (np.linalg.norm(x - x0) < tol): 
        if (np.linalg.norm(np.dot(A, x)-b ) < tol):
            print(step) 
            break 
        x0 = x

    print("X = {}".format(x)) 
    print("The number of iterations is: {}".format(step))
    return x
x = SOR(A, b, x0, tol, max_iter, w)
print(np.dot(A, x))

代码产生:

X = [ 0.27638192  0.17085425  0.21105529  0.19597989  0.20100503  0.20100502
  0.1959799   0.21105527  0.17085427  0.27638191]
The number of iterations is: 19
[ 1.00000002  0.99999998  1.00000002  0.99999999  1.00000001  1.          1.
  1.          1.          1.        ]