numpy 使用多个循环计算144x144的矩阵

egdjgwm8  于 2023-06-29  发布在  其他
关注(0)|答案(2)|浏览(97)

我在计算kuu_s矩阵时遇到问题,该矩阵的大小为144 x144;程序只计算121 × 121个元素,第一行和第一列为0,最后22 × 22个元素也为0。

import numpy as np
import scipy.integrate as spi

# Define the integrand function
def f0(x,n):
    if n == 1:
        return (1-x)
    elif n == 2:
        return x
    else:
        return np.sin((n - 2) * np.pi * x)

def f1(x,n):
    if n == 1:
        return -1
    elif n == 2:
        return 1
    else:
        return np.cos((n - 2)*np.pi*x)*(n-2)*np.pi

def f00(x, m, n):
        return f0(x,m)*f0(x,n)

def f11(x, m, n):
    return f1(x,m)*f1(x,n)

def f10(x, m, n):
        return f1(x,m)*f0(x,n)
def f01(x, m, n):
        return f0(x,m)*f1(x,n)
# Define the dimensions of the tensor
NMHT_0 = 12
# Create the tensor
I00 = I11 = I10 = I01 = np.zeros((NMHT_0, NMHT_0))
# Perform the integration
for m in range(1, NMHT_0 ):
    for n in range(1, NMHT_0 ):
        result1, error = spi.quad_vec(f00, 0, 1, args=(m, n)) result2, error2 = spi.quad_vec(f11, 0, 1, args=(m, n)) result3, error3 = spi.quad_vec(f10, 0, 1, args=(m, n)) result4, error4 = spi.quad_vec(f01, 0, 1, args=(m, n))

        I00[m, n] = result1 I11[m, n] = result2  I10[m, n] = result3 I01[m, n] = result4
a = 1
b = 1
A = np.random.rand(5,5)

Kuu_s = np.zeros((NMHT_0 ** 2, NMHT_0 ** 2))

k = 0
for i in range(1, NMHT_0):
     for j in range(1, NMHT_0):
        q = 0
        k += 1
        for m in range(1, NMHT_0):
            for n in range(1, NMHT_0):
                q += 1
                Kuu_s[k, q] += (
                            (A[1, 1] * (1 / a ** 2) * (I11[i, m] * I00[j, n])) +
                            (A[1, 3] * (1 / (a * b)) * (I10[i, m] * I01[j, n] + I01[i, m] * I10[j, n])) +
                            (A[3, 3] * (1 / b ** 2) * (I00[j, n] * I11[i, m]))
                    )

np.savetxt("matrixkuu2.docx",Kuu_s,delimiter='  ',fmt='%1.3e')

以下图片来自mathcad x1c 0d1x
我试过改变m n i j的限制,但我得到了越界索引的错误。我怎样才能修复这个问题,使程序计算所有144 x144的元素并将kuu_s添加到每个循环中

n3h0vuf2

n3h0vuf21#

我已经修复了代码中的间距问题,以及注解中提出的问题。这就是结果。它确实产生144x144输出数组。

import numpy as np
import scipy.integrate as spi

# Define the integrand function
def f0(x,n):
    if n == 1:
        return (1-x)
    elif n == 2:
        return x
    else:
        return np.sin((n - 2) * np.pi * x)

def f1(x,n):
    if n == 1:
        return -1
    elif n == 2:
        return 1
    else:
        return np.cos((n - 2)*np.pi*x)*(n-2)*np.pi

def f00(x, m, n):
    return f0(x,m)*f0(x,n)
def f11(x, m, n):
    return f1(x,m)*f1(x,n)
def f10(x, m, n):
    return f1(x,m)*f0(x,n)
def f01(x, m, n):
    return f0(x,m)*f1(x,n)

# Define the dimensions of the tensor
NMHT_0 = 12

# Create the tensor
I00 = np.zeros((NMHT_0, NMHT_0))
I11 = np.zeros((NMHT_0, NMHT_0))
I10 = np.zeros((NMHT_0, NMHT_0))
I01 = np.zeros((NMHT_0, NMHT_0))

