2-я сумма с использованием массива - Python - PullRequest
0 голосов
/ 27 сентября 2018

Я пытаюсь суммировать двумерную функцию, используя метод массива, так или иначе, использование цикла for не выводит правильный ответ.Я хочу найти (в латексе) $$ \ sum_ {i = 1} ^ {M} \ sum_ {j = 1} ^ {M_2} \ cos (i) \ cos (j) $$, где согласно Mathematica ответкогда М = 5 составляет 1,52725.В соответствии с циклом for:

def f(N):
s1=0;
for p1 in range(N):
    for p2 in range(N):
        s1+=np.cos(p1+1)*np.cos(p2+1)
        return s1
print(f(4))

равно 0,291927.

Поэтому я пытался использовать некоторый код вида:

def f1(N):
mat3=np.zeros((N,N),np.complex)
for i in range(0,len(mat3)):
    for j in range(0,len(mat3)):
        mat3[i][j]=np.cos(i+1)*np.cos(j+1)
        return sum(mat3)

, который снова

print(f1(4))

выводит 0,291927.Глядя на массив, мы должны найти для каждого значения i и ja матрицу вида

mat3=[[np.cos(1)*np.cos(1),np.cos(2)*np.cos(1),...],[np.cos(2)*np.cos(1),...]...[np.cos(N+1)*np.cos(N+1)]]

, поэтому для N = 4 мы должны иметь

mat3=[[np.cos(1)*np.cos(1) np.cos(2)*np.cos(1) ...] [np.cos(2)*np.cos(1) ...]...[... np.cos(5)*np.cos(5)]]

, но на самом деле я получаюследующий

mat3=[[0.29192658+0.j 0.+0.j 0.+0.j ... 0.+0.j] ... [... 0.+0.j]]

или матрица всех нулей, кроме элемента mat3 [0] [0].

Кто-нибудь знает правильный способ сделать это и получить правильный ответ?Я выбрал это в качестве примера, потому что проблема, которую я пытаюсь решить, заключается в построении функции, которая суммируется по двум индексам, и функции, которую выводит python, не то же самое, что Mathematica (то есть, функция вида $$ f (Е) = \ sum_ {= 1} ^ {М} \ sum_ {J = 1} ^ {M_2} Р (I, J, E), $$). * * +1023

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Я переместил ваш код в более крошечную версию:

import numpy as np

N = 5
x = np.arange(N) + 1
y = np.arange(N) + 1

x = x.reshape((-1, 1))
y = y.reshape((1, -1))

mat = np.cos(x) * np.cos(y)
print(mat.sum()) # 1.5272472727003474

Хитрость здесь в том, чтобы изменить форму x к столбцу, а y к вектору строки.Если вы умножите их, они будут сопоставлены, как в вашем цикле.

Это должно быть более производительным, поскольку cos() вызывается только 2 * N раз.И это позволяет избежать циклов (плохо в Python).

ОБНОВЛЕНИЕ (относительно вашего комментария):

Этот шаблон может быть расширен в любом измерении.По сути, вы получаете что-то вроде кросс-продукта.Где каждый экземпляр x сопоставляется с каждым экземпляром y, z, u, k, ... Вдоль соответствующих измерений.

Это немного запутанно для описания, поэтому вот еще немного кода:

import numpy as np

N = 5
x = np.arange(N) + 1
y = np.arange(N) + 1
z = np.arange(N) + 1

x = x.reshape((-1, 1, 1))
y = y.reshape((1, -1, 1))
z = z.reshape((1, 1, -1))

mat = z**2 * np.cos(x) * np.cos(y)

# x along first axis
# y along second, z along third
# mat[0, 0, 0] == 1**2 * np.cos(1) * np.cos(1)
# mat[0, 4, 2] == 3**2 * np.cos(1) * np.cos(5)

Если вы используете это для многих измерений и больших значений N, вы столкнетесь с проблемами с памятью.

0 голосов
/ 27 сентября 2018

В вашем примере кода оператор возврата не имеет правильного отступа.Он сразу возвращается в первой итерации цикла.Вместо этого сделайте отступ в теле функции, чтобы завершить оба цикла:

def f(N):
    s1=0;
    for p1 in range(N):
        for p2 in range(N):
            s1+=np.cos(p1+1)*np.cos(p2+1)
    return s1

>>> print(f(5))
1.527247272700347
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...