как исправить "только массивы длины 1 могут быть преобразованы в скаляры Python" при получении интеграла с аргументом массива - PullRequest
0 голосов
/ 16 февраля 2019

Я использую квад из scipy.integrate, чтобы получить интеграл в ограниченном диапазоне от объекта.Предположим, что целевой объект находится в ударе:

∫expm(A*X).expm(B*X)dx

, где A и B. являются матовой матрицей.

Чтобы решить эту проблему, я использовал код удара:

from scipy.integrate import quad
from scipy.linalg import expm
import numpy as np

def integrand(X, A, B):
    return np.dot(expm(A*X),expm(B*X))


A = np.array([[1, 2], [3, 4]])
B = np.array([[1, 2], [3, 4]])

I= quad(integrand, 0, 1, args=(A,B))

Но для результата я получаю эту ошибку:

TypeError: only length-1 arrays can be converted to Python scalars

Я знаю, что ошибка "только массивы длины 1 могут быть преобразованы в скаляры Python" возникает, когда функция ожидает одно значение, но вы передаетемассив вместо.но моя проблема основана на массиве.так как я могу это исправить.

1 Ответ

0 голосов
/ 18 февраля 2019

Как указано в комментариях, quad ожидает скалярную функцию.Вы всегда можете передать функцию в скаляр, добавив индекс в качестве вывода:

def integrand(X, A, B, ix=None):
    """ pass ix=None to return the matrix, ix = 0,1,2,3 to return an element"""
    output = np.dot(expm(A*X),expm(B*X))
    if ix is None:
        return output
    i, j = ix//2, ix%2
    return output[i,j]
I= np.array([quad(integrand, 0, 1, args=(A,B, i))[0]
for i in range(4)]).reshape(2,2)
I
>>array([[1031.61668602, 1502.47836021],
       [2253.71754031, 3285.33422634]])

Обратите внимание, что это очень неэффективно, поскольку вы вычисляете интеграл 4 раза, если это вас не беспокоит..

В качестве альтернативы используйте trapz:

x_i = np.linspace(0,1,60)
np.trapz([integrand(x, A, B) for x in x_i], x=x_i, axis=0)
>>array([[1034.46472361, 1506.62915374],
   [2259.94373062, 3294.40845422]])
...