Это простая задача перечисления симметрии. Я даю полный обзор, но знание квантовой химии не требуется.
Двухчастичный интеграл : И имеет следующие 4 симметрии: У меня есть функция, которая вычисляет интеграл и сохраняет его в одномерном массиве , проиндексированном следующим образом:⟨ я J | к л ⟩ = ∫ г | * я ( х ) г | * J ( х ' ) г | к ( х ) г | л ( х ' ) ⟨ я J | к л ⟩ = ⟨ J я | л к ⟩ = ⟨ к л | я J ⟩ = ⟨ л к | J я ⟩
int2
int2(ijkl2intindex2(i, j, k, l))
где функция ijkl2intindex2
возвращает уникальный индекс, принимая во внимание вышеуказанные симметрии. Единственное требование состоит в том, что если вы перебираете все комбинации i, j, k, l (от 1 до n каждая), он будет int2
последовательно заполнять массив и назначать один и тот же индекс всем комбинациям ijkl, которые связаны с вышеуказанным 4 симметрии.
Моя текущая реализация в Фортране здесь . Это очень медленно. Кто-нибудь знает, как сделать это эффективно? (На любом языке.)
Подсказка: если орбитали действительны, то в дополнение к вышеуказанным симметриям можно поменять местами и чтобы мы получили всего 8 симметрий: и тогда можно реализовать очень быструю функцию для ее индексации, см. мою реализацию здесь . Я хотел бы найти эффективную схему индексации для случаев, когда орбитали не являются реальными.я ↔ к J ↔ л ⟨ я J | к л ⟩ = ⟨ J я
Примечание: функции, которые я реализовал, фактически принимают четыре числа , , , в так называемой «химической» записи , то есть аргументы и взаимозаменяемы, но это не важно.J K L ( я J | к л ) = ⟨ я K | J л ⟩ J K
источник
Ответы:
[Редактировать: 4-й раз это очарование, наконец-то что-то разумное]
Первый член проще - пары пар, гдеi≥j и , где - треугольный индекс . Это выполняется функцией, подобной этой:t i d ( a , b ) a , btid(i,j)≥tid(k,l) tid(a,b) a,b
где второй цикл происходит потому , что мы не можем гнездо цикл целиком внутрилl l k
Комбинация обоих из них дает полный набор, поэтому объединение обоих циклов дает нам полный набор индексов.
В python мы можем написать следующий итератор, чтобы дать нам значения idx и i, j, k, l для каждого отдельного сценария:
И затем зациклите это так:
источник
Вот идея использования простой кривой заполнения пространства, модифицированной так, чтобы она возвращала один и тот же ключ для случаев симметрии (все фрагменты кода в Python).
Заметки:
Вот тестовый пример для n = 2:
Выход для n = 2:
Если интересно, обратная функция forge_key:
источник
Разве это не просто обобщение задачи индексации упакованной симметричной матрицы? Там есть смещение (i, j) = i * (i + 1) / 2 + j, не так ли? Разве вы не можете удвоить это и проиндексировать двусимметричный 4D массив? Реализация, требующая ветвления, кажется ненужной.
источник