计算一个144×144的矩阵,使用多个循环。

huangapple go评论52阅读模式
英文:

Calculating a matrix of 144x144 using multiple loops

问题

I have a problem calculating the kuu_s matrix, which is a size of 144x144; the program is only calculating 121x121 elements leaving the first row and columns to 0, and the last 22x22 elements also resulting in 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 = 13 # Updated to 13

# 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')

You should update NMHT_0 to 13 instead of 12 to ensure the program calculates all the 144x144 elements.

英文:

I have a problem calculating the kuu_s matrix ,which is a size of 144x144; the program is only calculating 121x121 elements leaving the first row and columns to 0, and the last 22x22 elements also resulting in 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')

the following pic is from mathcad
计算一个144×144的矩阵,使用多个循环。

I've tried changing the limits of m n i j ,but I get the error of out-of-bound index.
How could I fix the issue so that the program calculates all the 144x144 elements and adds kuu_s to each loop

答案1

得分: 2

我已修复了您的代码中的间距问题,以及评论中提出的问题。以下是结果。它确实生成一个144x144的输出数组。

import numpy as np
import scipy.integrate as spi

# 定义被积函数
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)

# 定义张量的维度
NMHT_0 = 12

# 创建张量
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))

# 执行积分
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')
英文:

I've fixed the spacing problems with your code, plus the issues raised in the comments. This is the result. It does produce a 144x144 output array.

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')

答案2

得分: 1

在创建Kuu_s时,您的循环从1开始,但应该从0开始,因为Python是从零开始索引的。第二个问题是关于起始kq值的问题。将它们从0开始并在循环开始时递增意味着它们首次使用时会等于1,但(如我已经提到的)Python是从零开始索引的,所以您会错过第一行和列。您有两个选择:

  1. kq从0开始并在循环结束时递增它们。
  2. kq从-1开始并在循环开始时递增它们。

我选择使用第二个选项,因为我认为这种方式的代码更清晰,尽管它可能更难阅读。

import numpy as np
from scipy.integrate import quad_vec

# 省略部分代码...

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变得非常大时才会成为问题(即会很慢)。

英文:

When creating Kuu_s, you start your loops at 1, when they should start at 0 because Python is zero-indexed. The second issue is starting your k and q values. Starting them at 0 and incrementing at the start of the loop means they will first be used when they equal 1, but (as I already mentioned) Pyhton is zero-indexed, so you're missing the first row and column. You have two options:

  1. Start k and q at 0 and increment them at the end of the loop.
  2. Start k and q at -1 and increment them at the start of the loop.

I chose to use the second option because I think the code is cleaner that way, though it is arguably less readable.

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")

You'll also note that I got rid of the initial double for loops used for integration in favor of properly using quad_vec for evaluating the integrals. There might be a way to get rid of the large nested loop at the end, but I didn't bother. It will only be a problem (i.e. it will be slow) if NHMT_0 gets very large.

huangapple
  • 本文由 发表于 2023年6月26日 14:24:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76554006.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定