Example #1
0
def g_u(x):
    """u的梯度(解析值)

    为尽量减少计算与误差,直接代入梯度解析式计算梯度.

    Args:
        x: (theta,phi)^T.

    Returns:
        g: 梯度矢量.
    """
    assert isinstance(x, Matrix), 'x不是Matrix'

    n = int(x.row / 2)
    g = Matrix(zero_mat(2 * n, 1))
    for i in range(n):
        a = 0
        b = 0
        for j in range(n):
            if j != i:
                a -= (sin(x[i][0] - x[j][0]) + cos(x[i][0]) * sin(x[j][0]) *
                      (1 - cos(x[i + n][0] - x[j + n][0]))) / (rij(
                          x[i][0], x[j][0], x[i + n][0], x[j + n][0])**3)
                b -= (sin(x[i][0]) * sin(x[j][0]) *
                      sin(x[i + n][0] - x[j + n][0])) / (rij(
                          x[i][0], x[j][0], x[i + n][0], x[j + n][0])**3)
        g[i][0] = a
        g[i + n][0] = b
    return g
Example #2
0
def fij(n, h, x0, y0):
    """
    线性方程组右侧列向量
    input:剖分数n,步长h,x0,y0
    output:Matrix fij
    """
    n0 = (n - 1) * (n - 1)
    f = Matrix(zero_mat(n0, 1))
    for i in range(1, n):
        for j in range(1, n):
            k = (i - 1) * (n - 1) + j - 1
            f[k][0] = fxy(x0 + i * h, y0 + j * h) * h * h
    return f
Example #3
0
def get_G(n):
    '''
    获取六边形电阻网络的导纳矩阵
    进行星->三角变换后变为等边长三角形网络
    取边上节点数为n,节点标号方式为从一个顶点开始,算作第一层,一次向上取第二层,第三层……
    return Matrix
    '''
    g = Matrix(zero_mat(int((n**2 + n) / 2), int((n**2 + n) / 2)))
    g[0][0] = 1
    g[0][1] = -1 / 2
    g[0][2] = -1 / 2
    i = 1
    for k in range(1, n - 1):
        g[i][i - k] = -1 / 2
        g[i][i + 1] = -1 / 3
        g[i][i + k + 1] = -1 / 2
        g[i][i + k + 2] = -1 / 3
        g[i][i] = 5 / 3
        for j in range(1, k):
            s = i + j
            g[s][s - k - 1] = -1 / 3
            g[s][s - k] = -1 / 3
            g[s][s - 1] = -1 / 3
            g[s][s + 1] = -1 / 3
            g[s][s + k + 1] = -1 / 3
            g[s][s + k + 2] = -1 / 3
            g[s][s] = 2
        s = i + k
        g[s][s - k - 1] = -1 / 2
        g[s][s - 1] = -1 / 3
        g[s][s + k + 1] = -1 / 3
        g[s][s + k + 2] = -1 / 2
        g[s][s] = 5 / 3
        i = s + 1
    g[i][i - n + 1] = -1 / 2
    g[i][i + 1] = -1 / 2
    g[i][i] = 1
    for j in range(1, n - 1):
        s = i + j
        g[s][s - n] = -1 / 3
        g[s][s - n + 1] = -1 / 3
        g[s][s - 1] = -1 / 2
        g[s][s + 1] = -1 / 2
        g[s][s] = 5 / 3
    s = i + n - 1
    g[s][s - n] = -1 / 2
    g[s][s - 1] = -1 / 2
    g[s][s] = 1
    # 带状矩阵,半宽为n
    return g
