#c #numerical-methods #eigen3
#c #численные методы #eigen3
Вопрос:
Я пытаюсь устранить вложенные циклы for, используя операции с коэффициентами для объектов eigen3. Для достижения этой цели я должен обобщить уже существующую функцию таким образом, чтобы я мог использовать пользовательские операции с коэффициентами.
Я обнаружил, что eigen предоставляет две функции, unaryExpr() и BinaryExpr() (документация), которые позволяют реализовать пользовательскую операцию с коэффициентами для собственных массивов. Однако, насколько я понимаю, вы можете предоставить только один или два аргумента этим функциям, которые представляют коэффициенты из самого массива. Я хотел бы также передать другие аргументы этой функции, поскольку мне нужны эти другие аргументы для завершения вычисления.
Я хотел бы обобщить следующую функцию
inline Complex expValue(int twoMS, int twoMSPrime, const Matrix2cdamp; mat)
{
const Vector2cdamp; bra = getSpinBasisState(twoMSPrime);
const Vector2cdamp; ket = getSpinBasisState(twoMS);
return bra.adjoint()*mat*ket;
}
Все возможные комбинации значений для twoMS и twoMSPrime я сохранил в массиве, подобном этому
Eigen::ArrayXXd spinCGPart(16, 2);
Итак, 16 различных комбинаций и два столбца, один для twoMS и один для twoMSPrime.
Вместо того, чтобы перебирать все различные комбинации, я хотел бы реализовать операцию с учетом коэффициентов следующим образом
Eigen::ArrayXXcd result(16, 1);
result = spinCGPart.col(0).binaryExpr(spinCGPart.col(1), generalExpVal);
Где generalExpVal должно быть что-то вроде
complex generalExpVal(int a, int b, const Matrix2cdamp; mat) const
{
const Vector2cdamp; bra = getSpinBasisState(b);
const Vector2cdamp; ket = getSpinBasisState(a);
return bra.adjoint()*mat*ket;
}
Я застрял с реализацией этой последней функции. Документация для BinaryExpr() выглядит так, как будто она не позволяет передавать функции дополнительные параметры. Так ли это? Мне нужно передать mat в качестве аргумента, поскольку он постоянно меняется на протяжении всего вычисления. Любое предложение относительно собственного или другого способа мышления о проблеме было бы очень полезно и оценено!
Комментарии:
1. Если
mat
значение одинаково для каждого коэффициента, функтор, конечно, может просто содержать ссылку на него. Но мне не совсем понятно, что вы хотите сделать. Не могли бы вы опубликовать свою текущую реализацию на основе вложенных циклов?
Ответ №1:
Все еще не уверен, чего вы на самом деле пытаетесь достичь здесь, но самый простой способ (с C 11 или более поздней версии) ссылаться на дополнительные объекты в вашем двоичном функторе — использовать лямбда-выражение:
result = spinCGPart.col(0).binaryExpr(spinCGPart.col(1),
[amp;](int a, int b){return generalExpVal(a,b,mat);});
Пример полной компиляции: https://godbolt.org/z/PBJJRW
С C 03 вы можете сделать это вручную, используя вспомогательную структуру или используя, например, boost::bind
.