ValueError: matmul: Входной операнд 1 имеет несовпадение в своем основном измерении 0,

Вопрос или проблема

Я новичок в Python и программировании в целом. Я пытаюсь решить особый тип волнового уравнения с помощью метода конечных элементов и выполнить моделирование в Python. У меня возникают ошибки, которые я не понимаю, и мне нужна помощь. Ниже приведена ошибка и, соответственно, часть кода.


ValueError                                Traceback (most recent call last)
<ipython-input-138-b33b0055e38e> in <module>
      6     # Метод конечных элементов
      7     #unew = (dt**2) * Minv @ (f*src[it]  -  K @ u) + 2*u - uold
----> 8     vnew = dt * Minv @ (f*src[it]  -  (Kv @ v) -  (Ku @ u)) + v
      9     v = v, vnew
     10     unew = (dt) * vnew

ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 2 is different from 1000)

Экстраполяция по времени

for it in range(nt):
    # --------------------------------------
    # Метод конечных элементов
    #unew = (dt**2) * Minv @ (f*src[it]  -  K @ u) + 2*u - uold 
    vnew = dt * Minv @ (f*src[it]  -  (Kv @ v) -  (Ku @ u)) + v 
    v = v, vnew
    unew = (dt) * vnew
    #uold, u = u, unew
    u = u, unew

# --------------------------------------
# Метод конечных разностей
pnew = (dt**2) * Mfd @ ( f/dx*src[it]+ D @ p) + 2*p #- pold
p = p, pnew

# --------------------------------------   
# Анимационный график. Отобразить оба решения
if not it % iplot:
    for l in line1:
        l.remove()
        del l
    for l in line2:
        l.remove()
        del l
    line1 = plt.plot(x, v, 'k', lw=1.5, label="МКЭ")
    line2 = plt.plot(x, p, 'r', lw=1.5, label="МКР")
    plt.legend()
    plt.gcf().canvas.draw()

Это связано с вашим стилем кодирования. Ваш код слишком похож на математическую нотацию. Проблемы включают в себя выполнение слишком многого в одной строке и приоритет операторов в Python

Ваш код:

vnew = dt * Minv @ (f*src[it]  -  (Kv @ v) -  (Ku @ u)) + v 

Разделение на более простые выражения позволит упростить отладку.

term_1 = (f*src[it])  -  (Kv @ v) -  (Ku @ u)
term_2 = term_1 + v
term_3 =  Minv @ term_2
vnew = dt * term_3

Ответ или решение

Ошибка ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0 возникает в результате неправильного выравнивания размеров массивов при выполнении операции матричного умножения (с помощью оператора @ в Python).

Анализ ошибки

В данной ошибке указано, что первый операнд для операции matmul (матричного умножения) имеет несовпадающие размеры. Это может произойти, если количество столбцов в первой матрице не совпадает с количеством строк во второй матрице. Сообщение об ошибке также указывает, что размерность 2 отличается от ожидаемого 1000, что говорит о том, что размерность одного из массивов не совпадает с размером другого.

В строке кода, вызывающей ошибку:

vnew = dt * Minv @ (f * src[it] - (Kv @ v) - (Ku @ u)) + v

Обратите внимание на выражение (Kv @ v) и (Ku @ u). Чтобы понять, где именно возникает проблема, нам необходимо рассмотреть размеры всех использованных матриц и векторов:

  1. Minv – вероятно, это матрица, которая должна быть обратной к матрице модуля масс.
  2. f – вектор силы.
  3. src[it] – источник, зависящий от времени.
  4. Kv и Ku – вероятно, матрицы жесткости, также зависящие от значений v и u.

Если Kv имеет размерность (N, M), а v имеет размерность (M, ), то Kv @ v будет иметь размерность (N, ). Если Ku имеет размерность (P, Q), а u имеет размерность (Q, ), то Ku @ u даст размерность (P, ). Теперь, когда вы вычитаете (Kv @ v) и (Ku @ u) внутри скобок, размеры результата должны совпадать.

Как исправить проблему

  1. Проверьте размеры матриц и векторов: Используйте методы, такие как .shape, чтобы выводить размерности всех входных данных перед выполнением операций матричного умножения. Например:

    print(f"Minv shape: {Minv.shape}")
    print(f"f * src[{it}] shape: {(f * src[it]).shape}")
    print(f"Kv shape: {Kv.shape}, v shape: {v.shape}")
    print(f"Ku shape: {Ku.shape}, u shape: {u.shape}")
  2. Обновите код для улучшения читаемости: Как было предложено в предыдущем разделе, разбивайте выражения на более простые этапы. Это не только улучшит читаемость, но и упростит отладку. Например:

    term_1 = (f * src[it]) - (Kv @ v) - (Ku @ u)  # Объединение всех членов
    term_2 = term_1 + v                            # Добавление текущей скорости
    term_3 = Minv @ term_2                         # Применение обратной матрицы массы
    vnew = dt * term_3                             # Умножение на шаг времени
  3. Проверка совместимости: Убедитесь, что все массивы, которые вы собираетесь складывать или вычитать, имеют одинаковую размерность. При необходимости можете использовать функции NumPy для повторного формирования массивов, такие как np.reshape() или np.expand_dims().

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...