Example #4
0
def get_G(n):
    '''
    获取三角形电阻网络的导纳矩阵
    取边上节点数为n,节点标号方式为从一个顶点开始,算作第一层,一次向上取第二层,第三层……
    return Matrix
    '''
    g = Matrix(zero_mat(int((n**2 + n) / 2), int((n**2 + n) / 2)))
    g[0][0] = 2
    g[0][1] = -1
    g[0][2] = -1
    i = 1
    for k in range(1, n - 1):
        g[i][i - k] = -1
        g[i][i + 1] = -1
        g[i][i + k + 1] = -1
        g[i][i + k + 2] = -1
        g[i][i] = 4
        for j in range(1, k):
            s = i + j
            g[s][s - k - 1] = -1
            g[s][s - k] = -1
            g[s][s - 1] = -1
            g[s][s + 1] = -1
            g[s][s + k + 1] = -1
            g[s][s + k + 2] = -1
            g[s][s] = 6
        s = i + k
        g[s][s - k - 1] = -1
        g[s][s - 1] = -1
        g[s][s + k + 1] = -1
        g[s][s + k + 2] = -1
        g[s][s] = 4
        i = s + 1
    g[i][i - n + 1] = -1
    g[i][i + 1] = -1
    g[i][i] = 2
    for j in range(1, n - 1):
        s = i + j
        g[s][s - n] = -1
        g[s][s - n + 1] = -1
        g[s][s - 1] = -1
        g[s][s + 1] = -1
        g[s][s] = 4
    s = i + n - 1
    g[s][s - n] = -1
    g[s][s - 1] = -1
    g[s][s] = 2
    # 带状矩阵,半宽为n
    return g
Example #5
0
def get_G(n, w):
    '''
    获取三角形交流网络的导纳矩阵
    取边上节点数为n,节点标号方式为从右下一个顶点开始,算作第一层,一次向上取第二层,第三层……
    return Matrix
    '''
    g = Matrix(zero_mat(int((n**2 + n) / 2), int((n**2 + n) / 2)))
    g[0][0] = 1j * (w - 1 / w)
    g[0][1] = -1j * w
    g[0][2] = 1j / w
    i = 1
    for k in range(1, n - 1):
        g[i][i - k] = -1j * w
        g[i][i + 1] = -1
        g[i][i + k + 1] = -1j * w
        g[i][i + k + 2] = 1j / w
        g[i][i] = 1 + 1j * (2 * w - 1 / w)
        for j in range(1, k):
            s = i + j
            g[s][s - k - 1] = 1j / w
            g[s][s - k] = -1j * w
            g[s][s - 1] = -1
            g[s][s + 1] = -1
            g[s][s + k + 1] = -1j * w
            g[s][s + k + 2] = 1j / w
            g[s][s] = 2 + 2j * (w - 1 / w)
        s = i + k
        g[s][s - k - 1] = 1j / w
        g[s][s - 1] = -1
        g[s][s + k + 1] = -1j * w
        g[s][s + k + 2] = 1j / w
        g[s][s] = 1 + 1j * (w - 2 / w)
        i = s + 1
    g[i][i - n + 1] = -1j * w
    g[i][i + 1] = -1
    g[i][i] = 1 + 1j * w
    for j in range(1, n - 1):
        s = i + j
        g[s][s - n] = 1j / w
        g[s][s - n + 1] = -1j * w
        g[s][s - 1] = -1
        g[s][s + 1] = -1
        g[s][s] = 2 + 1j * (w - 1 / w)
    s = i + n - 1
    g[s][s - n] = 1j / w
    g[s][s - 1] = -1
    g[s][s] = 1 - 1j / w
    # 带状矩阵,半宽为n
    return g
Example #6
0
def initialize_x0(n):
    """初始化电子位置.

    cos(theta)和phi坐标在各自范围内随机取值.

    Args:
        n: 电子数.

    Returns:
        x0: 初始化的位置分布.
    """
    x0 = Matrix(zero_mat(2 * n, 1))
    for i in range(n):
        x0[i][0] = acos(random.uniform(-1, 1))
        x0[i + n][0] = random.uniform(0, 2 * pi)
    return x0
