Умножьте Eigen :: MatrixXd (m, n) на матрицу 1x1 - PullRequest
1 голос
/ 01 октября 2019

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

Я хочу включить линейную алгебру, поскольку это значительно упрощает пользователю (мне)входные данные и определения функций перехода.

Теперь проблема в том, что может случиться, что некоторый векторный продукт (скаляр) умножается на матрицу. Однако это приводит к несоответствию размеров матрицы в библиотеке Eigen.

Немного предыстории о том, как она должна работать. Я использую std::map<std::string, Eigen::MatrixXd> variables для хранения всех переменных ввода от пользователя. Затем пользователь может ввести некоторую функцию, она автоматически генерируется и компилируется, а затем используется для имитации заданных переходов.

Например:

Пользователь вводит переменные delta_t = 1, a = 0.5, v = 0.0, x = 0.0.

Также функции перехода:

a = a
v = v + a * delta_t
x = x + v * delta_t

Теперь некоторый код генерируется автоматически, и симуляция может запускаться с delta_t = 1 sec для каждого шага симуляции,Это все работает без проблем. Если я теперь использую Векторы вместо скаляров, это становится проблематичным. В данном примере все является матрицей 1x1, поэтому никаких сложностей во время выполнения. Для переменных:

delta_t = 1
a = [0.5, 0.5, 0.5]
v = [0.0, 0.0, 0.0]
x = [0.0, 0.0, 0.0]

и тех же функций перехода я получаю ошибку времени выполнения, так как между dt и a существует несоответствие размеров. Теперь в этой конкретной ситуации я мог бы включить некоторую защиту во время генерации кода, чтобы уловить такие проблемы, однако, если вычисления становятся больше, и, возможно, есть некоторые промежуточные вычисления, которые приводят к скаляру, я не мог бы поймать это раньше без вычисления каждого измерениякаждого матричного / векторного произведения и проверки, если это 1x1. Есть ли способ сделать это вычисление n-by-m * 1-на-1 (лучший случай в собственных) без необходимости вручную проверять размеры для матриц 1-на-1? Если нет, у вас есть идеи, как решить эту проблему? Или я просто упускаю что-то действительно очевидное?

1 Ответ

1 голос
/ 02 октября 2019

Формально матрица 1x1 и скаляр - это не одно и то же. Было бы возможно реализовать Eigen таким образом, что когда матрица (во время выполнения) оказывается 1x1, она должна действовать точно так же, как скаляр (по сути, это то, что делает Matlab). Однако это потребует много дополнительной логики (т. Е. Накладных расходов во время выполнения) и может также скрыть много непреднамеренных ошибок. Кроме того, это нарушит ассоциативность, например,

(Matrix(1,n) *  Matrix(n,1)) * Matrix(m,m)  // possible
 Matrix(1,n) * (Matrix(n,1)  * Matrix(m,m)) // not possible

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


Обратите внимание, что для вашего примера вы могли бы просто написать

v = v + delta_t * a

и так далее, так каквозможно умножение 1x1 на матрицу 1xN. Это работает только до тех пор, пока a является вектором строки, конечно.

...