Аргументы для пользовательских унарных / binaryExpr () eigen3 - PullRequest
0 голосов
/ 11 апреля 2019

Я пытаюсь устранить вложенные циклы, используя операции с коэффициентами для объектов eigen3. Чтобы достичь этого, мне нужно обобщить уже существующую функцию, чтобы я мог выполнять пользовательские операции с коэффициентами.

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

Я хотел бы обобщить следующую функцию

inline Complex expValue(int twoMS, int twoMSPrime, const Matrix2cd& mat)
{
  const Vector2cd& bra = getSpinBasisState(twoMSPrime);
  const Vector2cd& ket = getSpinBasisState(twoMS);

  return bra.adjoint()*mat*ket;
}

Все возможные комбинации значений для двух MS и двух MSPrime, которые я сохранил в массиве, подобном этому

Eigen::ArrayXXd spinCGPart(16, 2);

Итак, 16 различных комбинаций и два столбца, один для двух MS и один для двух MSPrime. Вместо того, чтобы зацикливаться на всех различных комбинациях, я хотел бы реализовать операцию с коэффициентами, например,

Eigen::ArrayXXcd result(16, 1);
result = spinCGPart.col(0).binaryExpr(spinCGPart.col(1), generalExpVal);

Где generalExpVal должно быть что-то вроде

complex generalExpVal(int a, int b, const Matrix2cd& mat) const 
{
  const Vector2cd& bra = getSpinBasisState(b);
  const Vector2cd& ket = getSpinBasisState(a);

  return bra.adjoint()*mat*ket;
}

Я застрял в реализации этой последней функции. Документация для binaryExpr () выглядит так, как будто она не позволяет указывать дополнительные параметры функции. Это тот случай? Мне нужно передать аргумент mat в качестве аргумента, поскольку он постоянно меняется на протяжении всего вычисления. Любое предложение, касающееся собственного или другого подхода к проблеме, будет очень полезно и ценится!

1 Ответ

0 голосов
/ 13 апреля 2019

Все еще не уверен, чего вы на самом деле пытаетесь достичь, но самый простой способ (с C ++ 11 или более поздней версии) ссылаться на дополнительные объекты в вашем двоичном функторе - это использовать лямбда-выражение:

result = spinCGPart.col(0).binaryExpr(spinCGPart.col(1), 
           [&](int a, int b){return generalExpVal(a,b,mat);});

Пример полной компиляции: https://godbolt.org/z/PBJJRW

С C ++ 03 вы можете сделать это вручную, используя вспомогательную структуру или, например, boost::bind.

...