Example #7
0
def solve_R(g, a, b, n):
    '''
    直接法求解标号为a,b节点间的等效电阻R
    return R
    '''
    assert a < b, "b>a不符合规范"

    # 删去g的第a行a列,使其成为非奇异矩阵
    g.pop_col(a)
    g.pop_row(a)

    m = g.row
    # 对称正定矩阵Cholesky分解改进算法,G=LDL^T,带状矩阵优化
    for i in range(m):
        if i < n:
            for j in range(i + 1):
                for k in range(j):
                    g[i][j] = g[i][j] - g[i][k] * g[j][k] / g[k][k]
        else:
            for j in range(i - n, i + 1):
                for k in range(j):
                    g[i][j] = g[i][j] - g[i][k] * g[j][k] / g[k][k]

    # 对电流I进行处理,I=LDI'
    # 求解 LDI'=I 得到 I',下三角前代算法
    I = Matrix(zero_mat(m, 1))
    I[b - 1][0] = 1
    for i in range(m):
        assert g[i][i] != 0, "系数矩阵主元存在‘0’项"
        for j in range(i):
            I[i][0] = I[i][0] - g[i][j] / g[j][j] * I[j][0]
        I[i][0] = I[i][0]
    """
    # 利用(TD)^(-1)特性方法失败
    I = Matrix(zero_mat(m, 1))
    I[b-1][0] = 1
    for i in range(b, m):
        I[i][0] = -g[i][b - 1] / g[b - 1][b - 1]
    """

    g = g.T()
    # 上三角矩阵回代得解

    # 直接调用wheels通法
    x = up_tri_msolve(g, I)
    return x[b - 1][0]
    """
Example #8
0
def get_G(n):
    '''
    获取正方形电阻网络的导纳矩阵
    节点标号方式为从左下起,由左向右,依次取完每行
    return Matrix
    '''
    g = Matrix(zero_mat(n**2, n**2))
    for i in range(n**2):
        for j in range(n**2):
            if (abs(j - i) == 1) | (abs(j - i) == n):
                g[i][j] = -1
                g[i][i] += 1
    for i in range(1, n):
        g[i * n][i * n - 1] = 0
        g[i * n][i * n] -= 1
        g[i * n - 1][i * n] = 0
        g[i * n - 1][i * n - 1] -= 1
    return g
Example #9
0
def coefficientmatrix(n):
    """
    系数矩阵生成, 已包含边界条件‘u=0’
    input: 剖分数  n
    output:系数矩阵A
    """
    n0 = (n - 1) * (n - 1)  # 系数矩阵的维数
    A = Matrix(zero_mat(n0, n0))
    for i in range(0, n0):  # 设置中央对角线
        A[i][i] = 4
    for j in range(0, n - 1):  # 设置里面的两条斜对角线
        for k in range(0, n - 2):
            kk = j * (n - 1) + k
            A[kk][kk + 1] = -1
            A[kk + 1][kk] = -1
    for k in range(0, n0 - n + 1):  # 设置外面的两条斜对角线
        A[k][k + n - 1] = -1
        A[k + n - 1][k] = -1
    return A
Example #10
0
def initialize_x0(n):
    """初始化电子位置.

    cos(theta)和phi坐标在各自范围内均匀取值

    Args:
        n: 电子数.

    Returns:
        x0: 初始化的位置分布.
    """
    x0 = Matrix(zero_mat(2 * n, 1))
    costheta = [1 - i * 2 / (n - 1) for i in range(n)]
    phi = [i * 2 * pi / n for i in range(n)]
    random.shuffle(costheta)
    random.shuffle(phi)
    for i in range(n):
        x0[i][0] = acos(costheta[i])
        x0[i + n][0] = phi[i]
    return x0
Example #11
0
def initialize_x0(n):
    """初始化电子位置.

    cos(theta)和phi坐标在各自范围内随机取值.

    Args:
        n: 电子数.

    Returns:
        x0: 初始化的位置分布.
    """
    x0 = Matrix(zero_mat(2 * n, 1))
    i = 0
    for point in splot(n):
        if i >= n:
            break
        x0[i][0] = point[0]
        x0[i + n][0] = point[1]
        i += 1
    return x0
Example #12
0
def solve_R(g, a, b, n, M, e):
    '''
    迭代法求解标号为a,b节点间的等效电阻R
    return R
    '''
    assert a < b, "b>a不符合规范"

    # 删去g的第a行a列,使其成为非奇异矩阵
    g.pop_col(a)
    g.pop_row(a)

    m = g.row

    # 对电流I进行处理
    I = Matrix(zero_mat(m, 1))
    I[b - 1][0] = 1
    """
    # Jacobi迭代法收敛速度太慢
    # Jacobi迭代法求解 gx=I
    x_0 = Matrix(zero_mat(m, 1))
    for i in range(m):
        x_0[i][0] = 1           # 内置初始解向量
    x = Matrix(zero_mat(m, 1))  # 另一组解向量初始化
    M = 1000     # 内置最大迭代次数100
    e = 1e-10  # 内置判停标准1e-10
    for k in range(M):
        for i in range(m):
            x[i][0] = I[i][0]
            for j in range(m):
                x[i][0] = x[i][0] - g[i][j] * x_0[j][0]
            x[i][0] = x[i][0] / g[i][i] + x_0[i][0]
        if col_abs(x - x_0) < e:
            print("迭代次数: ", k+1)
            break
        elif k == M - 1:
            print("Not converged at given M=", M, " and e=", e)
            break
        x_0 = copy.deepcopy(x)
    """
    # Gauss-Seidel迭代法 + 带状对称矩阵优化
    x = Matrix(zero_mat(m, 1))
    for i in range(m):
        x[i][0] = 1  # 内置初始解向量
    x_0 = Matrix(zero_mat(m, 1))  # 另一组解向量初始化
    for k in range(M):
        x_0 = copy.deepcopy(x)
        if m > 2 * n + 1:
            for i in range(m):
                x[i][0] = I[i][0]
                if i < n:
                    for j in range(i):
                        x[i][0] = x[i][0] - g[i][j] * x[j][0]
                    for j in range(i + 1, i + n + 1):
                        x[i][0] = x[i][0] - g[i][j] * x[j][0]
                    x[i][0] = x[i][0] / g[i][i]
                elif i > m - n - 1:
                    for j in range(i - n, i):
                        x[i][0] = x[i][0] - g[i][j] * x[j][0]
                    for j in range(i + 1, m):
                        x[i][0] = x[i][0] - g[i][j] * x[j][0]
                    x[i][0] = x[i][0] / g[i][i]
                else:
                    for j in range(i - n, i):
                        x[i][0] = x[i][0] - g[i][j] * x[j][0]
                    for j in range(i + 1, i + n + 1):
                        x[i][0] = x[i][0] - g[i][j] * x[j][0]
                    x[i][0] = x[i][0] / g[i][i]
                # 逐次超松弛迭代法
                x[i][0] = -0.9 * x_0[i][0] + 1.9 * x[i][0]
        else:
            for i in range(m):
                x[i][0] = I[i][0]
                for j in range(i):
                    x[i][0] = x[i][0] - g[i][j] * x[j][0]
                for j in range(i + 1, m):
                    x[i][0] = x[i][0] - g[i][j] * x[j][0]
                x[i][0] = x[i][0] / g[i][i]
                # 逐次超松弛迭代法
                x[i][0] = -0.9 * x_0[i][0] + 1.9 * x[i][0]
        if col_abs(x - x_0) < e:
            print("迭代次数: ", k + 1)
            break
        elif k == M - 1:
            print("Not converged at given M=", M, " and e=", e)
            break

    return x[b - 1][0]
Example #13
0
def uxy(x, y):
    """泊松方程真解"""
    return sin(pi * x) * sin(pi * y)


a_x = 0.  # x方向边界
b_x = 1.
c_y = 0.  # y方向边界
d_y = 1.
for m in range(4, 8):
    n = 2**m  # 剖分数
    h = (b_x - a_x) / n  # 步长

    A0 = coefficientmatrix(n)  # 计算系数矩阵
    f_1d = Matrix(zero_mat((n - 1) * (n - 1), 1))  # 代求向量,初始化
    b_matrix = fij(n, h, a_x, c_y)  # 计算右端矩阵b
    f_1d = cg(A0, b_matrix, f_1d)  # 共轭梯度法求解

    uij = []  # 转换成二维矩阵
    fT = f_1d.T().matrix[0]
    zero = [0 for i in range(n + 1)]
    uij.append(zero)
    for i in range(n - 1):
        uij.append([0] + fT[i * (n - 1):(i + 1) * (n - 1):] + [0])
    uij.append(zero)

    El2 = e_l2(uij, n, h, a_x, c_y)  # 计算误差
    print('n=', n, ' 误差: ', El2)

    plt.figure()