# Perform the integration
for m in range(NMHT_0):
    for n in range(NMHT_0):
        result1, error1 = spi.quad_vec(f00, 0, 1, args=(m, n))
        result2, error2 = spi.quad_vec(f11, 0, 1, args=(m, n))
        result3, error3 = spi.quad_vec(f10, 0, 1, args=(m, n))
        result4, error4 = spi.quad_vec(f01, 0, 1, args=(m, n))

        I00[m, n] = result1 
        I11[m, n] = result2  
        I10[m, n] = result3 
        I01[m, n] = result4
a = 1
b = 1
A = np.random.rand(5,5)

Kuu_s = np.zeros((NMHT_0 ** 2, NMHT_0 ** 2))

for i in range(NMHT_0):
     for j in range(NMHT_0):
        k = i * NMHT_0 + j
        for m in range(NMHT_0):
            for n in range(NMHT_0):
                q = m * NMHT_0 + n
                Kuu_s[k, q] += (
                        (A[1, 1] * (1 / a ** 2) * (I11[i, m] * I00[j, n])) +
                        (A[1, 3] * (1 / (a * b)) * (I10[i, m] * I01[j, n] + I01[i, m] * I10[j, n])) +
                        (A[3, 3] * (1 / b ** 2) * (I00[j, n] * I11[i, m]))
                )

np.savetxt("matrixkuu2.txt",Kuu_s,delimiter='  ',fmt='%1.3e')
zsohkypk

zsohkypk2#

当创建Kuu_s时,你从1开始循环,而它们应该从0开始,因为Python是零索引的。第二个问题是启动kq值。从0开始并在循环开始时递增意味着它们将在等于1时首次使用,但是(正如我已经提到的)Pyhton是零索引的,因此您将丢失第一行和第一列。您有两个选择:
1.从0开始kq,并在循环结束时递增它们。
1.从-1开始kq,并在循环开始时递增它们。
我选择使用第二个选项,因为我认为这样的代码更清晰,尽管它的可读性较差。

import numpy as np
from scipy.integrate import quad_vec

def f0(x, N):
    res = np.sin((N - 2)*np.pi*x)
    res[N == 1] = (1-x)
    res[N == 2] = x

    return res

def f1(x, N):
    res = np.cos((N - 2)*np.pi*x)*(N-2)*np.pi
    res[N == 1] = -1
    res[N == 2] = 1

    return res

def f00(x, M, N):
    return f0(x, M)*f0(x, N)

def f11(x, M, N):
    return f1(x, M)*f1(x, N)

def f10(x, M, N):
    return f1(x, M)*f0(x, N)

def f01(x, M, N):
    return f0(x, M)*f1(x, N)

NMHT_0 = 12

M, N = np.meshgrid(np.arange(0, NMHT_0), np.arange(0, NMHT_0))
I00, _ = quad_vec(f00, 0, 1, args=(M, N))
I11, _ = quad_vec(f11, 0, 1, args=(M, N))
I10, _ = quad_vec(f10, 0, 1, args=(M, N))
I01, _ = quad_vec(f01, 0, 1, args=(M, N))

a = 1
b = 1
A = np.random.rand(5, 5)

Kuu_s = np.zeros((NMHT_0**2, NMHT_0**2))

k = -1
for i in range(NMHT_0):
    for j in range(NMHT_0):
        k += 1
        q = -1
        for m in range(NMHT_0):
            for n in range(NMHT_0):
                q += 1
                Kuu_s[k, q] = (
                    A[1, 1]*I11[i, m]*I00[j, n]/a**2
                    + A[3, 3]*I00[i, m]*I11[j, n]/b**2
                    + A[1, 3]*(I10[i, m]*I01[j, n]
                               + I01[i, m]*I10[j, n])/a/b
                )

np.savetxt("matrixkuu2.txt", Kuu_s, delimiter="  ", fmt="%1.3e")

您还将注意到,我去掉了用于积分的初始双for循环,而使用了正确的quad_vec来计算积分。可能有一种方法可以摆脱最后的大嵌套循环,但我没有费心。这将是一个问题(即)。如果NHMT_0变得非常大,则会很慢)。

相关问题