├── haskell ├── hie.yaml ├── cabal.project.local ├── fourmolu.yaml ├── test │ └── LatticeSymmetries │ │ ├── GeneratorSpec.hs │ │ ├── ParserSpec.hs │ │ ├── DenseSpec.hs │ │ ├── NonbranchingTermSpec.hs │ │ ├── ComplexRationalSpec.hs │ │ ├── BitStringSpec.hs │ │ ├── ConversionSpec.hs │ │ ├── GroupSpec.hs │ │ └── BenesSpec.hs ├── cbits │ └── init.c ├── LICENSE ├── src │ └── LatticeSymmetries │ │ ├── Yaml.hs │ │ ├── Context.hs │ │ ├── BitString.hs │ │ ├── NonbranchingTerm.hs │ │ ├── ComplexRational.hs │ │ ├── Utils.hs │ │ └── Dense.hs ├── overlay.nix ├── lib │ └── HeaderFileGeneration.hs └── lattice-symmetries-haskell.cabal ├── .hlint.yaml ├── nix ├── python ├── conda │ ├── conda_build_config.yaml │ ├── build.sh │ └── meta.yaml ├── setup.py ├── overlay.nix ├── example │ └── getting_started.py ├── lattice_symmetries │ └── build_extension.py └── test │ └── test_api.py ├── .gitmodules ├── test ├── 03_spin_hcor │ ├── HPhi │ │ ├── output │ │ │ └── zvo_energy.dat │ │ ├── stan.in │ │ ├── greenone.def │ │ ├── locspn.def │ │ ├── hund.def │ │ ├── coulombinter.def │ │ ├── namelist.def │ │ ├── calcmod.def │ │ ├── pairlift.def │ │ ├── exchange.def │ │ ├── modpara.def │ │ ├── pair.def │ │ ├── trans.def │ │ └── greentwo.def │ └── hamiltonian.yaml ├── 01_spin_kagome │ ├── HPhi │ │ ├── output │ │ │ └── zvo_energy.dat │ │ ├── trans.def │ │ ├── stan.in │ │ ├── locspn.def │ │ ├── namelist.def │ │ ├── calcmod.def │ │ ├── modpara.def │ │ ├── hund.def │ │ ├── exchange.def │ │ ├── coulombinter.def │ │ ├── greenone.def │ │ └── pair.def │ └── hamiltonian.yaml ├── 05_hubbard_tri │ ├── HPhi │ │ ├── output │ │ │ └── zvo_energy.dat │ │ ├── stan.in │ │ ├── locspn.def │ │ ├── namelist.def │ │ ├── coulombintra.def │ │ ├── calcmod.def │ │ ├── modpara.def │ │ ├── pair.def │ │ ├── greenone.def │ │ └── trans.def │ └── hamiltonian.yaml ├── 02_spin_ladder_DM │ ├── HPhi │ │ ├── output │ │ │ └── zvo_energy.dat │ │ ├── stan.in │ │ ├── locspn.def │ │ ├── namelist.def │ │ ├── calcmod.def │ │ ├── hund.def │ │ ├── exchange.def │ │ ├── coulombinter.def │ │ ├── modpara.def │ │ ├── greenone.def │ │ ├── pair.def │ │ └── trans.def │ └── hamiltonian.yaml └── 04_hubbard_square │ ├── HPhi │ ├── output │ │ └── zvo_energy.dat │ ├── stan.in │ ├── locspn.def │ ├── namelist.def │ ├── calcmod.def │ ├── coulombintra.def │ ├── modpara.def │ ├── pair.def │ ├── trans.def │ └── greenone.def │ └── hamiltonian.yaml ├── .gitignore ├── kernels ├── overlay.nix ├── kernels.h └── default.nix ├── chapel ├── data │ ├── heisenberg_chain_4.yaml │ ├── heisenberg_chain_4_off_diag.yaml │ ├── heisenberg_chain_6.yaml │ ├── heisenberg_chain_8.yaml │ ├── heisenberg_chain_10.yaml │ ├── heisenberg_chain_16.yaml │ ├── heisenberg_chain_20.yaml │ ├── heisenberg_chain_12.yaml │ ├── heisenberg_chain_24.yaml │ ├── heisenberg_chain_28.yaml │ ├── heisenberg_chain_30.yaml │ ├── heisenberg_kagome_16.yaml │ ├── heisenberg_chain_32.yaml │ ├── heisenberg_kagome_12.yaml │ ├── heisenberg_chain_24_symm.yaml │ ├── issue_01.yaml │ ├── heisenberg_chain_32_symm.yaml │ ├── heisenberg_chain_36_symm.yaml │ ├── heisenberg_chain_40_symm.yaml │ ├── heisenberg_chain_42_symm.yaml │ ├── heisenberg_kagome_12_symm.yaml │ ├── heisenberg_chain_44_symm.yaml │ ├── heisenberg_chain_46_symm.yaml │ ├── heisenberg_chain_48_symm.yaml │ ├── heisenberg_square_5x5.yaml │ ├── heisenberg_square_4x4.yaml │ └── heisenberg_square_6x6.yaml ├── test │ ├── TestRoseTree.chpl │ ├── TestStatesEnumeration.chpl │ └── TestMatrixVectorProduct.chpl ├── src │ ├── CommonParameters.chpl │ ├── LatticeSymmetries.chpl │ ├── ConcurrentAccessor.chpl │ ├── library.c │ ├── Utils.chpl │ └── HashedToBlock.chpl ├── benchmark │ ├── BenchmarkStatesEnumeration.chpl │ ├── BenchmarkMatrixVectorProduct.chpl │ └── BenchmarkBlockHashed.chpl ├── default.nix ├── ffi.nix ├── lib │ └── lattice_symmetries_chapel.h └── overlay.nix ├── .clang-tidy ├── .github └── workflows │ ├── ubuntu.yml │ ├── macos.yml │ └── conda.yml ├── template ├── install-jupyter-kernel.sh ├── flake.nix └── flake.lock ├── LICENSE ├── README.md ├── flake.lock └── .clang-format /haskell/hie.yaml: -------------------------------------------------------------------------------- 1 | cradle: 2 | cabal: -------------------------------------------------------------------------------- /.hlint.yaml: -------------------------------------------------------------------------------- 1 | - ignore: {name: Use camelCase} 2 | -------------------------------------------------------------------------------- /nix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twesterhout/lattice-symmetries/HEAD/nix -------------------------------------------------------------------------------- /python/conda/conda_build_config.yaml: -------------------------------------------------------------------------------- 1 | python: 2 | - 3.10 3 | numpy: 4 | - 1.23 5 | -------------------------------------------------------------------------------- /python/conda/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | $PYTHON -m pip install --no-deps . 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third_party/version2"] 2 | path = third_party/version2 3 | url = https://github.com/vectorclass/version2 4 | -------------------------------------------------------------------------------- /test/03_spin_hcor/HPhi/output/zvo_energy.dat: -------------------------------------------------------------------------------- 1 | Energy -5.1653788071251920 2 | Doublon 0.0000000000000000 3 | Sz 3.8905991010945788 4 | -------------------------------------------------------------------------------- /test/01_spin_kagome/HPhi/output/zvo_energy.dat: -------------------------------------------------------------------------------- 1 | Energy -3.0170209179017471 2 | Doublon 0.0000000000000000 3 | Sz 0.5000000000000000 4 | -------------------------------------------------------------------------------- /test/05_hubbard_tri/HPhi/output/zvo_energy.dat: -------------------------------------------------------------------------------- 1 | Energy -17.4356927965492972 2 | Doublon 0.1188490978829830 3 | Sz -0.0000000000000000 4 | -------------------------------------------------------------------------------- /test/02_spin_ladder_DM/HPhi/output/zvo_energy.dat: -------------------------------------------------------------------------------- 1 | Energy -3.0527756377319952 2 | Doublon 0.0000000000000000 3 | Sz -0.0000000000000000 4 | -------------------------------------------------------------------------------- /test/04_hubbard_square/HPhi/output/zvo_energy.dat: -------------------------------------------------------------------------------- 1 | Energy -10.2529529552635879 2 | Doublon 1.0444442739269257 3 | Sz 0.0000000000000000 4 | -------------------------------------------------------------------------------- /test/01_spin_kagome/HPhi/trans.def: -------------------------------------------------------------------------------- 1 | ======================== 2 | NTransfer 0 3 | ======================== 4 | ========i_j_s_tijs====== 5 | ======================== 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | dist-newstyle/ 3 | main 4 | init.o 5 | third_party/ 6 | *.egg-info/ 7 | *.so 8 | *.pyc 9 | result 10 | *.o 11 | .ghc.environment.* 12 | 13 | .nixie 14 | result 15 | -------------------------------------------------------------------------------- /kernels/overlay.nix: -------------------------------------------------------------------------------- 1 | { version 2 | }: 3 | 4 | final: prev: { 5 | lattice-symmetries = (prev.lattice-symmetries or { }) // { 6 | kernels = final.callPackage ./. { inherit version; }; 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /test/04_hubbard_square/HPhi/stan.in: -------------------------------------------------------------------------------- 1 | W = 4 2 | L = 2 3 | model = "FermionHubbard" 4 | method = "Lanczos" 5 | lattice = "Tetragonal" 6 | t = 1.0 7 | U = 4.0 8 | nelec = 8 9 | 2Sz = 0 10 | outputmode = "all" 11 | -------------------------------------------------------------------------------- /test/05_hubbard_tri/HPhi/stan.in: -------------------------------------------------------------------------------- 1 | a0w = 3 2 | a0l = 0 3 | a1w = -1 4 | a1l = 2 5 | model = "HubbardGC" 6 | method = "Lanczos" 7 | lattice = "Triangular" 8 | t = 1.0 9 | t' = 0.5 10 | U = 4.0 11 | outputmode = "all" 12 | -------------------------------------------------------------------------------- /test/01_spin_kagome/HPhi/stan.in: -------------------------------------------------------------------------------- 1 | a0w = 1 2 | a0l = 1 3 | a1w = -1 4 | a1l = 2 5 | model = "Spin" 6 | method = "Lanczos" 7 | lattice = "kagome" 8 | J0 = 1.0 9 | J1 = 0.5 10 | J2 = 0.5 11 | 2Sz = 1 12 | outputmode = "all" 13 | -------------------------------------------------------------------------------- /test/02_spin_ladder_DM/HPhi/stan.in: -------------------------------------------------------------------------------- 1 | L = 3 2 | W = 2 3 | model = "SpinGC" 4 | method = "Lanczos" 5 | lattice = "ladder" 6 | J0 = 1.0 7 | J1 = 1.0 8 | // D = 1.0 9 | Gamma = 0.5 10 | // 2Sz = 0 11 | outputmode = "all" 12 | -------------------------------------------------------------------------------- /haskell/cabal.project.local: -------------------------------------------------------------------------------- 1 | ignore-project: False 2 | write-ghc-environment-files: always 3 | tests: True 4 | test-options: "--color" 5 | test-show-details: streaming 6 | package lattice-symmetries-haskell 7 | flags: +no-standalone 8 | ghc-options: -g2 9 | -------------------------------------------------------------------------------- /kernels/kernels.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "is_representative_antisymmetric.h" 4 | #include "is_representative_general.h" 5 | #include "is_representative_symmetric.h" 6 | #include "state_info_antisymmetric.h" 7 | #include "state_info_general.h" 8 | #include "state_info_symmetric.h" -------------------------------------------------------------------------------- /kernels/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv 2 | , halide 3 | , version 4 | }: 5 | 6 | stdenv.mkDerivation { 7 | pname = "lattice-symmetries-kernels"; 8 | inherit version; 9 | src = ./.; 10 | dontConfigure = true; 11 | makeFlags = [ "HALIDE_PATH=${halide}" "PREFIX=$(out)" ]; 12 | } 13 | -------------------------------------------------------------------------------- /test/03_spin_hcor/HPhi/stan.in: -------------------------------------------------------------------------------- 1 | W = 2 2 | L = 2 3 | model = "SpinGC" 4 | method = "Lanczos" 5 | lattice = "Honeycomb" 6 | J0x = -1.0 7 | J0y = 0.0 8 | J0z = 0.0 9 | J1x = 0.0 10 | J1y = -1.0 11 | J1z = 0.0 12 | J2x = 0.0 13 | J2y = 0.0 14 | J2z = -1.0 15 | 2S=1 16 | h=-1.0 17 | -------------------------------------------------------------------------------- /test/02_spin_ladder_DM/HPhi/locspn.def: -------------------------------------------------------------------------------- 1 | ================================ 2 | NlocalSpin 6 3 | ================================ 4 | ========i_1LocSpn_0IteElc ====== 5 | ================================ 6 | 0 1 7 | 1 1 8 | 2 1 9 | 3 1 10 | 4 1 11 | 5 1 12 | -------------------------------------------------------------------------------- /test/03_spin_hcor/HPhi/greenone.def: -------------------------------------------------------------------------------- 1 | =============================== 2 | NCisAjs 4 3 | =============================== 4 | ======== Green functions ====== 5 | =============================== 6 | 0 0 0 0 7 | 0 1 0 1 8 | 1 0 1 0 9 | 1 1 1 1 10 | -------------------------------------------------------------------------------- /test/05_hubbard_tri/HPhi/locspn.def: -------------------------------------------------------------------------------- 1 | ================================ 2 | NlocalSpin 0 3 | ================================ 4 | ========i_1LocSpn_0IteElc ====== 5 | ================================ 6 | 0 0 7 | 1 0 8 | 2 0 9 | 3 0 10 | 4 0 11 | 5 0 12 | -------------------------------------------------------------------------------- /test/03_spin_hcor/HPhi/locspn.def: -------------------------------------------------------------------------------- 1 | ================================ 2 | NlocalSpin 8 3 | ================================ 4 | ========i_1LocSpn_0IteElc ====== 5 | ================================ 6 | 0 1 7 | 1 1 8 | 2 1 9 | 3 1 10 | 4 1 11 | 5 1 12 | 6 1 13 | 7 1 14 | -------------------------------------------------------------------------------- /test/05_hubbard_tri/HPhi/namelist.def: -------------------------------------------------------------------------------- 1 | ModPara modpara.def 2 | LocSpin locspn.def 3 | Trans trans.def 4 | CoulombIntra coulombintra.def 5 | OneBodyG greenone.def 6 | TwoBodyG greentwo.def 7 | CalcMod calcmod.def 8 | PairExcitation pair.def 9 | SpectrumVec zvo_eigenvec_0 10 | -------------------------------------------------------------------------------- /test/04_hubbard_square/HPhi/locspn.def: -------------------------------------------------------------------------------- 1 | ================================ 2 | NlocalSpin 0 3 | ================================ 4 | ========i_1LocSpn_0IteElc ====== 5 | ================================ 6 | 0 0 7 | 1 0 8 | 2 0 9 | 3 0 10 | 4 0 11 | 5 0 12 | 6 0 13 | 7 0 14 | -------------------------------------------------------------------------------- /test/04_hubbard_square/HPhi/namelist.def: -------------------------------------------------------------------------------- 1 | ModPara modpara.def 2 | LocSpin locspn.def 3 | Trans trans.def 4 | CoulombIntra coulombintra.def 5 | OneBodyG greenone.def 6 | TwoBodyG greentwo.def 7 | CalcMod calcmod.def 8 | PairExcitation pair.def 9 | SpectrumVec zvo_eigenvec_0 10 | -------------------------------------------------------------------------------- /test/01_spin_kagome/HPhi/locspn.def: -------------------------------------------------------------------------------- 1 | ================================ 2 | NlocalSpin 9 3 | ================================ 4 | ========i_1LocSpn_0IteElc ====== 5 | ================================ 6 | 0 1 7 | 1 1 8 | 2 1 9 | 3 1 10 | 4 1 11 | 5 1 12 | 6 1 13 | 7 1 14 | 8 1 15 | -------------------------------------------------------------------------------- /test/02_spin_ladder_DM/hamiltonian.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 6 3 | symmetries: [] 4 | hamiltonian: 5 | name: "Heisenberg Hamiltonian" 6 | terms: 7 | - expression: "Sˣ₀ Sˣ₁ + Sʸ₀ Sʸ₁ + Sᶻ₀ Sᶻ₁" 8 | sites: [[0, 2], [0, 4], [0, 1], [1, 3], [1, 5], [2, 4], [2, 3], [3, 5], [4, 5]] 9 | - expression: "0.5 Sˣ₀" 10 | sites: [[0], [1], [2], [3], [4], [5]] 11 | -------------------------------------------------------------------------------- /haskell/fourmolu.yaml: -------------------------------------------------------------------------------- 1 | indentation: 2 2 | function-arrows: leading 3 | comma-style: leading 4 | import-export-style: leading 5 | indent-wheres: true 6 | record-brace-space: true 7 | newlines-between-decls: 1 8 | haddock-style: single-line 9 | haddock-style-module: single-line 10 | let-style: auto 11 | in-style: right-align 12 | unicode: never 13 | respectful: true 14 | fixities: [] 15 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_4.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | particle: spin-1/2 3 | number_spins: 4 4 | hamming_weight: 2 5 | hamiltonian: 6 | name: Heisenberg Hamiltonian 7 | terms: 8 | - expression: "σˣ₀ σˣ₁" 9 | sites: &lattice [ [0, 1], [1, 2], [2, 3], [3, 0] ] 10 | - expression: "σʸ₀ σʸ₁" 11 | sites: *lattice 12 | - expression: "σᶻ₀ σᶻ₁" 13 | sites: *lattice 14 | -------------------------------------------------------------------------------- /chapel/test/TestRoseTree.chpl: -------------------------------------------------------------------------------- 1 | use LatticeSymmetries; 2 | 3 | proc main() { 4 | var tree = new shared RoseTree( 5 | 0, 6 | [ new shared RoseTree(1) 7 | , new shared RoseTree(2) 8 | , new shared RoseTree( 9 | 3, 10 | [ new shared RoseTree(30) 11 | , new shared RoseTree(31) 12 | ] 13 | ) 14 | ] 15 | ); 16 | 17 | writeln(tree); 18 | } 19 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_4_off_diag.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 4 3 | symmetries: [] 4 | hamiltonian: 5 | name: "Heisenberg Hamiltonian" 6 | lattice: &lattice [ [0, 1], [1, 2], [2, 3], [3, 0] ] 7 | terms: 8 | - expression: "σˣ₀ σˣ₁" 9 | sites: *lattice 10 | - expression: "σʸ₀ σʸ₁" 11 | sites: *lattice 12 | # - expression: "σᶻ₀ σᶻ₁" 13 | # sites: *lattice 14 | -------------------------------------------------------------------------------- /test/01_spin_kagome/HPhi/namelist.def: -------------------------------------------------------------------------------- 1 | ModPara modpara.def 2 | LocSpin locspn.def 3 | Trans trans.def 4 | CoulombInter coulombinter.def 5 | Hund hund.def 6 | Exchange exchange.def 7 | OneBodyG greenone.def 8 | TwoBodyG greentwo.def 9 | CalcMod calcmod.def 10 | PairExcitation pair.def 11 | SpectrumVec zvo_eigenvec_0 12 | -------------------------------------------------------------------------------- /test/02_spin_ladder_DM/HPhi/namelist.def: -------------------------------------------------------------------------------- 1 | ModPara modpara.def 2 | LocSpin locspn.def 3 | Trans trans.def 4 | CoulombInter coulombinter.def 5 | Hund hund.def 6 | Exchange exchange.def 7 | OneBodyG greenone.def 8 | TwoBodyG greentwo.def 9 | CalcMod calcmod.def 10 | PairExcitation pair.def 11 | SpectrumVec zvo_eigenvec_0 12 | -------------------------------------------------------------------------------- /test/03_spin_hcor/HPhi/hund.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NHund 4 3 | ============================================= 4 | =============== Hund coupling =============== 5 | ============================================= 6 | 1 4 0.500000000000000 7 | 3 6 0.500000000000000 8 | 5 0 0.500000000000000 9 | 7 2 0.500000000000000 10 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_6.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 6 3 | hamming_weight: 3 4 | symmetries: [] 5 | hamiltonian: 6 | name: "Heisenberg Hamiltonian" 7 | lattice: &lattice [ [0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 0] ] 8 | terms: 9 | - expression: "σˣ₀ σˣ₁" 10 | sites: *lattice 11 | - expression: "σʸ₀ σʸ₁" 12 | sites: *lattice 13 | - expression: "σᶻ₀ σᶻ₁" 14 | sites: *lattice 15 | -------------------------------------------------------------------------------- /test/03_spin_hcor/HPhi/coulombinter.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NCoulombInter 4 3 | ============================================= 4 | ================== CoulombInter ================ 5 | ============================================= 6 | 1 4 0.250000000000000 7 | 3 6 0.250000000000000 8 | 5 0 0.250000000000000 9 | 7 2 0.250000000000000 10 | -------------------------------------------------------------------------------- /chapel/src/CommonParameters.chpl: -------------------------------------------------------------------------------- 1 | module CommonParameters { 2 | config const kDisplayTimings : bool = false; 3 | config const kHashedToBlockNumChunks = 2 * here.maxTaskPar; 4 | config const kBlockToHashedNumChunks = 2 * numLocales * here.maxTaskPar; 5 | config const kIsRepresentativeBatchSize : int = 10240; 6 | config const kEnumerateStatesNumChunks : int = 8 * numLocales * here.maxTaskPar; 7 | config const kCacheNumberBits : int = 26; 8 | } 9 | -------------------------------------------------------------------------------- /test/03_spin_hcor/HPhi/namelist.def: -------------------------------------------------------------------------------- 1 | ModPara modpara.def 2 | LocSpin locspn.def 3 | Trans trans.def 4 | CoulombInter coulombinter.def 5 | Hund hund.def 6 | Exchange exchange.def 7 | PairLift pairlift.def 8 | OneBodyG greenone.def 9 | TwoBodyG greentwo.def 10 | CalcMod calcmod.def 11 | PairExcitation pair.def 12 | SpectrumVec zvo_eigenvec_0 13 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_8.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 8 3 | hamming_weight: 4 4 | symmetries: [] 5 | hamiltonian: 6 | name: "Heisenberg Hamiltonian" 7 | lattice: &lattice [ [0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 0] ] 8 | terms: 9 | - expression: "σˣ₀ σˣ₁" 10 | sites: *lattice 11 | - expression: "σʸ₀ σʸ₁" 12 | sites: *lattice 13 | - expression: "σᶻ₀ σᶻ₁" 14 | sites: *lattice 15 | 16 | -------------------------------------------------------------------------------- /test/05_hubbard_tri/HPhi/coulombintra.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NCoulombIntra 6 3 | ============================================= 4 | ================== CoulombIntra ================ 5 | ============================================= 6 | 0 4.000000000000000 7 | 1 4.000000000000000 8 | 2 4.000000000000000 9 | 3 4.000000000000000 10 | 4 4.000000000000000 11 | 5 4.000000000000000 12 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_10.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 10 3 | hamming_weight: 5 4 | spin_inversion: -1 5 | symmetries: [] 6 | hamiltonian: 7 | name: "Heisenberg Hamiltonian" 8 | lattice: &lattice [ [0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 0] ] 9 | terms: 10 | - expression: "σˣ₀ σˣ₁" 11 | sites: *lattice 12 | - expression: "σʸ₀ σʸ₁" 13 | sites: *lattice 14 | - expression: "σᶻ₀ σᶻ₁" 15 | sites: *lattice 16 | -------------------------------------------------------------------------------- /test/03_spin_hcor/hamiltonian.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 8 3 | symmetries: [] 4 | hamiltonian: 5 | name: "Hamiltonian" 6 | terms: 7 | - expression: "- Sˣ₀ Sˣ₁" 8 | sites: [[0, 5], [1, 4], [2, 7], [3, 6]] 9 | - expression: "- Sʸ₀ Sʸ₁" 10 | sites: [[0, 3], [1, 2], [4, 7], [5, 6]] 11 | - expression: "- Sᶻ₀ Sᶻ₁" 12 | sites: [[0, 1], [2, 3], [4, 5], [6, 7]] 13 | - expression: "- Sᶻ₀" 14 | sites: [[0], [1], [2], [3], [4], [5], [6], [7]] 15 | 16 | -------------------------------------------------------------------------------- /chapel/benchmark/BenchmarkStatesEnumeration.chpl: -------------------------------------------------------------------------------- 1 | use LatticeSymmetries; 2 | 3 | config const kHamiltonian = "data/heisenberg_chain_10.yaml"; 4 | 5 | proc main() { 6 | initRuntime(); 7 | defer deinitRuntime(); 8 | 9 | const (_, matrix) = loadConfigFromYaml(kHamiltonian, hamiltonian=true); 10 | const masks; 11 | const basisStates = enumerateStates(matrix.basis, masks); 12 | const dimension = + reduce basisStates.counts; 13 | logDebug("Hilbert space dimension: ", dimension); 14 | } 15 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_16.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 16 3 | hamming_weight: 8 4 | symmetries: [] 5 | hamiltonian: 6 | name: "Heisenberg Hamiltonian" 7 | lattice: &lattice [ [0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 0] ] 8 | terms: 9 | - expression: "σˣ₀ σˣ₁" 10 | sites: *lattice 11 | - expression: "σʸ₀ σʸ₁" 12 | sites: *lattice 13 | - expression: "σᶻ₀ σᶻ₁" 14 | sites: *lattice 15 | -------------------------------------------------------------------------------- /test/03_spin_hcor/HPhi/calcmod.def: -------------------------------------------------------------------------------- 1 | #CalcType = 0:Lanczos, 1:TPQCalc, 2:FullDiag, 3:CG, 4:Time-evolution 5:cTPQ 2 | #CalcModel = 0:Hubbard, 1:Spin, 2:Kondo, 3:HubbardGC, 4:SpinGC, 5:KondoGC 3 | #Restart = 0:None, 1:Save, 2:Restart&Save, 3:Restart 4 | #CalcSpec = 0:None, 1:Normal, 2:No H*Phi, 3:Save, 4:Restart, 5:Restart&Save 5 | CalcType 0 6 | CalcModel 4 7 | ReStart 0 8 | CalcSpec 0 9 | CalcEigenVec 0 10 | InitialVecType 0 11 | InputEigenVec 0 12 | OutputEigenVec 0 13 | InputHam 0 14 | OutputHam 0 15 | OutputExVec 0 16 | -------------------------------------------------------------------------------- /test/01_spin_kagome/HPhi/calcmod.def: -------------------------------------------------------------------------------- 1 | #CalcType = 0:Lanczos, 1:TPQCalc, 2:FullDiag, 3:CG, 4:Time-evolution 5:cTPQ 2 | #CalcModel = 0:Hubbard, 1:Spin, 2:Kondo, 3:HubbardGC, 4:SpinGC, 5:KondoGC 3 | #Restart = 0:None, 1:Save, 2:Restart&Save, 3:Restart 4 | #CalcSpec = 0:None, 1:Normal, 2:No H*Phi, 3:Save, 4:Restart, 5:Restart&Save 5 | CalcType 0 6 | CalcModel 1 7 | ReStart 0 8 | CalcSpec 0 9 | CalcEigenVec 0 10 | InitialVecType 0 11 | InputEigenVec 0 12 | OutputEigenVec 0 13 | InputHam 0 14 | OutputHam 0 15 | OutputExVec 0 16 | -------------------------------------------------------------------------------- /test/02_spin_ladder_DM/HPhi/calcmod.def: -------------------------------------------------------------------------------- 1 | #CalcType = 0:Lanczos, 1:TPQCalc, 2:FullDiag, 3:CG, 4:Time-evolution 5:cTPQ 2 | #CalcModel = 0:Hubbard, 1:Spin, 2:Kondo, 3:HubbardGC, 4:SpinGC, 5:KondoGC 3 | #Restart = 0:None, 1:Save, 2:Restart&Save, 3:Restart 4 | #CalcSpec = 0:None, 1:Normal, 2:No H*Phi, 3:Save, 4:Restart, 5:Restart&Save 5 | CalcType 0 6 | CalcModel 4 7 | ReStart 0 8 | CalcSpec 0 9 | CalcEigenVec 0 10 | InitialVecType 0 11 | InputEigenVec 0 12 | OutputEigenVec 0 13 | InputHam 0 14 | OutputHam 0 15 | OutputExVec 0 16 | -------------------------------------------------------------------------------- /test/04_hubbard_square/HPhi/calcmod.def: -------------------------------------------------------------------------------- 1 | #CalcType = 0:Lanczos, 1:TPQCalc, 2:FullDiag, 3:CG, 4:Time-evolution 5:cTPQ 2 | #CalcModel = 0:Hubbard, 1:Spin, 2:Kondo, 3:HubbardGC, 4:SpinGC, 5:KondoGC 3 | #Restart = 0:None, 1:Save, 2:Restart&Save, 3:Restart 4 | #CalcSpec = 0:None, 1:Normal, 2:No H*Phi, 3:Save, 4:Restart, 5:Restart&Save 5 | CalcType 0 6 | CalcModel 0 7 | ReStart 0 8 | CalcSpec 0 9 | CalcEigenVec 0 10 | InitialVecType 0 11 | InputEigenVec 0 12 | OutputEigenVec 0 13 | InputHam 0 14 | OutputHam 0 15 | OutputExVec 0 16 | -------------------------------------------------------------------------------- /test/05_hubbard_tri/HPhi/calcmod.def: -------------------------------------------------------------------------------- 1 | #CalcType = 0:Lanczos, 1:TPQCalc, 2:FullDiag, 3:CG, 4:Time-evolution 5:cTPQ 2 | #CalcModel = 0:Hubbard, 1:Spin, 2:Kondo, 3:HubbardGC, 4:SpinGC, 5:KondoGC 3 | #Restart = 0:None, 1:Save, 2:Restart&Save, 3:Restart 4 | #CalcSpec = 0:None, 1:Normal, 2:No H*Phi, 3:Save, 4:Restart, 5:Restart&Save 5 | CalcType 0 6 | CalcModel 3 7 | ReStart 0 8 | CalcSpec 0 9 | CalcEigenVec 0 10 | InitialVecType 0 11 | InputEigenVec 0 12 | OutputEigenVec 0 13 | InputHam 0 14 | OutputHam 0 15 | OutputExVec 0 16 | -------------------------------------------------------------------------------- /test/04_hubbard_square/HPhi/coulombintra.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NCoulombIntra 8 3 | ============================================= 4 | ================== CoulombIntra ================ 5 | ============================================= 6 | 0 4.000000000000000 7 | 1 4.000000000000000 8 | 2 4.000000000000000 9 | 3 4.000000000000000 10 | 4 4.000000000000000 11 | 5 4.000000000000000 12 | 6 4.000000000000000 13 | 7 4.000000000000000 14 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_20.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 20 3 | hamming_weight: 10 4 | symmetries: [] 5 | hamiltonian: 6 | name: "Heisenberg Hamiltonian" 7 | lattice: &lattice [ [0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16], [16, 17], [17, 18], [18, 19], [19, 0] ] 8 | terms: 9 | - expression: "σˣ₀ σˣ₁" 10 | sites: *lattice 11 | - expression: "σʸ₀ σʸ₁" 12 | sites: *lattice 13 | - expression: "σᶻ₀ σᶻ₁" 14 | sites: *lattice 15 | -------------------------------------------------------------------------------- /test/03_spin_hcor/HPhi/pairlift.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NPairLift 8 3 | ============================================= 4 | ====== Pair-Lift term ============ 5 | ============================================= 6 | 0 1 -0.250000000000000 7 | 1 2 0.250000000000000 8 | 2 3 -0.250000000000000 9 | 3 0 0.250000000000000 10 | 4 5 -0.250000000000000 11 | 5 6 0.250000000000000 12 | 6 7 -0.250000000000000 13 | 7 4 0.250000000000000 14 | -------------------------------------------------------------------------------- /test/03_spin_hcor/HPhi/exchange.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NExchange 8 3 | ============================================= 4 | ====== ExchangeCoupling coupling ============ 5 | ============================================= 6 | 0 1 -0.250000000000000 7 | 1 2 -0.250000000000000 8 | 2 3 -0.250000000000000 9 | 3 0 -0.250000000000000 10 | 4 5 -0.250000000000000 11 | 5 6 -0.250000000000000 12 | 6 7 -0.250000000000000 13 | 7 4 -0.250000000000000 14 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_12.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 12 3 | hamming_weight: null 4 | symmetries: [] 5 | # symmetries: 6 | # - permutation: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] 7 | # sector: 0 8 | hamiltonian: 9 | name: "Heisenberg Hamiltonian" 10 | lattice: &lattice [ [0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 0] ] 11 | terms: 12 | - expression: "σˣ₀ σˣ₁" 13 | sites: *lattice 14 | - expression: "σʸ₀ σʸ₁" 15 | sites: *lattice 16 | # - expression: "σᶻ₀ σᶻ₁" 17 | # sites: *lattice 18 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_24.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 24 3 | hamming_weight: 12 4 | symmetries: [] 5 | hamiltonian: 6 | name: "Heisenberg Hamiltonian" 7 | lattice: &lattice [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16], [16, 17], [17, 18], [18, 19], [19, 20], [20, 21], [21, 22], [22, 23], [23, 0]] 8 | terms: 9 | - expression: "σˣ₀ σˣ₁" 10 | sites: *lattice 11 | - expression: "σʸ₀ σʸ₁" 12 | sites: *lattice 13 | - expression: "σᶻ₀ σᶻ₁" 14 | sites: *lattice 15 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | --- 2 | Checks: '*,-fuchsia-*,-google-*,-zircon-*,-abseil-*,-llvmlibc-restrict-system-libc-headers,-llvmlibc-callee-namespace,-llvmlibc-implementation-in-namespace,-*-avoid-c-arrays,-modernize-use-trailing-return-type,-misc-non-private-member-variables-in-classes,-misc-no-recursion,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-modernize-use-using,-llvm-include-order,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-hicpp-no-array-decay,-cppcoreguidelines-macro-usage' 3 | WarningsAsErrors: '*' 4 | HeaderFilterRegex: '' 5 | FormatStyle: none 6 | -------------------------------------------------------------------------------- /test/04_hubbard_square/hamiltonian.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | particle: "spinful-fermion" 3 | number_sites: 8 4 | number_particles: [4, 4] 5 | hamiltonian: 6 | name: "Hamiltonian" 7 | terms: 8 | - expression: "- (c†₁↑ c₀↑ + c†₀↑ c₁↑ + c†₁↓ c₀↓ + c†₀↓ c₁↓)" 9 | sites: [[0, 1], [0, 3], [0, 4], [1, 2], [1, 5], [2, 3], [2, 6], [3, 7], [4, 5], [4, 7], [5, 6], [6, 7], 10 | # HPhi counts hoppings crossing the boundaries twice because the system is too thin 11 | [0, 4], [1, 5], [2, 6], [3, 7]] 12 | - expression: "4.0 n₀↑ n₀↓" 13 | sites: [[0], [1], [2], [3], [4], [5], [6], [7]] 14 | 15 | -------------------------------------------------------------------------------- /test/02_spin_ladder_DM/HPhi/hund.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NHund 9 3 | ============================================= 4 | =============== Hund coupling =============== 5 | ============================================= 6 | 0 2 -0.500000000000000 7 | 0 4 -0.500000000000000 8 | 0 1 -0.500000000000000 9 | 1 3 -0.500000000000000 10 | 1 5 -0.500000000000000 11 | 2 4 -0.500000000000000 12 | 2 3 -0.500000000000000 13 | 3 5 -0.500000000000000 14 | 4 5 -0.500000000000000 15 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_28.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 28 3 | hamming_weight: 14 4 | symmetries: [] 5 | hamiltonian: 6 | name: "Heisenberg Hamiltonian" 7 | lattice: &lattice [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16], [16, 17], [17, 18], [18, 19], [19, 20], [20, 21], [21, 22], [22, 23], [23, 24], [24, 25], [25, 26], [26, 27], [27, 0]] 8 | terms: 9 | - expression: "σˣ₀ σˣ₁" 10 | sites: *lattice 11 | - expression: "σʸ₀ σʸ₁" 12 | sites: *lattice 13 | - expression: "σᶻ₀ σᶻ₁" 14 | sites: *lattice 15 | -------------------------------------------------------------------------------- /test/02_spin_ladder_DM/HPhi/exchange.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NExchange 9 3 | ============================================= 4 | ====== ExchangeCoupling coupling ============ 5 | ============================================= 6 | 0 2 0.500000000000000 7 | 0 4 0.500000000000000 8 | 0 1 0.500000000000000 9 | 1 3 0.500000000000000 10 | 1 5 0.500000000000000 11 | 2 4 0.500000000000000 12 | 2 3 0.500000000000000 13 | 3 5 0.500000000000000 14 | 4 5 0.500000000000000 15 | -------------------------------------------------------------------------------- /test/02_spin_ladder_DM/HPhi/coulombinter.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NCoulombInter 9 3 | ============================================= 4 | ================== CoulombInter ================ 5 | ============================================= 6 | 0 2 -0.250000000000000 7 | 0 4 -0.250000000000000 8 | 0 1 -0.250000000000000 9 | 1 3 -0.250000000000000 10 | 1 5 -0.250000000000000 11 | 2 4 -0.250000000000000 12 | 2 3 -0.250000000000000 13 | 3 5 -0.250000000000000 14 | 4 5 -0.250000000000000 15 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_30.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 30 3 | hamming_weight: 15 4 | symmetries: [] 5 | hamiltonian: 6 | name: "Heisenberg Hamiltonian" 7 | lattice: &lattice [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16], [16, 17], [17, 18], [18, 19], [19, 20], [20, 21], [21, 22], [22, 23], [23, 24], [24, 25], [25, 26], [26, 27], [27, 28], [28, 29], [29, 0]] 8 | terms: 9 | - expression: "σˣ₀ σˣ₁" 10 | sites: *lattice 11 | - expression: "σʸ₀ σʸ₁" 12 | sites: *lattice 13 | - expression: "σᶻ₀ σᶻ₁" 14 | sites: *lattice 15 | 16 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_kagome_16.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 16 3 | hamming_weight: 8 4 | symmetries: [] 5 | hamiltonian: 6 | name: "Heisenberg Hamiltonian" 7 | 8 | lattice: &lattice [[0, 1], [0, 4], [1, 2], [1, 4], [2, 3], [2, 5], [3, 5], [4, 6], [5, 7], [5, 8], [6, 7], [6, 10], [7, 8], [7, 10], [8, 9], [8, 11], [9, 11], [10, 12], [11, 13], [11, 14], [12, 13], [13, 14], [14, 15]] 9 | terms: 10 | - expression: "Sˣ₀ Sˣ₁" 11 | sites: *lattice 12 | - expression: "Sʸ₀ Sʸ₁" 13 | sites: *lattice 14 | - expression: "Sᶻ₀ Sᶻ₁" 15 | sites: *lattice 16 | observables: [] 17 | number_vectors: 2 18 | output: "heisenberg_kagome_16.h5" 19 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_32.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 32 3 | hamming_weight: 16 4 | symmetries: [] 5 | hamiltonian: 6 | name: "Heisenberg Hamiltonian" 7 | lattice: &lattice [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16], [16, 17], [17, 18], [18, 19], [19, 20], [20, 21], [21, 22], [22, 23], [23, 24], [24, 25], [25, 26], [26, 27], [27, 28], [28, 29], [29, 30], [30, 31], [31, 0]] 8 | terms: 9 | - expression: "σˣ₀ σˣ₁" 10 | sites: *lattice 11 | - expression: "σʸ₀ σʸ₁" 12 | sites: *lattice 13 | - expression: "σᶻ₀ σᶻ₁" 14 | sites: *lattice 15 | -------------------------------------------------------------------------------- /haskell/test/LatticeSymmetries/GeneratorSpec.hs: -------------------------------------------------------------------------------- 1 | module LatticeSymmetries.GeneratorSpec (spec) where 2 | 3 | import qualified Data.Aeson as Aeson 4 | import LatticeSymmetries.Generator 5 | import Test.Hspec 6 | 7 | spec :: Spec 8 | spec = do 9 | describe "FromJSON ParticleTy" $ 10 | it "parses ParticleTy" $ do 11 | forM_ ([SpinTy, SpinlessFermionTy, SpinfulFermionTy] :: [ParticleTy]) $ \tp -> 12 | Aeson.decode (Aeson.encode tp) `shouldBe` Just tp 13 | Aeson.decode "\"spin\"" `shouldBe` Just SpinTy 14 | Aeson.decode "\"spinless-fermion\"" `shouldBe` Just SpinlessFermionTy 15 | Aeson.decode "\"spinful-fermion\"" `shouldBe` Just SpinfulFermionTy 16 | -------------------------------------------------------------------------------- /haskell/cbits/init.c: -------------------------------------------------------------------------------- 1 | #include "lattice_symmetries_types.h" 2 | #include 3 | #include 4 | // #include 5 | 6 | void ls_hs_init(void) { 7 | int argc = 1; 8 | char *argv[] = {"lattice_symmetries", NULL}; 9 | // "+RTS", "-N1", "--install-signal-handlers=no", "-RTS", NULL}; 10 | char **pargv = argv; 11 | 12 | // For some reason, options from argv are not processed properly, so we 13 | // manually set all RTS options using rts_opts field of RtsConfig 14 | RtsConfig conf = defaultRtsConfig; 15 | conf.rts_opts_enabled = RtsOptsAll; 16 | conf.rts_opts = "-N1 --install-signal-handlers=no"; 17 | hs_init_ghc(&argc, &pargv, conf); 18 | } 19 | 20 | void ls_hs_exit(void) { 21 | hs_exit(); 22 | } 23 | -------------------------------------------------------------------------------- /test/03_spin_hcor/HPhi/modpara.def: -------------------------------------------------------------------------------- 1 | -------------------- 2 | Model_Parameters 0 3 | -------------------- 4 | HPhi_Cal_Parameters 5 | -------------------- 6 | CDataFileHead zvo 7 | CParaFileHead zqp 8 | -------------------- 9 | Nsite 8 10 | Lanczos_max 2000 11 | initial_iv -1 12 | exct 1 13 | LanczosEps 14 14 | LanczosTarget 2 15 | LargeValue 2.625000000000000e+00 16 | NumAve 5 17 | ExpecInterval 20 18 | NOmega 200 19 | OmegaMax 2.100000000000000e+01 2.000000000000000e-02 20 | OmegaMin -2.100000000000000e+01 2.000000000000000e-02 21 | OmegaOrg 0.000000000000000e+00 0.000000000000000e+00 22 | PreCG 1 23 | -------------------------------------------------------------------------------- /test/05_hubbard_tri/HPhi/modpara.def: -------------------------------------------------------------------------------- 1 | -------------------- 2 | Model_Parameters 0 3 | -------------------- 4 | HPhi_Cal_Parameters 5 | -------------------- 6 | CDataFileHead zvo 7 | CParaFileHead zqp 8 | -------------------- 9 | Nsite 6 10 | Lanczos_max 2000 11 | initial_iv -1 12 | exct 1 13 | LanczosEps 14 14 | LanczosTarget 2 15 | LargeValue 2.200000000000000e+01 16 | NumAve 5 17 | ExpecInterval 20 18 | NOmega 200 19 | OmegaMax 1.320000000000000e+02 2.200000000000000e-01 20 | OmegaMin -1.320000000000000e+02 2.200000000000000e-01 21 | OmegaOrg 0.000000000000000e+00 0.000000000000000e+00 22 | PreCG 1 23 | -------------------------------------------------------------------------------- /test/02_spin_ladder_DM/HPhi/modpara.def: -------------------------------------------------------------------------------- 1 | -------------------- 2 | Model_Parameters 0 3 | -------------------- 4 | HPhi_Cal_Parameters 5 | -------------------- 6 | CDataFileHead zvo 7 | CParaFileHead zqp 8 | -------------------- 9 | Nsite 6 10 | Lanczos_max 2000 11 | initial_iv -1 12 | exct 1 13 | LanczosEps 14 14 | LanczosTarget 2 15 | LargeValue 3.875000000000000e+00 16 | NumAve 5 17 | ExpecInterval 20 18 | NOmega 200 19 | OmegaMax 2.325000000000000e+01 3.000000000000000e-02 20 | OmegaMin -2.325000000000000e+01 3.000000000000000e-02 21 | OmegaOrg 0.000000000000000e+00 0.000000000000000e+00 22 | PreCG 1 23 | -------------------------------------------------------------------------------- /test/01_spin_kagome/HPhi/modpara.def: -------------------------------------------------------------------------------- 1 | -------------------- 2 | Model_Parameters 0 3 | -------------------- 4 | HPhi_Cal_Parameters 5 | -------------------- 6 | CDataFileHead zvo 7 | CParaFileHead zqp 8 | -------------------- 9 | Nsite 9 10 | 2Sz 1 11 | Lanczos_max 2000 12 | initial_iv -1 13 | exct 1 14 | LanczosEps 14 15 | LanczosTarget 2 16 | LargeValue 3.000000000000000e+00 17 | NumAve 5 18 | ExpecInterval 20 19 | NOmega 200 20 | OmegaMax 2.700000000000000e+01 3.000000000000000e-02 21 | OmegaMin -2.700000000000000e+01 3.000000000000000e-02 22 | OmegaOrg 0.000000000000000e+00 0.000000000000000e+00 23 | PreCG 1 24 | -------------------------------------------------------------------------------- /test/04_hubbard_square/HPhi/modpara.def: -------------------------------------------------------------------------------- 1 | -------------------- 2 | Model_Parameters 0 3 | -------------------- 4 | HPhi_Cal_Parameters 5 | -------------------- 6 | CDataFileHead zvo 7 | CParaFileHead zqp 8 | -------------------- 9 | Nsite 8 10 | 2Sz 0 11 | Ncond 8 12 | Lanczos_max 2000 13 | initial_iv -1 14 | exct 1 15 | LanczosEps 14 16 | LanczosTarget 2 17 | LargeValue 1.200000000000000e+01 18 | NumAve 5 19 | ExpecInterval 20 20 | NOmega 200 21 | OmegaMax 9.600000000000000e+01 1.200000000000000e-01 22 | OmegaMin -9.600000000000000e+01 1.200000000000000e-01 23 | OmegaOrg 0.000000000000000e+00 0.000000000000000e+00 24 | PreCG 1 25 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_kagome_12.yaml: -------------------------------------------------------------------------------- 1 | # Heisenberg antiferromagnet on 12-site Kagome lattice with open boundary 2 | # conditions 3 | basis: 4 | number_spins: 12 5 | hamming_weight: 6 6 | symmetries: [] 7 | hamiltonian: 8 | name: "Heisenberg Hamiltonian" 9 | # 10 11 10 | # 6 7 8 9 11 | # 4 5 12 | # 0 1 2 3 13 | lattice: &lattice [[0, 1], [0, 4], [1, 2], [1, 4], [2, 3], [2, 5], [3, 5], 14 | [4, 6], [5, 7], [5, 8], 15 | [6, 7], [6, 10], [7, 8], [7, 10], [8, 9], [8, 11], [9, 11]] 16 | terms: 17 | - expression: "Sˣ₀ Sˣ₁" 18 | sites: *lattice 19 | - expression: "Sʸ₀ Sʸ₁" 20 | sites: *lattice 21 | - expression: "Sᶻ₀ Sᶻ₁" 22 | sites: *lattice 23 | observables: [] 24 | number_vectors: 1 25 | output: "heisenberg_kagome_12.h5" 26 | -------------------------------------------------------------------------------- /chapel/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv 2 | , chapel 3 | , chapelFixupBinary 4 | , lattice-symmetries 5 | , version 6 | }: 7 | 8 | stdenv.mkDerivation { 9 | pname = "lattice-symmetries-chapel"; 10 | inherit version; 11 | src = ./.; 12 | 13 | configurePhase = "ln --symbolic ${lattice-symmetries.ffi} src/FFI.chpl"; 14 | makeFlags = [ 15 | "PREFIX=$(out)" 16 | "OPTIMIZATION=--fast" 17 | "CHPL_CFLAGS='-I${lattice-symmetries.kernels}/include'" 18 | "CHPL_LDFLAGS='-L${lattice-symmetries.haskell.lib}/lib'" 19 | ]; 20 | preInstall = '' 21 | for f in $(ls lib); do 22 | chapelFixupBinary lib/$f 23 | done 24 | for f in $(ls bin); do 25 | chapelFixupBinary bin/$f 26 | done 27 | ''; 28 | 29 | buildInputs = [ lattice-symmetries.kernels lattice-symmetries.haskell.lib ]; 30 | nativeBuildInputs = [ chapel chapelFixupBinary ]; 31 | } 32 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_24_symm.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 24 3 | hamming_weight: 12 4 | spin_inversion: 1 5 | symmetries: 6 | - permutation: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0] 7 | sector: 0 8 | - permutation: [23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 9 | sector: 0 10 | hamiltonian: 11 | name: "Heisenberg Hamiltonian" 12 | lattice: &lattice [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16], [16, 17], [17, 18], [18, 19], [19, 20], [20, 21], [21, 22], [22, 23], [23, 0]] 13 | terms: 14 | - expression: "σˣ₀ σˣ₁" 15 | sites: *lattice 16 | - expression: "σʸ₀ σʸ₁" 17 | sites: *lattice 18 | - expression: "σᶻ₀ σᶻ₁" 19 | sites: *lattice 20 | -------------------------------------------------------------------------------- /chapel/data/issue_01.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 12 3 | hamming_weight: 6 4 | symmetries: 5 | - permutation: [2, 10, 0, 4, 3, 7, 11, 5, 9, 8, 1, 6] 6 | sector: 1 7 | hamiltonian: 8 | name: "Heisenberg Hamiltonian" 9 | lattice_1: &lattice_1 [[0, 1], [1, 2], [0, 3], [3, 5], [5, 6], [6, 7], [4, 7], [2, 4], [5, 8], [8, 0], [9, 2], [7, 9], [2, 10], [10, 0], [7, 11], [11, 5]] 10 | lattice_2: &lattice_2 [[1, 3], [6, 4], [6, 8], [1, 9], [10, 4], [11, 3], [11, 9], [10, 8]] 11 | terms: 12 | - expression: "σˣ₀ σˣ₁" 13 | sites: *lattice_1 14 | - expression: "σʸ₀ σʸ₁" 15 | sites: *lattice_1 16 | - expression: "σᶻ₀ σᶻ₁" 17 | sites: *lattice_1 18 | - expression: "0.8 × σˣ₀ σˣ₁" 19 | sites: *lattice_2 20 | - expression: "0.8 × σʸ₀ σʸ₁" 21 | sites: *lattice_2 22 | - expression: "0.8 × σᶻ₀ σᶻ₁" 23 | sites: *lattice_2 24 | -------------------------------------------------------------------------------- /test/02_spin_ladder_DM/HPhi/greenone.def: -------------------------------------------------------------------------------- 1 | =============================== 2 | NCisAjs 24 3 | =============================== 4 | ======== Green functions ====== 5 | =============================== 6 | 0 0 0 0 7 | 0 0 0 1 8 | 0 1 0 0 9 | 0 1 0 1 10 | 1 0 1 0 11 | 1 0 1 1 12 | 1 1 1 0 13 | 1 1 1 1 14 | 2 0 2 0 15 | 2 0 2 1 16 | 2 1 2 0 17 | 2 1 2 1 18 | 3 0 3 0 19 | 3 0 3 1 20 | 3 1 3 0 21 | 3 1 3 1 22 | 4 0 4 0 23 | 4 0 4 1 24 | 4 1 4 0 25 | 4 1 4 1 26 | 5 0 5 0 27 | 5 0 5 1 28 | 5 1 5 0 29 | 5 1 5 1 30 | -------------------------------------------------------------------------------- /test/05_hubbard_tri/hamiltonian.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | particle: "spinful-fermion" 3 | number_sites: 6 4 | hamiltonian: 5 | name: "Hamiltonian" 6 | terms: 7 | - expression: "- (c†₁↑ c₀↑ + c†₀↑ c₁↑ + c†₁↓ c₀↓ + c†₀↓ c₁↓)" 8 | sites: [ # Double counting because the lattice is too small 9 | [3, 0], [0, 3], [4, 1], [1, 4], [5, 2], [2, 5], 10 | [1, 3], [3, 1], [2, 4], [4, 2], [0, 5], [5, 0], 11 | # In this direction, there's no double counting anymore 12 | [0, 1], [1, 2], [0, 2], [3, 4], [4, 5], [3, 5] 13 | ] 14 | # Counting 0.5 four times because of periodic boundaries... 15 | - expression: "- 2 (c†₁↑ c₀↑ + c†₀↑ c₁↑ + c†₁↓ c₀↓ + c†₀↓ c₁↓)" 16 | sites: [ [0, 4], [1, 5], [2, 3] ] 17 | # HPhi also includes self-hoppings 18 | - expression: "- (c†₀↑ c₀↑ + c†₀↓ c₀↓)" 19 | sites: [ [0], [1], [2], [3], [4], [5] ] 20 | - expression: "4.0 n₀↑ n₀↓" 21 | sites: [[0], [1], [2], [3], [4], [5]] 22 | -------------------------------------------------------------------------------- /test/01_spin_kagome/HPhi/hund.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NHund 18 3 | ============================================= 4 | =============== Hund coupling =============== 5 | ============================================= 6 | 0 1 -0.250000000000000 7 | 0 2 -0.250000000000000 8 | 1 2 -0.500000000000000 9 | 1 6 -0.250000000000000 10 | 2 3 -0.250000000000000 11 | 1 5 -0.500000000000000 12 | 3 4 -0.250000000000000 13 | 3 5 -0.250000000000000 14 | 4 5 -0.500000000000000 15 | 4 0 -0.250000000000000 16 | 5 6 -0.250000000000000 17 | 4 8 -0.500000000000000 18 | 6 7 -0.250000000000000 19 | 6 8 -0.250000000000000 20 | 7 8 -0.500000000000000 21 | 7 3 -0.250000000000000 22 | 8 0 -0.250000000000000 23 | 7 2 -0.500000000000000 24 | -------------------------------------------------------------------------------- /test/01_spin_kagome/HPhi/exchange.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NExchange 18 3 | ============================================= 4 | ====== ExchangeCoupling coupling ============ 5 | ============================================= 6 | 0 1 0.250000000000000 7 | 0 2 0.250000000000000 8 | 1 2 0.500000000000000 9 | 1 6 0.250000000000000 10 | 2 3 0.250000000000000 11 | 1 5 0.500000000000000 12 | 3 4 0.250000000000000 13 | 3 5 0.250000000000000 14 | 4 5 0.500000000000000 15 | 4 0 0.250000000000000 16 | 5 6 0.250000000000000 17 | 4 8 0.500000000000000 18 | 6 7 0.250000000000000 19 | 6 8 0.250000000000000 20 | 7 8 0.500000000000000 21 | 7 3 0.250000000000000 22 | 8 0 0.250000000000000 23 | 7 2 0.500000000000000 24 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_32_symm.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 32 3 | hamming_weight: 16 4 | spin_inversion: 1 5 | symmetries: 6 | - permutation: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0] 7 | sector: 0 8 | - permutation: [31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 9 | sector: 0 10 | hamiltonian: 11 | name: "Heisenberg Hamiltonian" 12 | lattice: &lattice [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16], [16, 17], [17, 18], [18, 19], [19, 20], [20, 21], [21, 22], [22, 23], [23, 24], [24, 25], [25, 26], [26, 27], [27, 28], [28, 29], [29, 30], [30, 31], [31, 0]] 13 | terms: 14 | - expression: "σˣ₀ σˣ₁" 15 | sites: *lattice 16 | - expression: "σʸ₀ σʸ₁" 17 | sites: *lattice 18 | - expression: "σᶻ₀ σᶻ₁" 19 | sites: *lattice 20 | -------------------------------------------------------------------------------- /test/01_spin_kagome/HPhi/coulombinter.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NCoulombInter 18 3 | ============================================= 4 | ================== CoulombInter ================ 5 | ============================================= 6 | 0 1 -0.125000000000000 7 | 0 2 -0.125000000000000 8 | 1 2 -0.250000000000000 9 | 1 6 -0.125000000000000 10 | 2 3 -0.125000000000000 11 | 1 5 -0.250000000000000 12 | 3 4 -0.125000000000000 13 | 3 5 -0.125000000000000 14 | 4 5 -0.250000000000000 15 | 4 0 -0.125000000000000 16 | 5 6 -0.125000000000000 17 | 4 8 -0.250000000000000 18 | 6 7 -0.125000000000000 19 | 6 8 -0.125000000000000 20 | 7 8 -0.250000000000000 21 | 7 3 -0.125000000000000 22 | 8 0 -0.125000000000000 23 | 7 2 -0.250000000000000 24 | -------------------------------------------------------------------------------- /test/05_hubbard_tri/HPhi/pair.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NPair 12 3 | ============================================= 4 | =============== Pair Excitation ============= 5 | ============================================= 6 | 0 0 0 0 1 0.500000000000000 0.000000000000000 7 | 0 1 0 1 1 -0.500000000000000 -0.000000000000000 8 | 1 0 1 0 1 0.500000000000000 0.000000000000000 9 | 1 1 1 1 1 -0.500000000000000 -0.000000000000000 10 | 2 0 2 0 1 0.500000000000000 0.000000000000000 11 | 2 1 2 1 1 -0.500000000000000 -0.000000000000000 12 | 3 0 3 0 1 0.500000000000000 0.000000000000000 13 | 3 1 3 1 1 -0.500000000000000 -0.000000000000000 14 | 4 0 4 0 1 0.500000000000000 0.000000000000000 15 | 4 1 4 1 1 -0.500000000000000 -0.000000000000000 16 | 5 0 5 0 1 0.500000000000000 0.000000000000000 17 | 5 1 5 1 1 -0.500000000000000 -0.000000000000000 18 | -------------------------------------------------------------------------------- /test/02_spin_ladder_DM/HPhi/pair.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NPair 12 3 | ============================================= 4 | =============== Pair Excitation ============= 5 | ============================================= 6 | 0 0 0 0 1 -0.500000000000000 -0.000000000000000 7 | 0 1 0 1 1 0.500000000000000 0.000000000000000 8 | 1 0 1 0 1 -0.500000000000000 -0.000000000000000 9 | 1 1 1 1 1 0.500000000000000 0.000000000000000 10 | 2 0 2 0 1 -0.500000000000000 -0.000000000000000 11 | 2 1 2 1 1 0.500000000000000 0.000000000000000 12 | 3 0 3 0 1 -0.500000000000000 -0.000000000000000 13 | 3 1 3 1 1 0.500000000000000 0.000000000000000 14 | 4 0 4 0 1 -0.500000000000000 -0.000000000000000 15 | 4 1 4 1 1 0.500000000000000 0.000000000000000 16 | 5 0 5 0 1 -0.500000000000000 -0.000000000000000 17 | 5 1 5 1 1 0.500000000000000 0.000000000000000 18 | -------------------------------------------------------------------------------- /haskell/test/LatticeSymmetries/ParserSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | 3 | module LatticeSymmetries.ParserSpec (spec) where 4 | 5 | import LatticeSymmetries.Expr 6 | import LatticeSymmetries.Generator 7 | import LatticeSymmetries.Utils 8 | import Test.Hspec 9 | 10 | spec :: Spec 11 | spec = do 12 | describe "mkExpr" $ do 13 | it "handles simple operators" $ do 14 | toPrettyText (mkExpr SpinTag "σˣ₅") `shouldBe` "σ⁺₅ + σ⁻₅" 15 | toPrettyText (mkExpr SpinTag "σʸ₈₉₄₃") `shouldBe` "-ⅈ σ⁺₈₉₄₃ + ⅈ σ⁻₈₉₄₃" 16 | toPrettyText (mkExpr SpinTag "\\sigma^y_90") `shouldBe` "-ⅈ σ⁺₉₀ + ⅈ σ⁻₉₀" 17 | toPrettyText (mkExpr SpinfulFermionTag "4.0 n₀↑ n₀↓") `shouldBe` "4.0 n₀↑ n₀↓" 18 | it "handles complex expressions" $ do 19 | toPrettyText (mkExpr SpinfulFermionTag "5 (c^\\dagger_10\\up - c\\dagger2\\down) n3\\up") 20 | `shouldBe` "5.0 n₃↑ c†₁₀↑ - 5.0 n₃↑ c†₂↓" 21 | toPrettyText (mkExpr SpinlessFermionTag "3.25 (c†23-5(c12-n2))") 22 | `shouldBe` "16.25 n₂ - 16.25 c₁₂ + 3.25 c†₂₃" 23 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_36_symm.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 36 3 | hamming_weight: 18 4 | spin_inversion: 1 5 | symmetries: 6 | - permutation: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 0] 7 | sector: 0 8 | - permutation: [35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 9 | sector: 0 10 | hamiltonian: 11 | name: "Heisenberg Hamiltonian" 12 | lattice: &lattice [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16], [16, 17], [17, 18], [18, 19], [19, 20], [20, 21], [21, 22], [22, 23], [23, 24], [24, 25], [25, 26], [26, 27], [27, 28], [28, 29], [29, 30], [30, 31], [31, 32], [32, 33], [33, 34], [34, 35], [35, 0]] 13 | terms: 14 | - expression: "σˣ₀ σˣ₁" 15 | sites: *lattice 16 | - expression: "σʸ₀ σʸ₁" 17 | sites: *lattice 18 | - expression: "σᶻ₀ σᶻ₁" 19 | sites: *lattice 20 | 21 | -------------------------------------------------------------------------------- /chapel/src/LatticeSymmetries.chpl: -------------------------------------------------------------------------------- 1 | module LatticeSymmetries { 2 | public use FFI; 3 | // public use MyHDF5; 4 | public use ForeignTypes; 5 | public use StatesEnumeration; 6 | // public use MatrixVectorProduct; 7 | public use DistributedMatrixVector; 8 | public use BatchedOperator; 9 | public use ConcurrentAccessor; 10 | // public use CommunicationQueue; 11 | // public use MultiwayMerge; 12 | public use Vector; 13 | public use Utils; 14 | 15 | private use CTypes; 16 | 17 | proc initExportedKernels() { 18 | var kernels = new ls_chpl_kernels( 19 | enumerate_states=c_ptrTo(ls_chpl_enumerate_representatives), 20 | operator_apply_off_diag=c_ptrTo(ls_chpl_operator_apply_off_diag), 21 | operator_apply_diag=c_ptrTo(ls_chpl_operator_apply_diag), 22 | matrix_vector_product=c_ptrTo(ls_chpl_matrix_vector_product) 23 | ); 24 | // logDebug("Initializing chpl_kernels ..."); 25 | ls_hs_internal_set_chpl_kernels(c_ptrTo(kernels)); 26 | } 27 | 28 | export proc ls_chpl_init_kernels() { 29 | initExportedKernels(); 30 | } 31 | 32 | initExportedKernels(); 33 | } 34 | -------------------------------------------------------------------------------- /python/conda/meta.yaml: -------------------------------------------------------------------------------- 1 | {% set data = load_setup_py_data(setup_file='setup.py') %} 2 | 3 | package: 4 | name: lattice-symmetries 5 | version: {{ data.get('version') }} 6 | 7 | source: 8 | # git_url: https://github.com/twesterhout/nqs-playground 9 | # git_rev: develop 10 | - path: ../ 11 | 12 | build: 13 | number: 2 14 | 15 | test: 16 | requires: 17 | - pytest 18 | source_files: 19 | - run_tests.py 20 | commands: 21 | - python -m pytest run_tests.py 22 | 23 | 24 | requirements: 25 | build: 26 | - {{ compiler('c') }} 27 | - gmp 28 | # - libffi 29 | # - numactl-libs-cos7-x86_64 # [linux] 30 | # - zlib 31 | 32 | host: 33 | - python 34 | - pip 35 | - cffi>=1.15 36 | - numpy 37 | - scipy 38 | - loguru 39 | 40 | run: 41 | - cffi>=1.15 42 | - numpy 43 | - scipy 44 | - loguru 45 | # Runtime libraries needed by C, Haskell, and Chapel code 46 | - gmp 47 | # - libffi 48 | # - zlib 49 | # - numactl-libs-cos7-x86_64 # [linux] 50 | - sysroot_linux-64 # [linux] 51 | # - libstdcxx-ng # [linux] 52 | -------------------------------------------------------------------------------- /test/02_spin_ladder_DM/HPhi/trans.def: -------------------------------------------------------------------------------- 1 | ======================== 2 | NTransfer 12 3 | ======================== 4 | ========i_j_s_tijs====== 5 | ======================== 6 | 0 1 0 0 0.250000000000000 0.000000000000000 7 | 0 0 0 1 0.250000000000000 -0.000000000000000 8 | 1 1 1 0 0.250000000000000 0.000000000000000 9 | 1 0 1 1 0.250000000000000 -0.000000000000000 10 | 2 1 2 0 0.250000000000000 0.000000000000000 11 | 2 0 2 1 0.250000000000000 -0.000000000000000 12 | 3 1 3 0 0.250000000000000 0.000000000000000 13 | 3 0 3 1 0.250000000000000 -0.000000000000000 14 | 4 1 4 0 0.250000000000000 0.000000000000000 15 | 4 0 4 1 0.250000000000000 -0.000000000000000 16 | 5 1 5 0 0.250000000000000 0.000000000000000 17 | 5 0 5 1 0.250000000000000 -0.000000000000000 18 | -------------------------------------------------------------------------------- /haskell/test/LatticeSymmetries/DenseSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE RankNTypes #-} 2 | 3 | module LatticeSymmetries.DenseSpec (spec) where 4 | 5 | import Data.Vector (Vector) 6 | import qualified Data.Vector as B 7 | import LatticeSymmetries.Dense 8 | import Test.Hspec 9 | 10 | spec :: Spec 11 | spec = do 12 | describe "IsList DenseMatrix" $ do 13 | it "converts lists to matrices" $ do 14 | denseMatrixFromList [[1, 2], [3, 4], [5, 6]] `shouldBe` DenseMatrix 3 2 (B.generate 6 (+ 1)) 15 | denseMatrixFromList [] `shouldBe` DenseMatrix 0 0 (B.empty :: Vector Int) 16 | denseMatrixFromList [[], []] `shouldBe` DenseMatrix 2 0 (B.empty :: Vector Int) 17 | denseMatrixFromList [[1, 2, 3]] `shouldBe` DenseMatrix 1 3 (B.generate 3 (+ 1)) 18 | it "converts matrices to lists" $ do 19 | denseMatrixToList (DenseMatrix 3 2 (B.generate 6 (+ 1))) `shouldBe` [[1, 2], [3, 4], [5, 6]] 20 | denseMatrixToList (DenseMatrix 0 0 B.empty) `shouldBe` ([] :: [[Int]]) 21 | denseMatrixToList (DenseMatrix 2 0 B.empty) `shouldBe` ([[], []] :: [[Int]]) 22 | denseMatrixToList (DenseMatrix 1 3 (B.generate 3 (+ 1))) `shouldBe` [[1, 2, 3]] 23 | -------------------------------------------------------------------------------- /test/01_spin_kagome/hamiltonian.yaml: -------------------------------------------------------------------------------- 1 | # Heisenberg antiferromagnet on a 9-site anisotropic Kagome lattice with periodic boundary conditions 2 | basis: 3 | number_spins: 9 4 | hamming_weight: 5 5 | symmetries: [] 6 | hamiltonian: 7 | name: "Heisenberg Hamiltonian" 8 | # Cell: 9 | # 8 10 | # 6 7 11 | # 5 12 | # 3 4 13 | # 2 14 | # 0 1 15 | # Boundaries: 16 | # 4 0 17 | # 8 18 | # 1 6 7 3 19 | # 5 2 20 | # 7 3 4 0 21 | # 2 8 22 | # 4 0 1 6 23 | # 8 5 24 | terms: 25 | # i 26 | # \ 27 | # j 28 | - expression: "Sˣ₀ Sˣ₁ + Sʸ₀ Sʸ₁ + Sᶻ₀ Sᶻ₁" 29 | sites: [[1, 2], [1, 5], [4, 5], [4, 8], [7, 8], [7, 2]] 30 | # j 31 | # / 32 | # i 33 | - expression: "0.5 (Sˣ₀ Sˣ₁ + Sʸ₀ Sʸ₁ + Sᶻ₀ Sᶻ₁)" 34 | sites: [[0, 2], [2, 3], [3, 5], [5, 6], [6, 8], [8, 0]] 35 | # 36 | # i---j 37 | # 38 | - expression: "0.5 (Sˣ₀ Sˣ₁ + Sʸ₀ Sʸ₁ + Sᶻ₀ Sᶻ₁)" 39 | sites: [[0, 1], [1, 6], [3, 4], [4, 0], [6, 7], [7, 3]] 40 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_40_symm.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 40 3 | hamming_weight: 20 4 | spin_inversion: 1 5 | symmetries: 6 | - permutation: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0] 7 | sector: 0 8 | - permutation: [39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 9 | sector: 0 10 | hamiltonian: 11 | name: "Heisenberg Hamiltonian" 12 | lattice: &lattice [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16], [16, 17], [17, 18], [18, 19], [19, 20], [20, 21], [21, 22], [22, 23], [23, 24], [24, 25], [25, 26], [26, 27], [27, 28], [28, 29], [29, 30], [30, 31], [31, 32], [32, 33], [33, 34], [34, 35], [35, 36], [36, 37], [37, 38], [38, 39], [39, 0]] 13 | terms: 14 | - expression: "σˣ₀ σˣ₁" 15 | sites: *lattice 16 | - expression: "σʸ₀ σʸ₁" 17 | sites: *lattice 18 | - expression: "σᶻ₀ σᶻ₁" 19 | sites: *lattice 20 | 21 | -------------------------------------------------------------------------------- /haskell/test/LatticeSymmetries/NonbranchingTermSpec.hs: -------------------------------------------------------------------------------- 1 | module LatticeSymmetries.NonbranchingTermSpec (spec) where 2 | 3 | import LatticeSymmetries.Generator 4 | import LatticeSymmetries.NonbranchingTerm 5 | import Test.Hspec 6 | 7 | spec :: Spec 8 | spec = do 9 | describe "Semigroup NonbranchingTerm" $ do 10 | it ".." $ do 11 | let a = nonbranchingRepresentation (Generator (3 :: Int) FermionCreate) 12 | b = nonbranchingRepresentation (Generator (4 :: Int) FermionAnnihilate) 13 | c = nonbranchingRepresentation (Generator (3 :: Int) FermionAnnihilate) 14 | d = nonbranchingRepresentation (Generator (4 :: Int) FermionIdentity) 15 | -- print a 16 | -- print b 17 | case a <> a of 18 | (NonbranchingTerm v _ _ _ _ _) -> v `shouldBe` 0 19 | case b <> b of 20 | (NonbranchingTerm v _ _ _ _ _) -> v `shouldBe` 0 21 | (a <> c) `shouldBe` (nonbranchingRepresentation (Generator (3 :: Int) FermionCount)) 22 | (d <> d) `shouldBe` d 23 | (a <> d) `shouldBe` a 24 | (d <> a) `shouldBe` a 25 | (b <> d) `shouldBe` b 26 | (d <> b) `shouldBe` b 27 | 28 | -- print (a <> b) 29 | -- print (b <> a) 30 | -------------------------------------------------------------------------------- /chapel/benchmark/BenchmarkMatrixVectorProduct.chpl: -------------------------------------------------------------------------------- 1 | use LatticeSymmetries; 2 | import Random; 3 | import Time; 4 | 5 | 6 | config const kHamiltonian = "data/heisenberg_chain_10.yaml"; 7 | config const kRandomSeed = 42; 8 | config const kRunMatrixVectorProduct = true; 9 | 10 | proc main() { 11 | initRuntime(); 12 | defer deinitRuntime(); 13 | 14 | const (_, matrix) = loadConfigFromYaml(kHamiltonian, hamiltonian=true); 15 | 16 | const masks; 17 | const basisStates = enumerateStates(matrix.basis, masks); 18 | const dimension = + reduce basisStates.counts; 19 | logDebug("Hilbert space dimension: ", dimension); 20 | logDebug("masks.size(): ", masks.localSubdomain().size); 21 | 22 | var timer = new Time.stopwatch(); 23 | timer.start(); 24 | var x = new BlockVector(real(64), 1, basisStates.counts); 25 | coforall loc in Locales with (ref x) do on loc { 26 | ref myX = x.getBlock(loc.id); 27 | Random.fillRandom(myX, seed = kRandomSeed + loc.id); 28 | } 29 | var z = similar(x); 30 | timer.stop(); 31 | logDebug("Allocation and filling: ", timer.elapsed()); 32 | 33 | if kRunMatrixVectorProduct then 34 | matrixVectorProduct(matrix, x, z, basisStates); 35 | } 36 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_42_symm.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 42 3 | hamming_weight: 21 4 | spin_inversion: 1 5 | symmetries: 6 | - permutation: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 0] 7 | sector: 0 8 | - permutation: [41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 9 | sector: 0 10 | hamiltonian: 11 | name: "Heisenberg Hamiltonian" 12 | lattice: &lattice [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16], [16, 17], [17, 18], [18, 19], [19, 20], [20, 21], [21, 22], [22, 23], [23, 24], [24, 25], [25, 26], [26, 27], [27, 28], [28, 29], [29, 30], [30, 31], [31, 32], [32, 33], [33, 34], [34, 35], [35, 36], [36, 37], [37, 38], [38, 39], [39, 40], [40, 41], [41, 0]] 13 | terms: 14 | - expression: "σˣ₀ σˣ₁" 15 | sites: *lattice 16 | - expression: "σʸ₀ σʸ₁" 17 | sites: *lattice 18 | - expression: "σᶻ₀ σᶻ₁" 19 | sites: *lattice 20 | 21 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_kagome_12_symm.yaml: -------------------------------------------------------------------------------- 1 | # Heisenberg antiferromagnet on 12-site Kagome lattice with periodic boundary 2 | # conditions 3 | basis: 4 | number_spins: 12 5 | hamming_weight: 6 6 | symmetries: 7 | # 11 10 8 | # 8 9 6 7 9 | # 5 4 10 | # 2 3 0 1 11 | - permutation: [2, 3, 0, 1, 5, 4, 8, 9, 6, 7, 11, 10] 12 | sector: 0 13 | hamiltonian: 14 | name: "Heisenberg Hamiltonian" 15 | # 10 11 16 | # 6 7 8 9 17 | # 4 5 18 | # 0 1 2 3 19 | lattice: &lattice [[0, 1], [0, 3], [0, 4], [0, 10], 20 | [1, 2], [1, 4], [1, 11], 21 | [2, 3], [2, 5], [2, 11], 22 | [3, 5], [3, 10], 23 | [4, 6], [4, 9], 24 | [5, 7], [5, 8], 25 | [6, 7], [6, 9], [6, 10], 26 | [7, 8], [7, 10], 27 | [8, 9], [8, 11], 28 | [9, 11]] 29 | terms: 30 | - expression: "Sˣ₀ Sˣ₁" 31 | sites: *lattice 32 | - expression: "Sʸ₀ Sʸ₁" 33 | sites: *lattice 34 | - expression: "Sᶻ₀ Sᶻ₁" 35 | sites: *lattice 36 | -------------------------------------------------------------------------------- /chapel/ffi.nix: -------------------------------------------------------------------------------- 1 | { stdenv 2 | , chapel 3 | , lattice-symmetries 4 | , version 5 | }: 6 | 7 | stdenv.mkDerivation { 8 | pname = "lattice-symmetries-chapel-ffi"; 9 | inherit version; 10 | dontUnpack = true; 11 | 12 | buildPhase = '' 13 | c2chapel \ 14 | ${lattice-symmetries.haskell}/include/lattice_symmetries_functions.h \ 15 | -DLS_C2CHAPEL \ 16 | -I${chapel}/runtime/include \ 17 | -I${lattice-symmetries.kernels}/include \ 18 | >FFI.chpl 19 | 20 | # Remove the declaration of chpl_external_array since it's already 21 | # present in the ExternalArray module 22 | sed -i -e '/extern record chpl_external_array/,+5d' FFI.chpl 23 | sed -i -E '/chpl_make_external_array(_ptr)?(_free)?\(/d' FFI.chpl 24 | sed -i -e '/cleanupOpaqueArray(/d' FFI.chpl 25 | sed -i -e '/chpl_free_external_array(/d' FFI.chpl 26 | sed -i -e '/chpl_call_free_func(/d' FFI.chpl 27 | sed -i 's/extern type ls_hs_scalar = _Complex double/extern type ls_hs_scalar = complex(128)/' FFI.chpl 28 | ''; 29 | 30 | installPhase = "install -m 644 FFI.chpl $out"; 31 | buildInputs = [ lattice-symmetries.haskell lattice-symmetries.kernels ]; 32 | nativeBuildInputs = [ chapel ]; 33 | } 34 | -------------------------------------------------------------------------------- /haskell/test/LatticeSymmetries/ComplexRationalSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE RankNTypes #-} 2 | 3 | module LatticeSymmetries.ComplexRationalSpec (spec) where 4 | 5 | import LatticeSymmetries.ComplexRational 6 | import LatticeSymmetries.Utils 7 | import Test.Hspec 8 | import Test.Hspec.QuickCheck 9 | 10 | checkOp :: (forall a. Num a => a -> a -> a) -> (Cscalar, Cscalar) -> Expectation 11 | checkOp op (z₁, z₂) = (toComplexDouble r') `shouldSatisfy` (≈ r) 12 | where 13 | z₁' = fromComplexDouble z₁ :: ComplexRational 14 | z₂' = fromComplexDouble z₂ :: ComplexRational 15 | r = z₁ `op` z₂ 16 | r' = z₁' `op` z₂' 17 | 18 | checkDivide :: (Cscalar, Cscalar) -> Expectation 19 | checkDivide (z₁, z₂) 20 | | z₂ == 0 = pure () 21 | | otherwise = (toComplexDouble r') `shouldSatisfy` (≈ r) 22 | where 23 | z₁' = fromComplexDouble z₁ :: ComplexRational 24 | z₂' = fromComplexDouble z₂ :: ComplexRational 25 | r = z₁ / z₂ 26 | r' = z₁' / z₂' 27 | 28 | spec :: Spec 29 | spec = do 30 | describe "Num ComplexRational" $ do 31 | prop "adds numbers" $ checkOp (+) 32 | prop "subtracts numbers" $ checkOp (-) 33 | prop "multiplies numbers" $ checkOp (*) 34 | prop "divides numbers" $ checkDivide 35 | -------------------------------------------------------------------------------- /test/01_spin_kagome/HPhi/greenone.def: -------------------------------------------------------------------------------- 1 | =============================== 2 | NCisAjs 36 3 | =============================== 4 | ======== Green functions ====== 5 | =============================== 6 | 0 0 0 0 7 | 0 0 0 1 8 | 0 1 0 0 9 | 0 1 0 1 10 | 1 0 1 0 11 | 1 0 1 1 12 | 1 1 1 0 13 | 1 1 1 1 14 | 2 0 2 0 15 | 2 0 2 1 16 | 2 1 2 0 17 | 2 1 2 1 18 | 3 0 3 0 19 | 3 0 3 1 20 | 3 1 3 0 21 | 3 1 3 1 22 | 4 0 4 0 23 | 4 0 4 1 24 | 4 1 4 0 25 | 4 1 4 1 26 | 5 0 5 0 27 | 5 0 5 1 28 | 5 1 5 0 29 | 5 1 5 1 30 | 6 0 6 0 31 | 6 0 6 1 32 | 6 1 6 0 33 | 6 1 6 1 34 | 7 0 7 0 35 | 7 0 7 1 36 | 7 1 7 0 37 | 7 1 7 1 38 | 8 0 8 0 39 | 8 0 8 1 40 | 8 1 8 0 41 | 8 1 8 1 42 | -------------------------------------------------------------------------------- /chapel/test/TestStatesEnumeration.chpl: -------------------------------------------------------------------------------- 1 | use LatticeSymmetries; 2 | use BlockToHashed; 3 | use HashedToBlock; 4 | use MyHDF5; 5 | use Time; 6 | 7 | config const kHamiltonian = "data/heisenberg_kagome_12.yaml"; 8 | config const kRepresentatives = "data/heisenberg_kagome_12.h5"; 9 | 10 | proc main() { 11 | initRuntime(); 12 | defer deinitRuntime(); 13 | 14 | const basis = loadConfigFromYaml(kHamiltonian); 15 | 16 | var timer = new stopwatch(); 17 | timer.start(); 18 | const masks; 19 | const basisStates = enumerateStates(basis, masks); 20 | timer.stop(); 21 | 22 | const predicted = arrFromHashedToBlock(basisStates, masks); 23 | const reference = 24 | readDatasetAsBlocks(kRepresentatives, "/representatives", 25 | rank = 1, eltType = uint(64)); 26 | 27 | const theSame = && reduce [i in reference.domain] reference[i] == predicted[i]; 28 | if !theSame { 29 | var maxErrorCount = 10; 30 | for i in reference.domain { 31 | if reference[i] != predicted[i] && maxErrorCount > 0 { 32 | writeln("at index ", i, ": ", reference[i], " != ", predicted[i]); 33 | maxErrorCount -= 1; 34 | } 35 | } 36 | } 37 | writeln(timer.elapsed()); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /python/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, Extension 2 | import os 3 | import re 4 | 5 | 6 | def get_version(package): 7 | pwd = os.path.dirname(os.path.realpath(__file__)) 8 | with open(os.path.join(pwd, package, "__init__.py"), "r") as input: 9 | result = re.search(r'__version__\s*=\s*[\'"]([^\'"]*)[\'"]', input.read()) 10 | if not result: 11 | raise ValueError("failed to determine {} version".format(package)) 12 | return result.group(1) 13 | 14 | 15 | setup( 16 | name="lattice-symmetries", 17 | version=get_version("lattice_symmetries"), 18 | description="See README.md", 19 | url="http://github.com/twesterhout/lattice-symmetries-haskell", 20 | author="Tom Westerhout", 21 | author_email="14264576+twesterhout@users.noreply.github.com", 22 | license="BSD3", 23 | packages=["lattice_symmetries"], 24 | setup_requires=["cffi>=1.15.0"], 25 | cffi_modules=["lattice_symmetries/build_extension.py:ffibuilder"], 26 | install_requires=[ 27 | "cffi>=1.15.0", 28 | "numpy>=1.23.0", 29 | "scipy>=1.8.0", 30 | "loguru", 31 | ], 32 | package_data={"lattice_symmetries": ["lattice-symmetries-chapel*/**"]}, 33 | zip_safe=False, 34 | ) 35 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_44_symm.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 44 3 | hamming_weight: 22 4 | spin_inversion: 1 5 | symmetries: 6 | - permutation: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 0] 7 | sector: 0 8 | - permutation: [43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 9 | sector: 0 10 | hamiltonian: 11 | name: "Heisenberg Hamiltonian" 12 | lattice: &lattice [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16], [16, 17], [17, 18], [18, 19], [19, 20], [20, 21], [21, 22], [22, 23], [23, 24], [24, 25], [25, 26], [26, 27], [27, 28], [28, 29], [29, 30], [30, 31], [31, 32], [32, 33], [33, 34], [34, 35], [35, 36], [36, 37], [37, 38], [38, 39], [39, 40], [40, 41], [41, 42], [42, 43], [43, 0]] 13 | terms: 14 | - expression: "σˣ₀ σˣ₁" 15 | sites: *lattice 16 | - expression: "σʸ₀ σʸ₁" 17 | sites: *lattice 18 | - expression: "σᶻ₀ σᶻ₁" 19 | sites: *lattice 20 | 21 | -------------------------------------------------------------------------------- /chapel/benchmark/BenchmarkBlockHashed.chpl: -------------------------------------------------------------------------------- 1 | use LatticeSymmetries; 2 | use HashedToBlock; 3 | use BlockToHashed; 4 | use Time; 5 | 6 | config const kHamiltonian = "data/heisenberg_chain_10.yaml"; 7 | 8 | proc main() { 9 | initRuntime(); 10 | defer deinitRuntime(); 11 | 12 | const (_, matrix) = loadConfigFromYaml(kHamiltonian, hamiltonian=true); 13 | 14 | const masks; 15 | const basisStates = enumerateStates(matrix.basis, masks); 16 | 17 | const statesBlock = arrFromHashedToBlock(basisStates, masks); 18 | 19 | const statesHashed = arrFromBlockToHashed(statesBlock, masks); 20 | 21 | forall loc in Locales do on loc { 22 | const ref expected = basisStates.getBlock(loc.id); 23 | const ref predicted = statesHashed.getBlock(loc.id); 24 | const closeEnough = && reduce (expected == predicted); 25 | if (!closeEnough) { 26 | var maxErrorCount = 10; 27 | for i in expected.domain { 28 | if expected[i] != predicted[i] && maxErrorCount > 0 { 29 | writeln("at ", i, ": ", 30 | predicted[i], " (computed) != ", 31 | expected[i], " (expected)"); 32 | maxErrorCount -= 1; 33 | } 34 | } 35 | } 36 | assert(closeEnough); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_46_symm.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 46 3 | hamming_weight: 23 4 | spin_inversion: 1 5 | symmetries: 6 | - permutation: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 0] 7 | sector: 0 8 | - permutation: [45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 9 | sector: 0 10 | hamiltonian: 11 | name: "Heisenberg Hamiltonian" 12 | lattice: &lattice [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16], [16, 17], [17, 18], [18, 19], [19, 20], [20, 21], [21, 22], [22, 23], [23, 24], [24, 25], [25, 26], [26, 27], [27, 28], [28, 29], [29, 30], [30, 31], [31, 32], [32, 33], [33, 34], [34, 35], [35, 36], [36, 37], [37, 38], [38, 39], [39, 40], [40, 41], [41, 42], [42, 43], [43, 44], [44, 45], [45, 0]] 13 | terms: 14 | - expression: "σˣ₀ σˣ₁" 15 | sites: *lattice 16 | - expression: "σʸ₀ σʸ₁" 17 | sites: *lattice 18 | - expression: "σᶻ₀ σᶻ₁" 19 | sites: *lattice 20 | 21 | -------------------------------------------------------------------------------- /test/03_spin_hcor/HPhi/pair.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NPair 16 3 | ============================================= 4 | =============== Pair Excitation ============= 5 | ============================================= 6 | 0 0 0 0 1 -0.500000000000000 -0.000000000000000 7 | 0 1 0 1 1 0.500000000000000 0.000000000000000 8 | 1 0 1 0 1 -0.500000000000000 -0.000000000000000 9 | 1 1 1 1 1 0.500000000000000 0.000000000000000 10 | 2 0 2 0 1 -0.500000000000000 -0.000000000000000 11 | 2 1 2 1 1 0.500000000000000 0.000000000000000 12 | 3 0 3 0 1 -0.500000000000000 -0.000000000000000 13 | 3 1 3 1 1 0.500000000000000 0.000000000000000 14 | 4 0 4 0 1 -0.500000000000000 -0.000000000000000 15 | 4 1 4 1 1 0.500000000000000 0.000000000000000 16 | 5 0 5 0 1 -0.500000000000000 -0.000000000000000 17 | 5 1 5 1 1 0.500000000000000 0.000000000000000 18 | 6 0 6 0 1 -0.500000000000000 -0.000000000000000 19 | 6 1 6 1 1 0.500000000000000 0.000000000000000 20 | 7 0 7 0 1 -0.500000000000000 -0.000000000000000 21 | 7 1 7 1 1 0.500000000000000 0.000000000000000 22 | -------------------------------------------------------------------------------- /test/04_hubbard_square/HPhi/pair.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NPair 16 3 | ============================================= 4 | =============== Pair Excitation ============= 5 | ============================================= 6 | 0 0 0 0 1 0.500000000000000 0.000000000000000 7 | 0 1 0 1 1 -0.500000000000000 -0.000000000000000 8 | 1 0 1 0 1 0.500000000000000 0.000000000000000 9 | 1 1 1 1 1 -0.500000000000000 -0.000000000000000 10 | 2 0 2 0 1 0.500000000000000 0.000000000000000 11 | 2 1 2 1 1 -0.500000000000000 -0.000000000000000 12 | 3 0 3 0 1 0.500000000000000 0.000000000000000 13 | 3 1 3 1 1 -0.500000000000000 -0.000000000000000 14 | 4 0 4 0 1 0.500000000000000 0.000000000000000 15 | 4 1 4 1 1 -0.500000000000000 -0.000000000000000 16 | 5 0 5 0 1 0.500000000000000 0.000000000000000 17 | 5 1 5 1 1 -0.500000000000000 -0.000000000000000 18 | 6 0 6 0 1 0.500000000000000 0.000000000000000 19 | 6 1 6 1 1 -0.500000000000000 -0.000000000000000 20 | 7 0 7 0 1 0.500000000000000 0.000000000000000 21 | 7 1 7 1 1 -0.500000000000000 -0.000000000000000 22 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_chain_48_symm.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 48 3 | hamming_weight: 24 4 | spin_inversion: 1 5 | symmetries: 6 | - permutation: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 0] 7 | sector: 0 8 | - permutation: [47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 9 | sector: 0 10 | hamiltonian: 11 | name: "Heisenberg Hamiltonian" 12 | lattice: &lattice [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16], [16, 17], [17, 18], [18, 19], [19, 20], [20, 21], [21, 22], [22, 23], [23, 24], [24, 25], [25, 26], [26, 27], [27, 28], [28, 29], [29, 30], [30, 31], [31, 32], [32, 33], [33, 34], [34, 35], [35, 36], [36, 37], [37, 38], [38, 39], [39, 40], [40, 41], [41, 42], [42, 43], [43, 44], [44, 45], [45, 46], [46, 47], [47, 0]] 13 | terms: 14 | - expression: "σˣ₀ σˣ₁" 15 | sites: *lattice 16 | - expression: "σʸ₀ σʸ₁" 17 | sites: *lattice 18 | - expression: "σᶻ₀ σᶻ₁" 19 | sites: *lattice 20 | 21 | -------------------------------------------------------------------------------- /.github/workflows/ubuntu.yml: -------------------------------------------------------------------------------- 1 | name: Ubuntu 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | env: 10 | BUILD_TYPE: Debug 11 | INSTALL_LOCATION: .local 12 | 13 | jobs: 14 | build: 15 | strategy: 16 | matrix: 17 | gcc-version: [9, 10, 11] 18 | runs-on: ubuntu-latest 19 | if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')" 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | with: 24 | submodules: true 25 | 26 | - name: install dependencies 27 | run: | 28 | sudo apt update 29 | sudo apt install g++-${{ matrix.gcc-version }} gcc-${{ matrix.gcc-version }} 30 | 31 | - name: configure 32 | run: | 33 | cmake -Bbuild \ 34 | -DCMAKE_CXX_COMPILER=g++-${{ matrix.gcc-version }} \ 35 | -DCMAKE_C_COMPILER=gcc-${{ matrix.gcc-version }} \ 36 | -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ 37 | -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/$INSTALL_LOCATION 38 | 39 | - name: build 40 | run: cmake --build build -j4 41 | 42 | - name: run tests 43 | run: | 44 | cd build 45 | ctest -VV 46 | 47 | - name: install project 48 | run: cmake --build build --target install 49 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_square_5x5.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 25 3 | hamming_weight: 13 4 | symmetries: [] 5 | # - permutation: [1, 2, 3, 4, 0, 6, 7, 8, 9, 5, 11, 12, 13, 14, 10, 16, 17, 18, 19, 15, 21, 22, 23, 24, 20] 6 | # sector: 1 7 | # - permutation: [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, 1, 2, 3, 4] 8 | # sector: 1 9 | hamiltonian: 10 | name: "Heisenberg Hamiltonian" 11 | lattice: &lattice [[0, 1], [0, 5], [1, 2], [1, 6], [2, 3], [2, 7], [3, 4], [3, 8], 12 | [4, 0], [4, 9], [5, 6], [5, 10], [6, 7], [6, 11], [7, 8], [7, 12], 13 | [8, 9], [8, 13], [9, 5], [9, 14], [10, 11], [10, 15], [11, 12], [11, 16], 14 | [12, 13], [12, 17], [13, 14], [13, 18], [14, 10], [14, 19], [15, 16], [15, 20], 15 | [16, 17], [16, 21], [17, 18], [17, 22], [18, 19], [18, 23], [19, 15], [19, 24], 16 | [20, 21], [20, 0], [21, 22], [21, 1], [22, 23], [22, 2], [23, 24], [23, 3], 17 | [24, 20], [24, 4]] 18 | terms: 19 | - expression: "σˣ₀ σˣ₁" 20 | sites: *lattice 21 | - expression: "σʸ₀ σʸ₁" 22 | sites: *lattice 23 | - expression: "σᶻ₀ σᶻ₁" 24 | sites: *lattice 25 | observables: [] 26 | number_vectors: 1 27 | output: "heisenberg_square_5x5.h5" 28 | # datatype: "float32" 29 | # precision: 5.0e-7 30 | max_primme_block_size: 2 31 | max_primme_basis_size: 20 32 | -------------------------------------------------------------------------------- /.github/workflows/macos.yml: -------------------------------------------------------------------------------- 1 | name: OS X 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | env: 10 | BUILD_TYPE: Debug 11 | INSTALL_LOCATION: .local 12 | 13 | jobs: 14 | build: 15 | runs-on: macos-latest 16 | if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')" 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | with: 21 | submodules: true 22 | 23 | - name: install dependencies 24 | run: | 25 | brew install libomp 26 | 27 | - name: configure 28 | run: | 29 | # NOTE: AppleClang fails to find OpenMP 30 | # and GCC fails to link Halide generators since Halide was built against libc++ 31 | # ... so... we stick to LLVM/Clang 32 | cmake -Bbuild \ 33 | -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ 34 | -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/$INSTALL_LOCATION \ 35 | -DCMAKE_C_COMPILER="$(brew --prefix llvm@14)/bin/clang" \ 36 | -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@14)/bin/clang++" 37 | 38 | - name: build 39 | run: cmake --build build -j4 40 | 41 | - name: run tests 42 | run: | 43 | cd build 44 | ctest -VV 45 | 46 | - name: install project 47 | run: cmake --build build --target install 48 | -------------------------------------------------------------------------------- /test/01_spin_kagome/HPhi/pair.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NPair 18 3 | ============================================= 4 | =============== Pair Excitation ============= 5 | ============================================= 6 | 0 0 0 0 1 -0.500000000000000 -0.000000000000000 7 | 0 1 0 1 1 0.500000000000000 0.000000000000000 8 | 1 0 1 0 1 -0.500000000000000 -0.000000000000000 9 | 1 1 1 1 1 0.500000000000000 0.000000000000000 10 | 2 0 2 0 1 -0.500000000000000 -0.000000000000000 11 | 2 1 2 1 1 0.500000000000000 0.000000000000000 12 | 3 0 3 0 1 -0.500000000000000 -0.000000000000000 13 | 3 1 3 1 1 0.500000000000000 0.000000000000000 14 | 4 0 4 0 1 -0.500000000000000 -0.000000000000000 15 | 4 1 4 1 1 0.500000000000000 0.000000000000000 16 | 5 0 5 0 1 -0.500000000000000 -0.000000000000000 17 | 5 1 5 1 1 0.500000000000000 0.000000000000000 18 | 6 0 6 0 1 -0.500000000000000 -0.000000000000000 19 | 6 1 6 1 1 0.500000000000000 0.000000000000000 20 | 7 0 7 0 1 -0.500000000000000 -0.000000000000000 21 | 7 1 7 1 1 0.500000000000000 0.000000000000000 22 | 8 0 8 0 1 -0.500000000000000 -0.000000000000000 23 | 8 1 8 1 1 0.500000000000000 0.000000000000000 24 | -------------------------------------------------------------------------------- /test/03_spin_hcor/HPhi/trans.def: -------------------------------------------------------------------------------- 1 | ======================== 2 | NTransfer 16 3 | ======================== 4 | ========i_j_s_tijs====== 5 | ======================== 6 | 0 0 0 0 -0.500000000000000 0.000000000000000 7 | 0 1 0 1 0.500000000000000 0.000000000000000 8 | 1 0 1 0 -0.500000000000000 0.000000000000000 9 | 1 1 1 1 0.500000000000000 0.000000000000000 10 | 2 0 2 0 -0.500000000000000 0.000000000000000 11 | 2 1 2 1 0.500000000000000 0.000000000000000 12 | 3 0 3 0 -0.500000000000000 0.000000000000000 13 | 3 1 3 1 0.500000000000000 0.000000000000000 14 | 4 0 4 0 -0.500000000000000 0.000000000000000 15 | 4 1 4 1 0.500000000000000 0.000000000000000 16 | 5 0 5 0 -0.500000000000000 0.000000000000000 17 | 5 1 5 1 0.500000000000000 0.000000000000000 18 | 6 0 6 0 -0.500000000000000 0.000000000000000 19 | 6 1 6 1 0.500000000000000 0.000000000000000 20 | 7 0 7 0 -0.500000000000000 0.000000000000000 21 | 7 1 7 1 0.500000000000000 0.000000000000000 22 | -------------------------------------------------------------------------------- /chapel/src/ConcurrentAccessor.chpl: -------------------------------------------------------------------------------- 1 | module ConcurrentAccessor { 2 | 3 | use FFI; 4 | use CTypes; 5 | use ChapelLocks; 6 | 7 | // config const concurrentAccessorNumLocks = 5 * here.maxTaskPar; 8 | 9 | // A simple wrapper around an array `y` which synchronizes accesses. The only 10 | // operation which is allowed is `y[i] += x` <-> `accessor.localAdd(i, x)`. We use 11 | // multiple locks such that multiple threads have lower chance of trying to 12 | // access the same block at the same time. Doing so is still thread-safe, but 13 | // could negatively impact perforamnce especially on machines with high core 14 | // count. 15 | record ConcurrentAccessor { 16 | type eltType; 17 | var _data : c_ptr(chpl__processorAtomicType(eltType)); 18 | var _numElts : int; 19 | 20 | proc init(ref arr : [] ?t) 21 | where arr.domain.rank == 1 && arr.domain.strides == strideKind.one { 22 | if arr.locale != here then 23 | halt("ConcurrentAccessor can only be constructed around a local array"); 24 | this.eltType = t; 25 | // We go via c_void_ptr, because otherwise chpl issues a warning that we're 26 | // casting to a non-equivalent pointer type 27 | this._data = c_ptrTo(arr[arr.domain.low]):c_void_ptr:c_ptr(chpl__processorAtomicType(eltType)); 28 | this._numElts = arr.size; 29 | } 30 | 31 | inline proc localAdd(i : int, x : eltType) { 32 | _data[i].add(x, order=memoryOrder.relaxed); 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /chapel/src/library.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void ls_chpl_init(void); 5 | void ls_chpl_finalize(void); 6 | 7 | extern void chpl__init_BatchedOperator(int64_t _ln, int32_t _fn); 8 | extern void chpl__init_CommonParameters(int64_t _ln, int32_t _fn); 9 | extern void chpl__init_ConcurrentAccessor(int64_t _ln, int32_t _fn); 10 | extern void chpl__init_DistributedMatrixVector(int64_t _ln, int32_t _fn); 11 | extern void chpl__init_FFI(int64_t _ln, int32_t _fn); 12 | extern void chpl__init_ForeignTypes(int64_t _ln, int32_t _fn); 13 | extern void chpl__init_LatticeSymmetries(int64_t _ln, int32_t _fn); 14 | extern void chpl__init_StatesEnumeration(int64_t _ln, int32_t _fn); 15 | extern void chpl__init_Vector(int64_t _ln, int32_t _fn); 16 | extern void chpl_library_init(int argc, char *argv[]); 17 | extern void chpl_library_finalize(void); 18 | 19 | void ls_chpl_init(void) { 20 | int const argc = 1; 21 | char const *argv[2] = {"lattice_symmetries", NULL}; 22 | chpl_library_init(argc, (char**)argv); 23 | chpl__init_BatchedOperator(1, 2); 24 | chpl__init_CommonParameters(1, 2); 25 | chpl__init_ConcurrentAccessor(1, 2); 26 | chpl__init_DistributedMatrixVector(1, 2); 27 | chpl__init_FFI(1, 2); 28 | chpl__init_ForeignTypes(1, 2); 29 | chpl__init_StatesEnumeration(1, 2); 30 | chpl__init_Vector(1, 2); 31 | chpl__init_LatticeSymmetries(1, 2); 32 | } 33 | 34 | void ls_chpl_finalize(void) { chpl_library_finalize(); } 35 | -------------------------------------------------------------------------------- /haskell/test/LatticeSymmetries/BitStringSpec.hs: -------------------------------------------------------------------------------- 1 | module LatticeSymmetries.BitStringSpec (spec) where 2 | 3 | import qualified Data.Vector.Storable as S 4 | import qualified Data.Vector.Storable.Mutable as SM 5 | import LatticeSymmetries.BitString 6 | import System.IO.Unsafe (unsafePerformIO) 7 | import Test.Hspec 8 | import Test.Hspec.QuickCheck 9 | import Test.QuickCheck (Arbitrary (..)) 10 | import Prelude hiding (words) 11 | 12 | log2 :: Integer -> Int 13 | log2 !n 14 | | n == 1 = 0 15 | | n > 1 = 1 + log2 (div n 2) 16 | | otherwise = error "invalid n" 17 | 18 | numberWords :: BitString -> Int 19 | numberWords (BitString n) 20 | | n == 0 = 0 21 | | otherwise = 1 + log2 n 22 | 23 | instance Arbitrary BitString where 24 | arbitrary = (BitString . abs) <$> arbitrary 25 | 26 | spec :: Spec 27 | spec = do 28 | describe "readBitString <-> writeBitString" $ do 29 | prop "writes to vector & reads from memory" $ \x -> 30 | let n = numberWords x 31 | words = wordsFromBitString n x 32 | y = unsafePerformIO $ 33 | S.unsafeWith words $ \wordsPtr -> 34 | readBitString n wordsPtr 35 | in y `shouldBe` x 36 | prop "writes to memory & reads from memory" $ \x -> 37 | let n = numberWords x 38 | y = unsafePerformIO $ do 39 | buf <- SM.new n 40 | SM.unsafeWith buf $ \bufPtr -> 41 | writeBitString n bufPtr x 42 | SM.unsafeWith buf $ \bufPtr -> 43 | readBitString n bufPtr 44 | in y `shouldBe` x 45 | -------------------------------------------------------------------------------- /haskell/test/LatticeSymmetries/ConversionSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedLists #-} 2 | {-# LANGUAGE OverloadedRecordDot #-} 3 | 4 | module LatticeSymmetries.ConversionSpec (spec) where 5 | 6 | import Data.Text.IO qualified as Text 7 | import LatticeSymmetries.Basis 8 | import LatticeSymmetries.Conversion 9 | import LatticeSymmetries.Expr 10 | import LatticeSymmetries.Generator 11 | import LatticeSymmetries.Group 12 | import LatticeSymmetries.Utils 13 | import Test.Hspec 14 | 15 | spec :: Spec 16 | spec = do 17 | describe "Conversion" $ do 18 | it "prepareHPhi" $ do 19 | let 20 | basis = SpinBasis 4 (Just 2) Nothing emptySymmetries 21 | expr = 22 | spinsToFermions $ 23 | mkExpr SpinTag "σˣ₀ σˣ₁ + σʸ₀ σʸ₁ + σᶻ₀ σᶻ₁ + σˣ₁ σˣ₂ + σʸ₁ σʸ₂ + σᶻ₁ σᶻ₂ + σˣ₂ σˣ₃ + σʸ₂ σʸ₃ + σᶻ₂ σᶻ₃ + σˣ₃ σˣ₀ + σʸ₃ σʸ₀ + σᶻ₃ σᶻ₀" 24 | (hphi, others) = extractInteractions expr 25 | isHermitianExpr expr `shouldBe` True 26 | Text.putStrLn $ toPrettyText others 27 | Text.putStrLn $ show hphi.exchange 28 | others `shouldBe` Expr [] 29 | prepareHPhi "/tmp/lattice-symmetries-haskell/hphi" basis hphi 30 | it "preparemVMC" $ do 31 | let 32 | basis = SpinfulFermionBasis 2 (SpinfulTotalParticles 2) 33 | expr = mkExpr SpinfulFermionTag "- 2 (c†₁↑ c₀↑ + c†₀↑ c₁↑ + c†₁↓ c₀↓ + c†₀↓ c₁↓) + 4.0 n₀↑ n₀↓ + 4.0 n₁↑ n₁↓" 34 | (int, others) = extractInteractions expr 35 | isHermitianExpr expr `shouldBe` True 36 | others `shouldBe` Expr [] 37 | prepareVMC "/tmp/lattice-symmetries-haskell/vmc" basis int 38 | -------------------------------------------------------------------------------- /haskell/test/LatticeSymmetries/GroupSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedLists #-} 2 | 3 | module LatticeSymmetries.GroupSpec (spec) where 4 | 5 | import qualified Data.Aeson as Aeson 6 | import Data.Bits 7 | import Data.Vector (Vector) 8 | import qualified Data.Vector.Generic as G 9 | import LatticeSymmetries.Benes 10 | import Test.Hspec 11 | import Test.Hspec.QuickCheck 12 | import Test.QuickCheck 13 | 14 | spec :: Spec 15 | spec = do 16 | -- describe "mkSymmetries" $ do 17 | -- it "should build symmetry groups" $ do 18 | -- print $ 19 | -- mkSymmetries 20 | -- [ mkSymmetry (mkPermutation [1, 2, 3, 0]) 0, 21 | -- mkSymmetry (mkPermutation [3, 2, 1, 0]) 1 22 | -- ] 23 | -- True `shouldBe` True 24 | describe "FromJSON Symmetry" $ do 25 | it "parses Symmetry" $ do 26 | Aeson.decode "{\"permutation\": [1, 2, 3, 0], \"sector\": 2}" `shouldBe` Just (mkSymmetry [1, 2, 3, 0] 2) 27 | Aeson.decode "{\"permutation\": [0, 1], \"sector\": 0}" `shouldBe` Just (mkSymmetry [0, 1] 0) 28 | Aeson.decode "{\"permutation\": [], \"sector\": 0}" `shouldBe` Just (mkSymmetry [] 0) 29 | describe "FromJSON Symmetries" $ do 30 | it "parses Symmetries" $ do 31 | Aeson.decode "[{\"permutation\": [1, 2, 0], \"sector\": 1}]" 32 | `shouldBe` Just ([mkSymmetry [1, 2, 0] 1] :: Symmetries) 33 | Aeson.decode 34 | "[{\"permutation\": [1, 2, 3, 0], \"sector\": 0}, \ 35 | \ {\"permutation\": [3, 2, 1, 0], \"sector\": 0}]" 36 | `shouldBe` Just ([mkSymmetry [1, 2, 3, 0] 0, mkSymmetry [3, 2, 1, 0] 0] :: Symmetries) 37 | -------------------------------------------------------------------------------- /template/install-jupyter-kernel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -o pipefail 5 | 6 | show_help() { 7 | cat <<-EOF 8 | Usage: ${0##*/} [-h] [NAME] 9 | 10 | -h display this help and exit 11 | EOF 12 | } 13 | 14 | OPTIND=1 15 | while getopts h: opt; do 16 | case $opt in 17 | h) 18 | show_help 19 | exit 0 20 | ;; 21 | *) 22 | show_help >&2 23 | exit 1 24 | ;; 25 | esac 26 | done 27 | shift "$((OPTIND - 1))" 28 | 29 | PROJECT_NAME="lattice-symmetries-kernel" 30 | if [[ $# -ge 1 ]]; then 31 | PROJECT_NAME=$1 32 | fi 33 | 34 | # NOTE: Determine the location of the script. 35 | # See https://stackoverflow.com/a/246128 for details 36 | SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) 37 | 38 | cd "$SCRIPT_DIR" 39 | # Build the container 40 | CONTAINER_PATH=$(nix build --no-link --print-out-paths .) 41 | # Copy the container to the current directory 42 | nix shell nixpkgs#coreutils -c sh -c "cp -b -f -v '$CONTAINER_PATH' container.img" 43 | # Install the ipython kernel 44 | singularity exec container.img python3 -m ipykernel install \ 45 | --user \ 46 | --name="$PROJECT_NAME" 47 | 48 | cat >"$HOME/.local/share/jupyter/kernels/$PROJECT_NAME/kernel.json" <lattice_symmetries/extracted_declarations.h 28 | awk '/python-cffi: START/{flag=1;next}/python-cffi: STOP/{flag=0}flag' \ 29 | ${prev.lattice-symmetries.haskell}/include/lattice_symmetries_functions.h \ 30 | >>lattice_symmetries/extracted_declarations.h 31 | ''; 32 | 33 | preCheck = "rm -rf lattice_symmetries"; 34 | 35 | checkPhase = '' 36 | runHook preCheck 37 | python3 -m pytest --color=yes --capture=no test/test_api.py | tee output.txt 38 | grep -q -E '(FAILURES|failed)' output.txt && exit 1 39 | runHook postCheck 40 | ''; 41 | 42 | nativeCheckInputs = with python-final; [ pytestCheckHook ]; 43 | }; 44 | }) 45 | ]; 46 | lattice-symmetries = (prev.lattice-symmetries or { }) // { 47 | python = prev.python3Packages.lattice-symmetries; 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > ⚠️ **INFO** 2 | > 3 | > This is a Haskell rewrite of the original 4 | > [lattice-symmetries](https://github.com/twesterhout/lattice-symmetries). At 5 | > some point, this package will completely replace the first version of 6 | > lattice-symmetries. 7 | 8 | # lattice-symmetries [![Build](https://github.com/twesterhout/lattice-symmetries-haskell/actions/workflows/ci.yml/badge.svg)](https://github.com/twesterhout/lattice-symmetries-haskell/actions/workflows/ci.yml) 9 | [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) 10 | 11 | A package to simplify working with symmetry-adapted quantum many-body bases. 12 | 13 | 14 | ## Hamiltonians 15 | 16 | #### Spins 17 | 18 | 19 | 20 | 21 | 28 | 35 | 36 | 37 | 44 | 49 | 50 | 51 | 58 | 65 | 66 |
MathsCode
22 | 23 | $$ 24 | \mathbf{S}_i \cdot \mathbf{S}_j = S^x_i S^x_j + S^y_i S^y_j + S^z_i S^z_j 25 | $$ 26 | 27 | 29 | 30 | `"Sˣ₀ Sˣ₁ + Sʸ₀ Sʸ₁ + Sᶻ₀ Sᶻ₁"` 31 | or 32 | `"Sx0 Sx0 + Sy1 Sy1 + Sz0 Sz1"` 33 | 34 |
38 | 39 | $$ 40 | \mathbf{S}_i \cdot \mathbf{S}_j = \frac{1}{4} \left( \sigma^x_i \sigma^x_j + \sigma^y_i \sigma^y_j + \sigma^z_i \sigma^z_j \right) 41 | $$ 42 | 43 | 45 | 46 | `"0.25 (σˣ₀ σˣ₁ + σʸ₀ σʸ₁ + σᶻ₀ σᶻ₁)"` 47 | 48 |
52 | 53 | $$ 54 | \sigma^{+}_i \sigma^{-}_j 55 | $$ 56 | 57 | 59 | 60 | `"σ⁺₀ σ⁻₁"` or 61 | `"\sigma^+_0 \sigma^-_1"` or 62 | `"\sigma+0 \sigma-1"` 63 | 64 |
67 | 68 | #### Electrons 69 | 70 | 71 | 72 | 83 | 95 |
MathsCode
73 | 74 | $$ 75 | c^\dagger_{i\uparrow}c_{j\uparrow} + c^\dagger_{i\downarrow}c_{j\downarrow} 76 | $$ 77 | 78 | 79 | 80 | `"c†₀↑ c₁↑ + c†₀↓ c₁↓"` 81 | 82 |
84 | 85 | $$ 86 | n_{i\uparrow} n_{i\downarrow} 87 | $$ 88 | 89 | 90 | 91 | `"n₀↑ n₀↓"` or 92 | `"n0up n0down"` 93 | 94 |
96 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_square_4x4.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 16 3 | hamming_weight: 8 4 | spin_inversion: 1 5 | symmetries: 6 | # Initial layout: 7 | # - permutation: [ 0, 1, 2, 3, 8 | # 4, 5, 6, 7, 9 | # 8, 9, 10, 11, 10 | # 12, 13, 14, 15] 11 | # 12 | # Translation along x-axis 13 | - permutation: [ 1, 2, 3, 0, 14 | 5, 6, 7, 4, 15 | 9, 10, 11, 8, 16 | 13, 14, 15, 12] 17 | sector: 0 18 | # Translation along y-axis 19 | - permutation: [ 4, 5, 6, 7, 20 | 8, 9, 10, 11, 21 | 12, 13, 14, 15, 22 | 0, 1, 2, 3] 23 | sector: 0 24 | # Reflection along x-axis (i.e. around y-axis) 25 | - permutation: [ 3, 2, 1, 0, 26 | 7, 6, 5, 4, 27 | 11, 10, 9, 8, 28 | 15, 14, 13, 12] 29 | sector: 0 30 | # Reflection along y-axis (i.e. around x-axis) 31 | - permutation: [12, 13, 14, 15, 32 | 8, 9, 10, 11, 33 | 4, 5, 6, 7, 34 | 0, 1, 2, 3] 35 | sector: 0 36 | # Rotation 37 | - permutation: [ 3, 7, 11, 15, 38 | 2, 6, 10, 14, 39 | 1, 5, 9, 13, 40 | 0, 4, 8, 12] 41 | sector: 0 42 | hamiltonian: 43 | name: "Heisenberg Hamiltonian" 44 | lattice: &lattice [[0, 1], [0, 4], [1, 2], [1, 5], [2, 3], [2, 6], [3, 0], [3, 7], 45 | [4, 5], [4, 8], [5, 6], [5, 9], [6, 7], [6, 10], [7, 4], [7, 11], 46 | [8, 9], [8, 12], [9, 10], [9, 13], [10, 11], [10, 14], [11, 8], [11, 15], 47 | [12, 13], [12, 0], [13, 14], [13, 1], [14, 15], [14, 2], [15, 12], [15, 3]] 48 | terms: 49 | - expression: "σˣ₀ σˣ₁" 50 | sites: *lattice 51 | - expression: "σʸ₀ σʸ₁" 52 | sites: *lattice 53 | - expression: "σᶻ₀ σᶻ₁" 54 | sites: *lattice 55 | -------------------------------------------------------------------------------- /haskell/src/LatticeSymmetries/Yaml.hs: -------------------------------------------------------------------------------- 1 | module LatticeSymmetries.Yaml where 2 | 3 | import Data.Aeson 4 | import Data.Aeson.Key qualified 5 | import Data.Aeson.KeyMap qualified 6 | import Data.Aeson.Types (Parser) 7 | import Data.Vector (Vector) 8 | import Data.Vector.Generic qualified as G 9 | import Data.Yaml.Aeson (decodeFileWithWarnings, prettyPrintParseException) 10 | import LatticeSymmetries.Basis 11 | import LatticeSymmetries.Expr 12 | import LatticeSymmetries.Operator 13 | 14 | data ConfigSpec = ConfigSpec !SomeBasis !(Maybe SomeOperator) !(Vector SomeOperator) 15 | 16 | instance FromJSON ConfigSpec where 17 | parseJSON = withObject "Config" $ \v -> do 18 | someBasis <- v .: "basis" 19 | maybeHamiltonian <- 20 | withSomeBasis someBasis $ \basis -> 21 | case Data.Aeson.KeyMap.lookup (Data.Aeson.Key.fromString "hamiltonian") v of 22 | Just h -> 23 | Just . SomeOperator (getParticleTag basis) 24 | <$> operatorFromJSON basis h 25 | Nothing -> pure Nothing 26 | observables <- 27 | withSomeBasis someBasis $ \basis -> 28 | case Data.Aeson.KeyMap.lookup (Data.Aeson.Key.fromString "observables") v of 29 | Just h -> 30 | flip (withArray "Observables") h $ 31 | G.mapM (fmap (SomeOperator (getParticleTag basis)) . operatorFromJSON basis) 32 | Nothing -> pure G.empty 33 | pure $ ConfigSpec someBasis maybeHamiltonian observables 34 | 35 | configFromYAML :: HasCallStack => Text -> IO ConfigSpec 36 | configFromYAML = objectFromYAML "config" 37 | 38 | operatorFromJSON :: IsBasis t => Basis t -> Value -> Parser (Operator t) 39 | operatorFromJSON basis = withObject "Operator" $ \v -> do 40 | ((t :| ts) :: NonEmpty (Expr t)) <- v .: "terms" 41 | pure $ mkOperator basis (foldl' (+) t ts) 42 | 43 | objectFromYAML :: (HasCallStack, FromJSON a) => Text -> Text -> IO a 44 | objectFromYAML _ filename = do 45 | r <- decodeFileWithWarnings (toString filename) 46 | case r of 47 | Left e -> error $ toText $ prettyPrintParseException e 48 | Right (_, x) -> pure x 49 | -------------------------------------------------------------------------------- /chapel/test/TestMatrixVectorProduct.chpl: -------------------------------------------------------------------------------- 1 | use LatticeSymmetries; 2 | use MyHDF5; 3 | use HashedToBlock; 4 | use BlockToHashed; 5 | use Time; 6 | 7 | proc localLoadVectors(filename : string, x : string = "/x", y : string = "/y") { 8 | var input = readDataset(filename, x, real(64), rank = 2)[0, ..]; 9 | var output = readDataset(filename, y, real(64), rank = 2)[0, ..]; 10 | return (input, output); 11 | } 12 | 13 | config const kHamiltonian = "data/heisenberg_chain_10.yaml"; 14 | config const kVectors = "data/matvec/heisenberg_chain_10.h5"; 15 | config const kAbsTol = 1e-13; 16 | config const kRelTol = 1e-11; 17 | 18 | proc approxEqual(a : real, b : real, atol = kAbsTol, rtol = kRelTol) { 19 | return abs(a - b) <= max(atol, rtol * max(abs(a), abs(b))); 20 | } 21 | proc approxEqual(a : [], b : [], atol = kAbsTol, rtol = kRelTol) { 22 | return [i in a.domain] approxEqual(a[i], b[i], atol, rtol); 23 | } 24 | 25 | proc main() { 26 | initRuntime(); 27 | defer deinitRuntime(); 28 | 29 | const (_, matrix) = loadConfigFromYaml(kHamiltonian, hamiltonian=true); 30 | 31 | const masks; 32 | const basisStates = enumerateStates(matrix.basis, masks); 33 | 34 | const x = arrFromBlockToHashed(readDatasetAsBlocks(kVectors, "/x"), masks); 35 | 36 | var z = similar(x); 37 | 38 | var timer = new stopwatch(); 39 | timer.start(); 40 | matrixVectorProduct(matrix, x, z, basisStates); 41 | timer.stop(); 42 | 43 | const yBlock = readDatasetAsBlocks(kVectors, "/y"); 44 | const zBlock = arrFromHashedToBlock(z, masks); 45 | 46 | const closeEnough = && reduce approxEqual(yBlock, zBlock); 47 | writeln(closeEnough); 48 | if (!closeEnough) { 49 | var maxErrorCount = 10; 50 | for i in yBlock.domain { 51 | if !approxEqual(zBlock[i], yBlock[i]) && maxErrorCount > 0 { 52 | writeln("at ", i, ": ", 53 | zBlock[i], " (computed) != ", 54 | yBlock[i], " (expected); Δ = ", 55 | abs(zBlock[i] - yBlock[i])); 56 | maxErrorCount -= 1; 57 | } 58 | } 59 | } 60 | assert(closeEnough); 61 | writeln(timer.elapsed()); 62 | } 63 | -------------------------------------------------------------------------------- /python/example/getting_started.py: -------------------------------------------------------------------------------- 1 | from functools import reduce 2 | import lattice_symmetries as ls 3 | import numpy as np 4 | import operator 5 | import scipy.sparse.linalg 6 | 7 | 8 | def main(): 9 | number_spins = 10 # System size 10 | hamming_weight = number_spins // 2 # Hamming weight (i.e. number of spin ups) 11 | 12 | # Constructing symmetries 13 | sites = np.arange(number_spins) 14 | # Momentum in x direction with eigenvalue π 15 | T = ls.Symmetry((sites + 1) % number_spins, sector=number_spins // 2) 16 | # Parity with eigenvalue π 17 | P = ls.Symmetry(sites[::-1], sector=1) 18 | 19 | # Constructing the group 20 | symmetries = ls.Symmetries([T, P]) 21 | print("Symmetry group contains {} elements".format(len(symmetries))) 22 | 23 | # Constructing the basis 24 | basis = ls.SpinBasis( 25 | number_spins=number_spins, 26 | # NOTE: we don't actually need to specify hamming_weight when spin_inversion 27 | # is set. The library will guess that hamming_weight = number_spins / 2. 28 | spin_inversion=-1, 29 | symmetries=symmetries, 30 | ) 31 | basis.build() # Build the list of representatives, we need it since we're doing ED 32 | print("Hilbert space dimension is {}".format(basis.number_states)) 33 | 34 | edges = [(i, (i + 1) % number_spins) for i in range(number_spins)] 35 | expr = ls.Expr("2 (σ⁺₀ σ⁻₁ + σ⁺₁ σ⁻₀) + σᶻ₀ σᶻ₁", sites=edges) 36 | print("Expression:", expr) 37 | 38 | # Alternatively, we can create expr in an algebraic way: 39 | two_site_expr = ls.Expr("2 (σ⁺₀ σ⁻₁ + σ⁺₁ σ⁻₀) + σᶻ₀ σᶻ₁") 40 | many_exprs = [two_site_expr.replace_indices({0: i, 1: j}) for (i, j) in edges] 41 | expr2 = reduce(operator.add, many_exprs) 42 | assert expr == expr2 43 | 44 | # Construct the Hamiltonian 45 | hamiltonian = ls.Operator(basis, expr) 46 | 47 | 48 | # Diagonalize the Hamiltonian using ARPACK 49 | eigenvalues, eigenstates = scipy.sparse.linalg.eigsh(hamiltonian, k=1, which="SA") 50 | print("Ground state energy is {}".format(eigenvalues[0])) 51 | assert np.isclose(eigenvalues[0], -18.06178542) 52 | 53 | 54 | if __name__ == "__main__": 55 | main() 56 | -------------------------------------------------------------------------------- /chapel/lib/lattice_symmetries_chapel.h: -------------------------------------------------------------------------------- 1 | #include "stdchpl.h" 2 | #include "ctype.h" 3 | #include "wctype.h" 4 | #include "lattice_symmetries_types.h" 5 | void chpl__init_BatchedOperator(int64_t _ln, 6 | int32_t _fn); 7 | void ls_chpl_operator_apply_diag(ls_hs_operator * matrixPtr, 8 | int64_t count, 9 | uint64_t * alphas, 10 | chpl_external_array * coeffs, 11 | int64_t numTasks); 12 | void ls_chpl_operator_apply_off_diag(ls_hs_operator * matrixPtr, 13 | int64_t count, 14 | uint64_t * alphas, 15 | chpl_external_array * betas, 16 | chpl_external_array * coeffs, 17 | chpl_external_array * offsets, 18 | int64_t numTasks); 19 | void chpl__init_CommonParameters(int64_t _ln, 20 | int32_t _fn); 21 | void chpl__init_ConcurrentAccessor(int64_t _ln, 22 | int32_t _fn); 23 | void chpl__init_DistributedMatrixVector(int64_t _ln, 24 | int32_t _fn); 25 | void ls_chpl_matrix_vector_product(ls_hs_operator * matrixPtr, 26 | int32_t numVectors, 27 | _real64 * xPtr, 28 | _real64 * yPtr); 29 | void chpl__init_FFI(int64_t _ln, 30 | int32_t _fn); 31 | void chpl__init_ForeignTypes(int64_t _ln, 32 | int32_t _fn); 33 | void chpl__init_LatticeSymmetries(int64_t _ln, 34 | int32_t _fn); 35 | void ls_chpl_init_kernels(void); 36 | void chpl__init_StatesEnumeration(int64_t _ln, 37 | int32_t _fn); 38 | void ls_chpl_enumerate_representatives(ls_hs_basis * p, 39 | uint64_t lower, 40 | uint64_t upper, 41 | chpl_external_array * dest); 42 | void chpl__init_Vector(int64_t _ln, 43 | int32_t _fn); 44 | -------------------------------------------------------------------------------- /haskell/overlay.nix: -------------------------------------------------------------------------------- 1 | { lib 2 | , withPic 3 | }: 4 | 5 | self: super: rec { 6 | haskell = super.haskell // { 7 | packageOverrides = lib.composeExtensions super.haskell.packageOverrides 8 | (hself: hsuper: { 9 | lattice-symmetries-haskell = 10 | (hself.callCabal2nix "lattice-symmetries-haskell" ./. { 11 | inherit (super.lattice-symmetries) kernels; 12 | }).overrideAttrs 13 | (attrs: { 14 | outputs = (attrs.outputs or [ ]) ++ [ "lib" ]; 15 | postInstall = '' 16 | ${attrs.postInstall or ""} 17 | 18 | echo "Installing foreign library to $lib ..." 19 | mkdir -p $lib/lib 20 | install -v -Dm 755 \ 21 | $out/lib/ghc-*/lib/liblattice_symmetries_haskell.so \ 22 | $lib/lib/ 23 | 24 | mkdir -p $out/include 25 | install -v -Dm 644 \ 26 | lattice_symmetries_functions.h \ 27 | $out/include/ 28 | ''; 29 | }); 30 | } 31 | // lib.optionalAttrs (withPic && (lib.versionAtLeast hsuper.ghc.version "9.6.1")) { 32 | # Ensure that all Haskell packages are built with -fPIC 33 | mkDerivation = args: (hsuper.mkDerivation args).overrideAttrs (attrs: { 34 | configureFlags = (attrs.configureFlags or [ ]) ++ [ 35 | "--ghc-option=-fPIC" 36 | "--ghc-option=-fexternal-dynamic-refs" 37 | ]; 38 | }); 39 | } 40 | // lib.optionalAttrs (lib.versionAtLeast hsuper.ghc.version "9.6.1") { 41 | # Loosen constraints to make them build with 9.6.1 42 | tagged = super.haskell.lib.doJailbreak hsuper.tagged; 43 | zigzag = super.haskell.lib.doJailbreak hsuper.zigzag; 44 | typerep-map = super.haskell.lib.doJailbreak hsuper.typerep-map; 45 | relude = super.haskell.lib.dontCheck (super.haskell.lib.doJailbreak hsuper.relude); 46 | bytebuild = super.haskell.lib.doJailbreak hsuper.bytebuild; 47 | chronos = super.haskell.lib.doJailbreak hsuper.chronos; 48 | }); 49 | }; 50 | lattice-symmetries = (super.lattice-symmetries or { }) // { 51 | haskell = haskell.packages.ghc96.lattice-symmetries-haskell; 52 | }; 53 | } 54 | -------------------------------------------------------------------------------- /haskell/test/LatticeSymmetries/BenesSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedLists #-} 2 | 3 | module LatticeSymmetries.BenesSpec (spec) where 4 | 5 | import qualified Data.Aeson as Aeson 6 | import Data.Bits 7 | import Data.Vector (Vector) 8 | import qualified Data.Vector.Generic as G 9 | import LatticeSymmetries.Benes 10 | import Test.Hspec 11 | import Test.Hspec.QuickCheck 12 | import Test.QuickCheck 13 | 14 | data PermutationTestData = PermutationTestData !Permutation !(Vector Integer) 15 | deriving stock (Show) 16 | 17 | instance Arbitrary PermutationTestData where 18 | arbitrary = sized $ \size -> do 19 | n <- chooseInt (1, 500) 20 | p <- mkPermutation . G.fromList <$> shuffle [0 .. n - 1] 21 | v <- G.replicateM size (chooseInteger (0, bit n - 1)) 22 | pure $ PermutationTestData p v 23 | 24 | checkPermuteBits :: PermutationTestData -> Expectation 25 | checkPermuteBits (PermutationTestData p v) = do 26 | let !network = toBenesNetwork p 27 | G.forM_ v $ \x -> 28 | permuteBits network x `shouldBe` permuteBits' p x 29 | 30 | spec :: Spec 31 | spec = do 32 | describe "permuteBits" $ do 33 | it "should permute bits" $ do 34 | let p₁ = toBenesNetwork (mkPermutation [0, 1, 2]) 35 | permuteBits p₁ 0b100 `shouldBe` 0b100 36 | let p₂ = toBenesNetwork (mkPermutation [1, 2, 0]) 37 | permuteBits p₂ 0b100 `shouldBe` 0b010 38 | permuteBits p₂ 0b101 `shouldBe` 0b110 39 | let v₃ = mkPermutation [1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8] 40 | p₃ = toBenesNetwork v₃ 41 | permuteBits p₃ 0b100111010010 `shouldBe` 0b110011100001 42 | permuteBits p₃ 0b100111010010 `shouldBe` permuteBits' v₃ 0b100111010010 43 | modifyMaxSize (const 100) $ prop "correctly permutes bits" $ checkPermuteBits 44 | describe "ToJSON Permutation" $ do 45 | it "encodes Permutation" $ do 46 | Aeson.encode (mkPermutation [0, 1, 2, 3]) `shouldBe` "[0,1,2,3]" 47 | Aeson.encode (mkPermutation [3, 5, 0, 1, 2, 4]) `shouldBe` "[3,5,0,1,2,4]" 48 | describe "FromJSON Permutation" $ do 49 | it "parses Permutation" $ do 50 | Aeson.decode "[3, 0, 2, 1]" `shouldBe` Just (mkPermutation [3, 0, 2, 1]) 51 | Aeson.decode "[3, 0, 2, 1, 4, 5, 6]" `shouldBe` Just (mkPermutation [3, 0, 2, 1, 4, 5, 6]) 52 | Aeson.decode "{ \"oops\": [2, 1, 0] }" `shouldBe` (Nothing :: Maybe Permutation) 53 | -------------------------------------------------------------------------------- /haskell/src/LatticeSymmetries/Context.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | 3 | module LatticeSymmetries.Context 4 | ( importLS 5 | ) 6 | where 7 | 8 | import Data.Map.Strict qualified as Map 9 | import Language.C.Inline qualified as C 10 | import Language.C.Inline.Context (Context (..)) 11 | import Language.C.Types (CIdentifier, TypeSpecifier (..)) 12 | import Language.Haskell.TH (DecsQ, Q, TypeQ, lookupTypeName) 13 | import Language.Haskell.TH qualified as TH 14 | import Prelude hiding (optional) 15 | 16 | importLS :: DecsQ 17 | importLS = 18 | concat 19 | <$> sequence 20 | [ C.context =<< lsCxt 21 | , C.include "" 22 | , C.include "" 23 | ] 24 | 25 | lsCxt :: Q C.Context 26 | lsCxt = do 27 | typePairs <- Map.fromList <$> lsTypePairs 28 | pure $ C.fptrCtx <> C.bsCtx <> C.baseCtx <> mempty {ctxTypesTable = typePairs} 29 | 30 | lsTypePairs :: Q [(TypeSpecifier, TypeQ)] 31 | lsTypePairs = 32 | optionals 33 | [ ("ls_hs_nonbranching_terms", "Cnonbranching_terms") 34 | , ("ls_hs_basis", "Cbasis") 35 | , ("ls_hs_operator", "Coperator") 36 | , ("Halide::Internal::Dimension", "CxxDimension") 37 | , ("Halide::Internal::FusedPair", "FusedPair") 38 | , ("Halide::Internal::PrefetchDirective", "PrefetchDirective") 39 | , ("Halide::Internal::ReductionVariable", "ReductionVariable") 40 | , ("Halide::Internal::Split", "Split") 41 | , ("Halide::Internal::StageSchedule", "CxxStageSchedule") 42 | , ("Halide::Argument", "CxxArgument") 43 | , ("Halide::Buffer", "CxxBuffer") 44 | , ("Halide::LoopLevel", "CxxLoopLevel") 45 | , ("Halide::Stage", "CxxStage") 46 | , ("Halide::Range", "CxxRange") 47 | , ("Halide::RDom", "CxxRDom") 48 | , ("halide_buffer_t", "Language.Halide.Buffer.RawHalideBuffer") 49 | , ("halide_device_interface_t", "HalideDeviceInterface") 50 | , ("halide_dimension_t", "HalideDimension") 51 | , ("halide_trace_event_t", "TraceEvent") 52 | ] 53 | where 54 | optional :: (CIdentifier, String) -> Q [(TypeSpecifier, TypeQ)] 55 | optional (cName, hsName) = do 56 | hsType <- lookupTypeName hsName 57 | pure $ maybe [] (\x -> [(TypeName cName, pure (TH.ConT x))]) hsType 58 | optionals :: [(CIdentifier, String)] -> Q [(TypeSpecifier, TypeQ)] 59 | optionals pairs = concat <$> mapM optional pairs 60 | -------------------------------------------------------------------------------- /haskell/src/LatticeSymmetries/BitString.hs: -------------------------------------------------------------------------------- 1 | -- | 2 | -- Module : LatticeSymmetries.BitString 3 | -- Description : Defines the 'BitString' data type 4 | -- Copyright : (c) Tom Westerhout, 2022 5 | -- Stability : experimental 6 | module LatticeSymmetries.BitString 7 | ( BitString (..), 8 | readBitString, 9 | writeBitString, 10 | writeManyBitStrings, 11 | wordsFromBitString, 12 | ) 13 | where 14 | 15 | import Control.Monad.Primitive 16 | import Control.Monad.ST 17 | import Data.Bits 18 | import qualified Data.Primitive.Ptr as P 19 | import Data.Vector.Generic (Vector) 20 | import qualified Data.Vector.Generic as G 21 | import qualified Data.Vector.Generic.Mutable as GM 22 | import Foreign.Ptr 23 | 24 | -- | A newtype over 'Integer' indicating that we don't treat it as a number, but rather as a 25 | -- collection of bits. 26 | -- 27 | -- The order of bits is determined by the 'Bits' instance of 'Integer'. 28 | newtype BitString = BitString {unBitString :: Integer} 29 | deriving stock (Show, Eq, Ord) 30 | deriving newtype (Bits) 31 | 32 | writeBitString :: PrimMonad m => Int -> Ptr Word64 -> BitString -> m () 33 | writeBitString numberWords p (BitString x₀) = do 34 | let go !i !x 35 | | i < numberWords = do 36 | P.writeOffPtr p i (fromIntegral x :: Word64) 37 | go (i + 1) (x `shiftR` 64) 38 | | otherwise = pure () 39 | go 0 x₀ 40 | 41 | writeManyBitStrings :: PrimMonad m => Int -> Ptr Word64 -> [BitString] -> m () 42 | writeManyBitStrings numberWords p xs = go p xs 43 | where 44 | go !ptr (y : ys) = writeBitString numberWords ptr y >> go (P.advancePtr ptr numberWords) ys 45 | go _ [] = pure () 46 | 47 | readBitString :: PrimMonad m => Int -> Ptr Word64 -> m BitString 48 | readBitString numberWords p = do 49 | let go !i !x 50 | | i < numberWords = do 51 | y <- BitString <$> (fromIntegral :: Word64 -> Integer) <$> P.readOffPtr p i 52 | go (i + 1) ((y `shiftL` (64 * i)) .|. x) 53 | | otherwise = pure x 54 | go 0 zeroBits 55 | 56 | wordsFromBitString :: Vector v Word64 => Int -> BitString -> v Word64 57 | wordsFromBitString numberWords (BitString x₀) = runST $ do 58 | mvector <- GM.unsafeNew numberWords 59 | let go !i !x 60 | | i < numberWords = do 61 | GM.unsafeWrite mvector i (fromIntegral x :: Word64) 62 | go (i + 1) (x `shiftR` 64) 63 | | otherwise = pure () 64 | go 0 x₀ 65 | G.unsafeFreeze mvector 66 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1689068808, 9 | "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "nix-chapel": { 22 | "inputs": { 23 | "flake-utils": [ 24 | "flake-utils" 25 | ], 26 | "nixpkgs": [ 27 | "nixpkgs" 28 | ] 29 | }, 30 | "locked": { 31 | "lastModified": 1689321935, 32 | "narHash": "sha256-r5MQDWX6ZYj4eCTeGHVoMHkAZuY8qh+HJJTZs/M8/Fw=", 33 | "owner": "twesterhout", 34 | "repo": "nix-chapel", 35 | "rev": "e03eae25122c0980c1dffe19f0906996ff082af9", 36 | "type": "github" 37 | }, 38 | "original": { 39 | "owner": "twesterhout", 40 | "repo": "nix-chapel", 41 | "type": "github" 42 | } 43 | }, 44 | "nixpkgs": { 45 | "locked": { 46 | "lastModified": 1689192006, 47 | "narHash": "sha256-QM0f0d8oPphOTYJebsHioR9+FzJcy1QNIzREyubB91U=", 48 | "owner": "nixos", 49 | "repo": "nixpkgs", 50 | "rev": "2de8efefb6ce7f5e4e75bdf57376a96555986841", 51 | "type": "github" 52 | }, 53 | "original": { 54 | "owner": "nixos", 55 | "ref": "nixos-unstable", 56 | "repo": "nixpkgs", 57 | "type": "github" 58 | } 59 | }, 60 | "root": { 61 | "inputs": { 62 | "flake-utils": "flake-utils", 63 | "nix-chapel": "nix-chapel", 64 | "nixpkgs": "nixpkgs" 65 | } 66 | }, 67 | "systems": { 68 | "locked": { 69 | "lastModified": 1681028828, 70 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 71 | "owner": "nix-systems", 72 | "repo": "default", 73 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 74 | "type": "github" 75 | }, 76 | "original": { 77 | "owner": "nix-systems", 78 | "repo": "default", 79 | "type": "github" 80 | } 81 | } 82 | }, 83 | "root": "root", 84 | "version": 7 85 | } 86 | -------------------------------------------------------------------------------- /chapel/overlay.nix: -------------------------------------------------------------------------------- 1 | { version 2 | }: 3 | 4 | final: prev: { 5 | atomic_queue = final.callPackage ./atomic_queue.nix { }; 6 | lattice-symmetries = (prev.lattice-symmetries or { }) // { 7 | ffi = final.callPackage ./ffi.nix { inherit version; }; 8 | chapel = final.callPackage ./. { inherit version; }; 9 | distributed = 10 | let 11 | chapelBuild = target: makeFlags: final.stdenv.mkDerivation { 12 | pname = target; 13 | inherit version; 14 | src = ./.; 15 | configurePhase = "ln --symbolic ${final.lattice-symmetries.ffi} src/FFI.chpl"; 16 | buildPhase = '' 17 | make \ 18 | ${final.lib.concatStringsSep " " makeFlags} \ 19 | CHPL_HOST_MEM=jemalloc CHPL_TARGET_MEM=jemalloc \ 20 | CHPL_LAUNCHER=none \ 21 | OPTIMIZATION=--fast \ 22 | CHPL_CFLAGS='-I${final.lattice-symmetries.kernels}/include' \ 23 | CHPL_LDFLAGS='-L${final.lattice-symmetries.haskell.lib}/lib' \ 24 | HDF5_CFLAGS='-I${final.hdf5.dev}/include' \ 25 | HDF5_LDFLAGS='-L${final.hdf5}/lib -lhdf5_hl -lhdf5 -lrt' \ 26 | bin/${target} 27 | 28 | for f in $(ls bin); do 29 | chapelFixupBinary bin/$f 30 | done 31 | ''; 32 | installPhase = '' 33 | mkdir -p $out/bin 34 | install -Dm 755 bin/* $out/bin 35 | ''; 36 | nativeBuildInputs = with final; [ chapel chapelFixupBinary ]; 37 | }; 38 | 39 | toContainer = drv: final.singularity-tools.buildImage { 40 | name = drv.pname; 41 | contents = [ drv ]; 42 | diskSize = 10240; 43 | memSize = 5120; 44 | }; 45 | 46 | buildContainers = makeFlags: 47 | builtins.foldl' 48 | (acc: s: acc // { "${s}" = toContainer (chapelBuild s makeFlags); }) 49 | { } 50 | [ 51 | "TestMatrixVectorProduct" 52 | "BenchmarkStatesEnumeration" 53 | "BenchmarkMatrixVectorProduct" 54 | "BenchmarkBlockHashed" 55 | ]; 56 | in 57 | { 58 | smp = buildContainers [ 59 | "CHPL_COMM=gasnet" 60 | "CHPL_COMM_SUBSTRATE=smp" 61 | ]; 62 | ibv = buildContainers [ 63 | "CHPL_COMM=gasnet" 64 | "CHPL_COMM_SUBSTRATE=ibv" 65 | "CHPL_GASNET_SEGMENT=fast" 66 | ]; 67 | }; 68 | }; 69 | } 70 | -------------------------------------------------------------------------------- /template/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "A project using lattice-symmetries"; 3 | 4 | # We specify additional cache locations to avoid a very lengthly compilation of 5 | # dependencies. Since Nix ensures reproducibility, it is safe to fetch pre-built 6 | # packages from cache. 7 | nixConfig = { 8 | extra-substituters = "https://twesterhout-chapel.cachix.org"; 9 | extra-trusted-public-keys = "twesterhout-chapel.cachix.org-1:bs5PQPqy21+rP2KJl+O40/eFVzdsTe6m7ZTiOEE7PaI="; 10 | }; 11 | 12 | inputs = { 13 | # We follow nixpkgs and flake-utils from lattice-symmetries to have a higher 14 | # probability of dependencies being cached. 15 | nixpkgs.follows = "lattice-symmetries/nixpkgs"; 16 | flake-utils.follows = "lattice-symmetries/flake-utils"; 17 | lattice-symmetries.url = "github:twesterhout/lattice-symmetries"; 18 | flake-compat = { 19 | url = "github:edolstra/flake-compat"; 20 | flake = false; 21 | }; 22 | }; 23 | 24 | outputs = inputs: 25 | let 26 | pkgs-for = system: import inputs.nixpkgs { 27 | inherit system; 28 | overlays = [ inputs.lattice-symmetries.overlays.default ]; 29 | }; 30 | 31 | # Our Python dependencies 32 | my-python-packages = ps: with ps; [ 33 | # jupyter 34 | lattice-symmetries 35 | ipykernel 36 | loguru 37 | matplotlib 38 | numpy 39 | pandas 40 | scipy 41 | seaborn 42 | ]; 43 | in 44 | { 45 | packages = inputs.flake-utils.lib.eachDefaultSystemMap (system: 46 | with (pkgs-for system); { 47 | default = singularity-tools.buildImage { 48 | name = "my-project"; 49 | contents = [ 50 | (python3.withPackages my-python-packages) 51 | coreutils 52 | ]; 53 | diskSize = 10240; 54 | memSize = 5120; 55 | }; 56 | }); 57 | 58 | devShells = inputs.flake-utils.lib.eachDefaultSystemMap (system: 59 | with (pkgs-for system); { 60 | default = mkShell { 61 | nativeBuildInputs = [ 62 | (python3.withPackages my-python-packages) 63 | # LSP support for Python 64 | python3Packages.black 65 | nodePackages.pyright 66 | ]; 67 | shellHook = '' 68 | export PROMPT_COMMAND="" 69 | export PS1='🐍 Python ${python3.version} \w $ ' 70 | export LS_PATH=${lattice-symmetries.python} 71 | ''; 72 | }; 73 | }); 74 | }; 75 | } 76 | -------------------------------------------------------------------------------- /haskell/src/LatticeSymmetries/NonbranchingTerm.hs: -------------------------------------------------------------------------------- 1 | -- | 2 | -- Module : LatticeSymmetries.NonbranchingTerm 3 | -- Description : Non-branching terms in the Hamiltonian 4 | -- Copyright : (c) Tom Westerhout, 2022 5 | -- Stability : experimental 6 | module LatticeSymmetries.NonbranchingTerm 7 | ( NonbranchingTerm (..) 8 | , HasNonbranchingRepresentation (..) 9 | , nbtIsDiagonal 10 | ) 11 | where 12 | 13 | import Data.Bits 14 | import LatticeSymmetries.BitString 15 | import LatticeSymmetries.ComplexRational 16 | 17 | -- | Non-branching term of the Hamiltonian. 18 | -- 19 | -- Suppose that \(T\) is such a term. The "non-branching" part means that when we apply \(T\) to a 20 | -- basis state \(|\alpha\rangle\), we get just one other basis state back, i.e. 21 | -- \( T|\alpha\rangle = c|\beta\rangle \). 22 | -- 23 | -- We use the representation from . See Appendix A in the paper. 24 | data NonbranchingTerm = NonbranchingTerm 25 | -- (v, m, l, r, x, s) 26 | { nbtV :: !ComplexRational 27 | , nbtM :: !BitString 28 | , nbtL :: !BitString 29 | , nbtR :: !BitString 30 | , nbtX :: !BitString 31 | , nbtS :: !BitString 32 | } 33 | deriving stock (Show, Eq) 34 | 35 | -- | Implements a .&. complement b without using complement function 36 | andWithComplement :: BitString -> BitString -> BitString 37 | andWithComplement a b = a .&. (b `xor` fakeOnes) 38 | where 39 | fakeOnes = go (BitString 0xFFFFFFFFFFFFFFFF) 64 40 | go !n !i = if n >= a then n else go ((n `shiftL` i) .|. n) (2 * i) 41 | 42 | -- | Composition of operators. 43 | instance Semigroup NonbranchingTerm where 44 | (<>) (NonbranchingTerm vₐ mₐ lₐ rₐ _ sₐ) (NonbranchingTerm vᵦ mᵦ lᵦ rᵦ xᵦ sᵦ) = NonbranchingTerm v m l r x s 45 | where 46 | v = if (rₐ `xor` lᵦ) .&. mₐ .&. mᵦ /= zeroBits then 0 else ((-1) ^ p) * vₐ * vᵦ 47 | m = mₐ .|. mᵦ 48 | -- What we want is 49 | -- r = rᵦ .|. (rₐ .&. complement mᵦ) 50 | -- l = lₐ .|. (lᵦ .&. complement mₐ) 51 | -- however, complement does not work for Integer, because that would create an infinitely long 52 | -- bitstring 53 | r = rᵦ .|. andWithComplement rₐ mᵦ 54 | l = lₐ .|. andWithComplement lᵦ mₐ 55 | x = l `xor` r 56 | s = (sₐ `xor` sᵦ) .&. complement m 57 | z = (r .&. sᵦ) `xor` xᵦ 58 | p = popCount $ (r .&. sᵦ) `xor` (z .&. sₐ) 59 | 60 | -- | Specifies that an operator is non-branching and can be cast into 'NonbranchingTerm'. 61 | -- 62 | -- Our low-level C kernels deal with non-branching terms for efficiency, but in the Haskell land we 63 | -- want to deal with mathematical expressions (i.e. polynomials of creation/annihilation operators). 64 | -- This typeclass connects the two worlds. 65 | -- 66 | -- @g@ will typically be 'LatticeSymmetries.Generator.SpinGeneratorType', 'LatticeSymmetries.Generator.FermionGeneratorType' or 'LatticeSymmetries.Generator.Generator'. 67 | class HasNonbranchingRepresentation g where 68 | nonbranchingRepresentation :: g -> NonbranchingTerm 69 | 70 | -- | Checks whether an operator is diagonal. 71 | nbtIsDiagonal :: NonbranchingTerm -> Bool 72 | nbtIsDiagonal t = nbtX t == zeroBits 73 | -------------------------------------------------------------------------------- /.github/workflows/conda.yml: -------------------------------------------------------------------------------- 1 | name: Conda 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | env: 10 | BUILD_TYPE: Debug 11 | INSTALL_LOCATION: .local 12 | 13 | jobs: 14 | # build: 15 | # name: Build within Conda on ${{ matrix.os }} 16 | # runs-on: ${{ matrix.os }} 17 | # strategy: 18 | # matrix: 19 | # os: [ubuntu-latest, macos-latest] 20 | 21 | # steps: 22 | # - uses: actions/checkout@v2 23 | # with: 24 | # submodules: true 25 | # - uses: conda-incubator/setup-miniconda@v2 26 | # if: matrix.os == 'ubuntu-latest' 27 | # with: 28 | # activate-environment: lattice_symmetries_devel 29 | # environment-file: conda-devel-linux.yml 30 | # auto-activate-base: false 31 | # - uses: conda-incubator/setup-miniconda@v2 32 | # if: matrix.os == 'macos-latest' 33 | # with: 34 | # activate-environment: lattice_symmetries_devel 35 | # environment-file: conda-devel-osx.yml 36 | # auto-activate-base: false 37 | # 38 | # - name: Info 39 | # run: | 40 | # conda info 41 | # conda env list 42 | 43 | # - name: Build 44 | # run: | 45 | # if [[ -d /usr/local/miniconda/etc ]]; then 46 | # source /usr/local/miniconda/etc/profile.d/conda.sh 47 | # else 48 | # source /usr/share/miniconda/etc/profile.d/conda.sh 49 | # fi 50 | # conda activate lattice_symmetries_devel 51 | # cmake -GNinja \ 52 | # -Bbuild \ 53 | # -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ 54 | # -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/$INSTALL_LOCATION 55 | # cmake --build build 56 | # 57 | # - name: Run tests 58 | # run: | 59 | # cd build 60 | # ctest -VV 61 | 62 | # - name: Install 63 | # run: cmake --build build --target install 64 | 65 | conda_package: 66 | name: Build Conda package on ${{ matrix.os }} 67 | runs-on: ${{ matrix.os }} 68 | strategy: 69 | matrix: 70 | os: [ubuntu-latest, macos-latest] 71 | 72 | steps: 73 | - uses: actions/checkout@v2 74 | with: 75 | submodules: true 76 | - uses: conda-incubator/setup-miniconda@v2 77 | with: 78 | auto-activate-base: true 79 | 80 | - name: Info 81 | run: | 82 | conda info 83 | conda env list 84 | conda install anaconda-client conda-build conda-verify 85 | 86 | - name: Build 87 | run: | 88 | if [[ $(uname) != "Linux" ]]; then 89 | wget --no-verbose https://github.com/phracker/MacOSX-SDKs/releases/download/11.3/MacOSX11.3.sdk.tar.xz 90 | sudo tar xf MacOSX11.3.sdk.tar.xz -C /opt 91 | echo "" >> conda/conda_build_config.yaml 92 | echo "CONDA_BUILD_SYSROOT:" >> conda/conda_build_config.yaml 93 | echo " - /opt/MacOSX11.3.sdk # [osx]" >> conda/conda_build_config.yaml 94 | fi 95 | mkdir conda_output 96 | conda build -c conda-forge conda --output-folder=$PWD/conda_output 97 | 98 | - uses: actions/upload-artifact@v3 99 | with: 100 | path: conda_output/* 101 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: LLVM 4 | 5 | AccessModifierOffset: -2 6 | AlignAfterOpenBracket: Align 7 | AlignConsecutiveAssignments: true 8 | AlignConsecutiveDeclarations: true 9 | AlignEscapedNewlinesLeft: false 10 | AlignOperands: true 11 | AlignTrailingComments: true 12 | AllowAllParametersOfDeclarationOnNextLine: true 13 | AllowShortBlocksOnASingleLine: true 14 | AllowShortCaseLabelsOnASingleLine: true 15 | AllowShortFunctionsOnASingleLine: All 16 | AllowShortIfStatementsOnASingleLine: true 17 | AllowShortLoopsOnASingleLine: false 18 | AlwaysBreakAfterReturnType: None 19 | AlwaysBreakBeforeMultilineStrings: false 20 | AlwaysBreakTemplateDeclarations: MultiLine 21 | BinPackArguments: true 22 | BinPackParameters: true 23 | BraceWrapping: 24 | AfterClass: false 25 | AfterControlStatement: false 26 | AfterEnum: false 27 | AfterFunction: true 28 | AfterNamespace: false 29 | AfterStruct: false 30 | AfterUnion: false 31 | AfterExternBlock: false 32 | BeforeCatch: true 33 | BeforeElse: true 34 | IndentBraces: false 35 | SplitEmptyFunction: false 36 | SplitEmptyRecord: false 37 | SplitEmptyNamespace: true 38 | BreakBeforeBinaryOperators: NonAssignment 39 | BreakBeforeBraces: Custom 40 | BreakBeforeInheritanceComma: true 41 | BreakBeforeTernaryOperators: true 42 | BreakConstructorInitializers: BeforeComma 43 | BreakStringLiterals: true 44 | ColumnLimit: 100 45 | CommentPragmas: '^ IWYU pragma:' 46 | CompactNamespaces: false 47 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 48 | ConstructorInitializerIndentWidth: 4 49 | ContinuationIndentWidth: 4 50 | Cpp11BracedListStyle: true 51 | DerivePointerAlignment: false 52 | DisableFormat: false 53 | ExperimentalAutoDetectBinPacking: false 54 | FixNamespaceComments: true 55 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] 56 | IncludeCategories: 57 | - Regex: '^"detail/' 58 | Priority: 1 59 | - Regex: '^<(boost|gsl|spdlog|tl)' 60 | Priority: 4 61 | - Regex: '^<.*\.h>$' 62 | Priority: 5 63 | - Regex: '^<' 64 | Priority: 6 65 | - Regex: '.*' 66 | Priority: 2 67 | IncludeIsMainRegex: '$' 68 | IndentCaseLabels: false 69 | IndentPPDirectives: AfterHash 70 | IndentWidth: 4 71 | IndentWrappedFunctionNames: false 72 | KeepEmptyLinesAtTheStartOfBlocks: true 73 | MacroBlockBegin: '' 74 | MacroBlockEnd: '' 75 | MaxEmptyLinesToKeep: 1 76 | NamespaceIndentation: Inner 77 | PenaltyBreakAssignment: 0 78 | PenaltyBreakBeforeFirstCallParameter: 20 79 | PenaltyBreakComment: 300 80 | PenaltyBreakFirstLessLess: 120 81 | PenaltyBreakString: 400 82 | PenaltyExcessCharacter: 12345 83 | PenaltyReturnTypeOnItsOwnLine: 60 84 | PointerAlignment: Left 85 | ReflowComments: false 86 | SortIncludes: true 87 | SortUsingDeclarations: true 88 | SpaceAfterCStyleCast: false 89 | SpaceAfterTemplateKeyword: true 90 | SpaceBeforeAssignmentOperators: true 91 | SpaceBeforeParens: ControlStatements 92 | SpaceInEmptyParentheses: false 93 | SpacesBeforeTrailingComments: 1 94 | SpacesInAngles: false 95 | SpacesInCStyleCastParentheses: false 96 | SpacesInParentheses: false 97 | SpacesInSquareBrackets: false 98 | Standard: Cpp11 99 | TabWidth: 4 100 | UseTab: Never 101 | ... 102 | -------------------------------------------------------------------------------- /chapel/data/heisenberg_square_6x6.yaml: -------------------------------------------------------------------------------- 1 | basis: 2 | number_spins: 36 3 | hamming_weight: 18 4 | spin_inversion: 1 5 | symmetries: 6 | # Initial layout: 7 | # [ 0, 1, 2, 3, 4, 5, 8 | # 6, 7, 8, 9, 10, 11, 9 | # 12, 13, 14, 15, 16, 17, 10 | # 18, 19, 20, 21, 22, 23, 11 | # 24, 25, 26, 27, 28, 29, 12 | # 30, 31, 32, 33, 34, 35] 13 | # 14 | # Translation along x-axis 15 | - permutation: [ 1, 2, 3, 4, 5, 0, 16 | 7, 8, 9, 10, 11, 6, 17 | 13, 14, 15, 16, 17, 12, 18 | 19, 20, 21, 22, 23, 18, 19 | 25, 26, 27, 28, 29, 24, 20 | 31, 32, 33, 34, 35, 30] 21 | sector: 0 22 | # Translation along y-axis 23 | - permutation: [ 6, 7, 8, 9, 10, 11, 24 | 12, 13, 14, 15, 16, 17, 25 | 18, 19, 20, 21, 22, 23, 26 | 24, 25, 26, 27, 28, 29, 27 | 30, 31, 32, 33, 34, 35, 28 | 0, 1, 2, 3, 4, 5] 29 | sector: 0 30 | # Reflection along x-axis (i.e. around y-axis) 31 | - permutation: [ 5, 4, 3, 2, 1, 0, 32 | 11, 10, 9, 8, 7, 6, 33 | 17, 16, 15, 14, 13, 12, 34 | 23, 22, 21, 20, 19, 18, 35 | 29, 28, 27, 26, 25, 24, 36 | 35, 34, 33, 32, 31, 30] 37 | sector: 0 38 | # Reflection along y-axis (i.e. around x-axis) 39 | - permutation: [30, 31, 32, 33, 34, 35, 40 | 24, 25, 26, 27, 28, 29, 41 | 18, 19, 20, 21, 22, 23, 42 | 12, 13, 14, 15, 16, 17, 43 | 6, 7, 8, 9, 10, 11, 44 | 0, 1, 2, 3, 4, 5] 45 | sector: 0 46 | # Rotation 47 | - permutation: [ 5, 11, 17, 23, 29, 35, 48 | 4, 10, 16, 22, 28, 34, 49 | 3, 9, 15, 21, 27, 33, 50 | 2, 8, 14, 20, 26, 32, 51 | 1, 7, 13, 19, 25, 31, 52 | 0, 6, 12, 18, 24, 30] 53 | sector: 0 54 | hamiltonian: 55 | name: "Heisenberg Hamiltonian" 56 | terms: 57 | - expression: "σˣ₀ σˣ₁" 58 | sites: &lattice [ 59 | [0, 1], [0, 6], [1, 2], [1, 7], [2, 3], [2, 8], [3, 4], [3, 9], 60 | [4, 5], [4, 10], [5, 0], [5, 11], [6, 7], [6, 12], [7, 8], [7, 13], 61 | [8, 9], [8, 14], [9, 10], [9, 15], [10, 11], [10, 16], [11, 6], [11, 17], 62 | [12, 13], [12, 18], [13, 14], [13, 19], [14, 15], [14, 20], [15, 16], [15, 21], 63 | [16, 17], [16, 22], [17, 12], [17, 23], [18, 19], [18, 24], [19, 20], [19, 25], 64 | [20, 21], [20, 26], [21, 22], [21, 27], [22, 23], [22, 28], [23, 18], [23, 29], 65 | [24, 25], [24, 30], [25, 26], [25, 31], [26, 27], [26, 32], [27, 28], [27, 33], 66 | [28, 29], [28, 34], [29, 24], [29, 35], [30, 31], [30, 0], [31, 32], [31, 1], 67 | [32, 33], [32, 2], [33, 34], [33, 3], [34, 35], [34, 4], [35, 30], [35, 5]] 68 | - expression: "σʸ₀ σʸ₁" 69 | sites: *lattice 70 | - expression: "σᶻ₀ σᶻ₁" 71 | sites: *lattice 72 | observables: [] 73 | number_vectors: 2 74 | output: "data/heisenberg_square_6x6.h5" 75 | datatype: "float32" 76 | max_primme_block_size: 4 77 | max_primme_basis_size: 20 78 | -------------------------------------------------------------------------------- /haskell/src/LatticeSymmetries/ComplexRational.hs: -------------------------------------------------------------------------------- 1 | -- | 2 | -- Module : LatticeSymmetries.ComplexRational 3 | -- Description : Arbitrary-precision complex numbers 4 | -- Copyright : (c) Tom Westerhout, 2022 5 | -- Stability : experimental 6 | module LatticeSymmetries.ComplexRational 7 | ( ComplexRational (..) 8 | , ℂ 9 | , ConvertibleToComplexDouble (..) 10 | , realPart 11 | , imagPart 12 | , conjugate 13 | , magnitudeSquared 14 | , Cscalar 15 | ) 16 | where 17 | 18 | import Data.Complex (Complex (..)) 19 | import Foreign.C.Types (CDouble (..)) 20 | import Prettyprinter (Doc, Pretty (..)) 21 | import Prettyprinter qualified as Pretty 22 | 23 | -- | Arbitrary precision complex number \(\mathbb{C}\) built from two 'Rational's. 24 | data ComplexRational = ComplexRational {-# UNPACK #-} !Rational {-# UNPACK #-} !Rational 25 | deriving stock (Eq, Show) 26 | 27 | type ℂ = ComplexRational 28 | 29 | prettyRational :: Rational -> Doc ann 30 | prettyRational x 31 | | realToFrac (fromRational x :: Double) == x = pretty (fromRational x :: Double) 32 | | otherwise = Pretty.parens $ pretty (numerator x) <> "/" <> pretty (denominator x) 33 | 34 | instance Pretty ComplexRational where 35 | pretty (ComplexRational r i) 36 | | i == 0 = prettyRational r 37 | | r == 0 && i == 1 = "ⅈ" 38 | | r == 0 && i == -1 = "-ⅈ" 39 | | r == 0 = prettyRational i <> "ⅈ" 40 | | otherwise = Pretty.parens $ prettyRational r <> " + " <> prettyRational i <> "ⅈ" 41 | 42 | realPart :: ComplexRational -> Rational 43 | realPart (ComplexRational r _) = r 44 | {-# INLINE realPart #-} 45 | 46 | imagPart :: ComplexRational -> Rational 47 | imagPart (ComplexRational _ i) = i 48 | {-# INLINE imagPart #-} 49 | 50 | conjugate :: ComplexRational -> ComplexRational 51 | conjugate (ComplexRational r i) = ComplexRational r (-i) 52 | {-# INLINE conjugate #-} 53 | 54 | magnitudeSquared :: ComplexRational -> Rational 55 | magnitudeSquared (ComplexRational r i) = r * r + i * i 56 | {-# INLINE magnitudeSquared #-} 57 | 58 | instance Num ComplexRational where 59 | {-# INLINE (+) #-} 60 | {-# INLINE (-) #-} 61 | {-# INLINE (*) #-} 62 | {-# INLINE fromInteger #-} 63 | (ComplexRational r i) + (ComplexRational r' i') = ComplexRational (r + r') (i + i') 64 | (ComplexRational r i) - (ComplexRational r' i') = ComplexRational (r - r') (i - i') 65 | (ComplexRational r i) * (ComplexRational r' i') = ComplexRational (r * r' - i * i') (r * i' + i * r') 66 | negate (ComplexRational r i) = ComplexRational (-r) (-i) 67 | abs _ = error "Num instance of ComplexRational does not implement abs" 68 | signum _ = error "Num instance of ComplexRational does not implement signum" 69 | fromInteger n = ComplexRational (fromInteger n) 0 70 | 71 | instance Fractional ComplexRational where 72 | {-# INLINE (/) #-} 73 | {-# INLINE fromRational #-} 74 | (ComplexRational r i) / z'@(ComplexRational r' i') = 75 | ComplexRational ((r * r' + i * i') / d) ((-r * i' + i * r') / d) 76 | where 77 | d = magnitudeSquared z' 78 | fromRational a = ComplexRational a 0 79 | 80 | type Cscalar = Complex CDouble 81 | 82 | class Fractional a => ConvertibleToComplexDouble a where 83 | toComplexDouble :: a -> Cscalar 84 | fromComplexDouble :: Cscalar -> a 85 | 86 | instance ConvertibleToComplexDouble ComplexRational where 87 | toComplexDouble (ComplexRational r i) = (fromRational r) :+ (fromRational i) 88 | fromComplexDouble (r :+ i) = ComplexRational (toRational r) (toRational i) 89 | 90 | instance ConvertibleToComplexDouble (Complex CDouble) where 91 | toComplexDouble = id 92 | fromComplexDouble = id 93 | 94 | instance ConvertibleToComplexDouble (Complex Double) where 95 | toComplexDouble = coerce 96 | fromComplexDouble = coerce 97 | -------------------------------------------------------------------------------- /haskell/src/LatticeSymmetries/Utils.hs: -------------------------------------------------------------------------------- 1 | -- | 2 | -- Module : LatticeSymmetries.Utils 3 | -- Description : Random utilities 4 | -- Copyright : (c) Tom Westerhout, 2022 5 | -- Stability : experimental 6 | module LatticeSymmetries.Utils 7 | ( -- ** Looping constructs 8 | loopM 9 | , iFoldM 10 | 11 | -- ** Error handling 12 | , throwC 13 | , propagateErrorToC 14 | 15 | -- ** String handling 16 | , peekUtf8 17 | , newCString 18 | , decodeCString 19 | , toPrettyText 20 | 21 | -- ** Testing utilities 22 | , ApproxEq (..) 23 | ) 24 | where 25 | 26 | import Control.Exception.Safe (handleAnyDeep) 27 | import Data.Aeson 28 | import Data.ByteString (packCString, useAsCString) 29 | import Data.ByteString.Internal (ByteString (..)) 30 | import Data.Complex 31 | import Foreign.C.String (CString) 32 | import Foreign.C.Types (CChar, CDouble (..)) 33 | import Foreign.ForeignPtr (withForeignPtr) 34 | import Foreign.Marshal.Alloc (mallocBytes) 35 | import Foreign.Marshal.Utils (copyBytes) 36 | import Foreign.Ptr (Ptr, castPtr) 37 | import Foreign.Storable (Storable (..)) 38 | import Prettyprinter (Pretty (..)) 39 | import Prettyprinter qualified as Pretty 40 | import Prettyprinter.Render.Text (renderStrict) 41 | 42 | loopM :: Monad m => i -> (i -> Bool) -> (i -> i) -> (i -> m ()) -> m () 43 | loopM i₀ cond inc action = go i₀ 44 | where 45 | go !i 46 | | cond i = do () <- action i; go (inc i) 47 | | otherwise = pure () 48 | {-# INLINE loopM #-} 49 | 50 | iFoldM :: Monad m => i -> (i -> Bool) -> (i -> i) -> a -> (a -> i -> m a) -> m a 51 | iFoldM i₀ cond inc x₀ action = go x₀ i₀ 52 | where 53 | go !x !i 54 | | cond i = do !x' <- action x i; go x' (inc i) 55 | | otherwise = pure x 56 | {-# INLINE iFoldM #-} 57 | 58 | foreign import ccall unsafe "ls_hs_error" 59 | ls_hs_error :: CString -> IO () 60 | 61 | -- | Invoke the 'ls_hs_error' error handling function with the given message. 62 | throwC :: HasCallStack => a -> Text -> IO a 63 | throwC def msg = do 64 | useAsCString (encodeUtf8 msg) ls_hs_error 65 | pure def 66 | 67 | propagateErrorToC :: (HasCallStack, NFData a) => a -> IO a -> IO a 68 | propagateErrorToC def = handleAnyDeep (throwC def . show) 69 | 70 | infix 4 ≈ 71 | 72 | class ApproxEq a where 73 | (≈) :: a -> a -> Bool 74 | approx :: Double -> Double -> a -> a -> Bool 75 | 76 | instance ApproxEq Double where 77 | approx rtol atol a b = abs (a - b) <= max atol (rtol * max (abs a) (abs b)) 78 | (≈) = approx 1.4901161193847656e-8 8.881784197001252e-16 79 | 80 | instance ApproxEq (Complex Double) where 81 | approx rtol atol (ra :+ ia) (rb :+ ib) = 82 | approx rtol atol ra rb && approx rtol atol ia ib 83 | (≈) = approx 1.4901161193847656e-8 8.881784197001252e-16 84 | 85 | instance ApproxEq (Complex CDouble) where 86 | approx = coerce (approx :: Double -> Double -> Complex Double -> Complex Double -> Bool) 87 | (≈) = coerce ((≈) :: Complex Double -> Complex Double -> Bool) 88 | 89 | peekUtf8 :: CString -> IO Text 90 | peekUtf8 c_str = decodeUtf8 <$> packCString c_str 91 | 92 | newCString :: ByteString -> IO CString 93 | newCString (PS fp _ l) = do 94 | (buf :: Ptr CChar) <- mallocBytes (l + 1) 95 | withForeignPtr fp $ \(p :: Ptr Word8) -> do 96 | copyBytes buf (castPtr p) l 97 | pokeByteOff buf l (0 :: CChar) 98 | pure buf 99 | 100 | -- | Read JSON from a 'CString'. 101 | decodeCString :: (HasCallStack, FromJSON a) => CString -> IO a 102 | decodeCString cStr = do 103 | s <- packCString cStr 104 | case eitherDecode (fromStrict s) of 105 | Right x -> pure x 106 | Left msg -> error (toText msg) 107 | 108 | toPrettyText :: Pretty a => a -> Text 109 | toPrettyText = renderStrict . Pretty.layoutPretty (Pretty.LayoutOptions Pretty.Unbounded) . pretty 110 | -------------------------------------------------------------------------------- /test/04_hubbard_square/HPhi/trans.def: -------------------------------------------------------------------------------- 1 | ======================== 2 | NTransfer 48 3 | ======================== 4 | ========i_j_s_tijs====== 5 | ======================== 6 | 1 0 0 0 1.000000000000000 0.000000000000000 7 | 0 0 1 0 1.000000000000000 -0.000000000000000 8 | 1 1 0 1 1.000000000000000 0.000000000000000 9 | 0 1 1 1 1.000000000000000 -0.000000000000000 10 | 4 0 0 0 2.000000000000000 0.000000000000000 11 | 0 0 4 0 2.000000000000000 0.000000000000000 12 | 4 1 0 1 2.000000000000000 0.000000000000000 13 | 0 1 4 1 2.000000000000000 0.000000000000000 14 | 2 0 1 0 1.000000000000000 0.000000000000000 15 | 1 0 2 0 1.000000000000000 -0.000000000000000 16 | 2 1 1 1 1.000000000000000 0.000000000000000 17 | 1 1 2 1 1.000000000000000 -0.000000000000000 18 | 5 0 1 0 2.000000000000000 0.000000000000000 19 | 1 0 5 0 2.000000000000000 0.000000000000000 20 | 5 1 1 1 2.000000000000000 0.000000000000000 21 | 1 1 5 1 2.000000000000000 0.000000000000000 22 | 3 0 2 0 1.000000000000000 0.000000000000000 23 | 2 0 3 0 1.000000000000000 -0.000000000000000 24 | 3 1 2 1 1.000000000000000 0.000000000000000 25 | 2 1 3 1 1.000000000000000 -0.000000000000000 26 | 6 0 2 0 2.000000000000000 0.000000000000000 27 | 2 0 6 0 2.000000000000000 0.000000000000000 28 | 6 1 2 1 2.000000000000000 0.000000000000000 29 | 2 1 6 1 2.000000000000000 0.000000000000000 30 | 0 0 3 0 1.000000000000000 0.000000000000000 31 | 3 0 0 0 1.000000000000000 -0.000000000000000 32 | 0 1 3 1 1.000000000000000 0.000000000000000 33 | 3 1 0 1 1.000000000000000 -0.000000000000000 34 | 7 0 3 0 2.000000000000000 0.000000000000000 35 | 3 0 7 0 2.000000000000000 0.000000000000000 36 | 7 1 3 1 2.000000000000000 0.000000000000000 37 | 3 1 7 1 2.000000000000000 0.000000000000000 38 | 5 0 4 0 1.000000000000000 0.000000000000000 39 | 4 0 5 0 1.000000000000000 -0.000000000000000 40 | 5 1 4 1 1.000000000000000 0.000000000000000 41 | 4 1 5 1 1.000000000000000 -0.000000000000000 42 | 6 0 5 0 1.000000000000000 0.000000000000000 43 | 5 0 6 0 1.000000000000000 -0.000000000000000 44 | 6 1 5 1 1.000000000000000 0.000000000000000 45 | 5 1 6 1 1.000000000000000 -0.000000000000000 46 | 7 0 6 0 1.000000000000000 0.000000000000000 47 | 6 0 7 0 1.000000000000000 -0.000000000000000 48 | 7 1 6 1 1.000000000000000 0.000000000000000 49 | 6 1 7 1 1.000000000000000 -0.000000000000000 50 | 4 0 7 0 1.000000000000000 0.000000000000000 51 | 7 0 4 0 1.000000000000000 -0.000000000000000 52 | 4 1 7 1 1.000000000000000 0.000000000000000 53 | 7 1 4 1 1.000000000000000 -0.000000000000000 54 | -------------------------------------------------------------------------------- /template/flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-compat": { 4 | "flake": false, 5 | "locked": { 6 | "lastModified": 1673956053, 7 | "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", 8 | "owner": "edolstra", 9 | "repo": "flake-compat", 10 | "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", 11 | "type": "github" 12 | }, 13 | "original": { 14 | "owner": "edolstra", 15 | "repo": "flake-compat", 16 | "type": "github" 17 | } 18 | }, 19 | "flake-utils": { 20 | "inputs": { 21 | "systems": "systems" 22 | }, 23 | "locked": { 24 | "lastModified": 1689068808, 25 | "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", 26 | "owner": "numtide", 27 | "repo": "flake-utils", 28 | "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", 29 | "type": "github" 30 | }, 31 | "original": { 32 | "owner": "numtide", 33 | "repo": "flake-utils", 34 | "type": "github" 35 | } 36 | }, 37 | "lattice-symmetries": { 38 | "inputs": { 39 | "flake-utils": "flake-utils", 40 | "nix-chapel": "nix-chapel", 41 | "nixpkgs": "nixpkgs" 42 | }, 43 | "locked": { 44 | "lastModified": 1691146629, 45 | "narHash": "sha256-JnfpSj49vlpOVImXdBHk7mSDGRPelCXWr7E0MH9bnok=", 46 | "owner": "twesterhout", 47 | "repo": "lattice-symmetries", 48 | "rev": "d6549f34e9bb0e7097e11ccfbc9b69a16e45264f", 49 | "type": "github" 50 | }, 51 | "original": { 52 | "owner": "twesterhout", 53 | "repo": "lattice-symmetries", 54 | "type": "github" 55 | } 56 | }, 57 | "nix-chapel": { 58 | "inputs": { 59 | "flake-utils": [ 60 | "lattice-symmetries", 61 | "flake-utils" 62 | ], 63 | "nixpkgs": [ 64 | "lattice-symmetries", 65 | "nixpkgs" 66 | ] 67 | }, 68 | "locked": { 69 | "lastModified": 1689321935, 70 | "narHash": "sha256-r5MQDWX6ZYj4eCTeGHVoMHkAZuY8qh+HJJTZs/M8/Fw=", 71 | "owner": "twesterhout", 72 | "repo": "nix-chapel", 73 | "rev": "e03eae25122c0980c1dffe19f0906996ff082af9", 74 | "type": "github" 75 | }, 76 | "original": { 77 | "owner": "twesterhout", 78 | "repo": "nix-chapel", 79 | "type": "github" 80 | } 81 | }, 82 | "nixpkgs": { 83 | "locked": { 84 | "lastModified": 1689192006, 85 | "narHash": "sha256-QM0f0d8oPphOTYJebsHioR9+FzJcy1QNIzREyubB91U=", 86 | "owner": "nixos", 87 | "repo": "nixpkgs", 88 | "rev": "2de8efefb6ce7f5e4e75bdf57376a96555986841", 89 | "type": "github" 90 | }, 91 | "original": { 92 | "owner": "nixos", 93 | "ref": "nixos-unstable", 94 | "repo": "nixpkgs", 95 | "type": "github" 96 | } 97 | }, 98 | "root": { 99 | "inputs": { 100 | "flake-compat": "flake-compat", 101 | "flake-utils": [ 102 | "lattice-symmetries", 103 | "flake-utils" 104 | ], 105 | "lattice-symmetries": "lattice-symmetries", 106 | "nixpkgs": [ 107 | "lattice-symmetries", 108 | "nixpkgs" 109 | ] 110 | } 111 | }, 112 | "systems": { 113 | "locked": { 114 | "lastModified": 1681028828, 115 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 116 | "owner": "nix-systems", 117 | "repo": "default", 118 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 119 | "type": "github" 120 | }, 121 | "original": { 122 | "owner": "nix-systems", 123 | "repo": "default", 124 | "type": "github" 125 | } 126 | } 127 | }, 128 | "root": "root", 129 | "version": 7 130 | } 131 | -------------------------------------------------------------------------------- /python/lattice_symmetries/build_extension.py: -------------------------------------------------------------------------------- 1 | from cffi import FFI 2 | import glob 3 | import os 4 | 5 | # def get_chapel_lib_path(prefix="lattice_symmetries"): 6 | # print(os.getcwd()) 7 | # print(os.listdir(prefix)) 8 | # for f in glob.glob(os.path.join(prefix, "lattice-symmetries-chapel*")): 9 | # print("get_chapel_lib_path -> {}".format(f[len(prefix) + 1:])) 10 | # return f[len(prefix) + 1:] 11 | # return os.environ.get("LATTICE_SYMMETRIES_PATH") 12 | 13 | def get_include_dirs(): 14 | return [] 15 | # kernels_path = os.environ.get("LS_KERNELS_PATH") 16 | # if kernels_path is not None: 17 | # return [os.path.join(kernels_path, "include")] 18 | # else: 19 | # return [] 20 | 21 | # prefix = get_chapel_lib_path() 22 | # if prefix is None: 23 | # assert False 24 | # return [] 25 | # else: 26 | # return [os.path.join("lattice_symmetries", prefix, "include")] 27 | 28 | def get_library_dirs(): 29 | return [] 30 | # prefix = get_chapel_lib_path() 31 | # if prefix is None: 32 | # assert False 33 | # return [] 34 | # else: 35 | # return [os.path.join("lattice_symmetries", prefix, "lib")] 36 | 37 | def get_runtime_dirs(): 38 | return [] 39 | # prefix = get_chapel_lib_path() 40 | # if prefix is None: 41 | # assert False 42 | # return [] 43 | # else: 44 | # return [os.path.join("$ORIGIN", prefix, "lib")] 45 | 46 | def get_generated_declarations(): 47 | with open("lattice_symmetries/extracted_declarations.h", "r") as f: 48 | return f.read() 49 | 50 | ffibuilder = FFI() 51 | 52 | ffibuilder.cdef( 53 | get_generated_declarations() + "\n" + 54 | """ 55 | void set_python_exception_handler(); 56 | ptrdiff_t ls_hs_basis_number_states(ls_hs_basis const* basis); 57 | uint64_t const* ls_hs_basis_states(ls_hs_basis const* basis); 58 | extern "Python" void python_replace_indices(int, int, int*, int*); 59 | """ 60 | ) 61 | 62 | ffibuilder.set_source( 63 | "lattice_symmetries._ls_hs", 64 | """ 65 | #define LS_NO_STD_COMPLEX 66 | #include "lattice_symmetries_types.h" 67 | #include "lattice_symmetries_functions.h" 68 | #include 69 | 70 | static void python_exception_handler(char const* message) { 71 | PyGILState_STATE gstate = PyGILState_Ensure(); 72 | // fprintf(stderr, "Calling PyErr_SetString '%s' ...\\n", message); 73 | PyErr_SetString(PyExc_RuntimeError, message); 74 | // fprintf(stderr, "Returning ...\\n"); 75 | PyGILState_Release(gstate); 76 | } 77 | 78 | static void set_python_exception_handler() { 79 | fprintf(stderr, "set_python_exception_handler ...\\n"); 80 | ls_hs_set_exception_handler(&python_exception_handler); 81 | } 82 | 83 | static ptrdiff_t ls_hs_basis_number_states(ls_hs_basis const* basis) { 84 | if (basis->representatives.elts == NULL) { return -1; } 85 | return (ptrdiff_t)basis->representatives.num_elts; 86 | } 87 | static uint64_t const* ls_hs_basis_states(ls_hs_basis const* basis) { 88 | return basis->representatives.elts; 89 | } 90 | """, 91 | include_dirs=get_include_dirs(), 92 | # [# "../cbits", "/home/tom/src/distributed-matvec/lib/lattice_symmetries_chapel.h"], 93 | # "/home/tom/src/distributed-matvec/third_party/include"], 94 | extra_compile_args=["-Wall", "-Wextra"], 95 | libraries=["lattice_symmetries_chapel", "lattice_symmetries_haskell"], 96 | library_dirs=get_library_dirs(), 97 | extra_link_args=["-Wl,-rpath,{}".format(d) for d in get_runtime_dirs()], 98 | # [ 99 | # "/home/tom/src/distributed-matvec/third_party/lib", 100 | # # "../dist-newstyle/build/x86_64-linux/ghc-8.10.7/lattice-symmetries-haskell-0.1.0.0/f/lattice_symmetries_haskell/noopt/build/lattice_symmetries_haskell", 101 | # # "../kernels/build", 102 | # "/home/tom/src/distributed-matvec/lib"], 103 | ) 104 | 105 | if __name__ == "__main__": 106 | ffibuilder.compile(verbose=True) 107 | 108 | -------------------------------------------------------------------------------- /chapel/src/Utils.chpl: -------------------------------------------------------------------------------- 1 | module Utils { 2 | 3 | private use List; 4 | private use FFI; 5 | import IO; 6 | 7 | proc initRuntime() { 8 | coforall loc in Locales do on loc { 9 | ls_hs_init(); 10 | } 11 | } 12 | 13 | proc deinitRuntime() { 14 | coforall loc in Locales do on loc { 15 | ls_hs_exit(); 16 | } 17 | } 18 | 19 | record VarianceAccumulator { 20 | type eltType; 21 | var _count : int; 22 | var _mean : eltType; 23 | var _M2 : eltType; 24 | 25 | proc init(x : ?eltType) { 26 | this.eltType = eltType; 27 | this._count = 1; 28 | this._mean = x; 29 | this._M2 = 0; 30 | } 31 | 32 | proc update(x : eltType) { 33 | _count += 1; 34 | const delta = x - _mean; 35 | _mean += delta / _count; 36 | const delta2 = x - _mean; 37 | _M2 += delta * delta2; 38 | } 39 | 40 | inline proc mean { return if _count == 0 then (0.0 / 0.0):eltType else _mean; } 41 | inline proc std { return if _count < 2 then (0.0 / 0.0):eltType else _M2 / _count; } 42 | 43 | proc writeThis(f) throws { 44 | f.write(mean, " ± ", std); 45 | } 46 | } 47 | 48 | 49 | class RoseTree { 50 | type eltType; 51 | var func : string; 52 | var stat : eltType; 53 | var children : list(shared RoseTree(eltType)); 54 | 55 | proc init(func : string, stat : ?eltType) { 56 | this.eltType = eltType; 57 | this.func = func; 58 | this.stat = stat; 59 | } 60 | proc init(func : string, stat : ?eltType, children) { 61 | this.eltType = eltType; 62 | this.func = func; 63 | this.stat = stat; 64 | this.children = children; 65 | } 66 | 67 | proc addChild(x : shared RoseTree(eltType)) { 68 | this.children.pushBack(x); 69 | } 70 | proc addChild(func : string, stat : eltType) { 71 | addChild(new shared RoseTree(func, stat)); 72 | } 73 | 74 | proc getChild(func : string) ref { 75 | for c in children { 76 | if c.func == func then return c; 77 | } 78 | halt("child " + func:string + " not found"); 79 | } 80 | 81 | proc toAccumulatorTree() : shared RoseTree(VarianceAccumulator(eltType)) { 82 | var tree = new shared RoseTree(func, new VarianceAccumulator(stat)); 83 | for c in children do 84 | tree.addChild(c.toAccumulatorTree()); 85 | return tree; 86 | } 87 | 88 | proc writeChildren(f, indent : string) throws { 89 | if !children.isEmpty() { 90 | for (x, i) in zip(children, 0 ..) { 91 | const currentPrefix = if i == children.size - 1 then "└─ " else "├─ "; 92 | const childPrefix = if i == children.size - 1 then " " else "│ "; 93 | f.write(indent, currentPrefix, x.func, ": ", x.stat, '\n'); 94 | x.writeChildren(f, indent + childPrefix); 95 | } 96 | } 97 | } 98 | override proc writeThis(f) throws { 99 | f.write(func, ": ", stat, '\n'); 100 | writeChildren(f, indent = " "); 101 | } 102 | } 103 | 104 | 105 | type TimingTree = shared RoseTree(real); 106 | 107 | proc timingTree(func, result, children) { 108 | return new shared RoseTree(func, result, 109 | [(f, r) in children] new shared RoseTree(f, r)); 110 | } 111 | proc timingTree(func, result) { 112 | return new shared RoseTree(func, result); 113 | } 114 | 115 | proc meanAndErr(xs : [] real) { 116 | const mean = (+ reduce xs) / xs.size:real; 117 | const variance = 118 | (1.0 / xs.size:real) 119 | * (+ reduce ([i in xs.domain] (xs[i] - mean) * (xs[i] - mean))); 120 | const err = round(100 * sqrt(variance)) / 100; 121 | return (mean, err); 122 | } 123 | 124 | proc fromAccumulatorTree(tree) : TimingTree { 125 | var outTree = new shared RoseTree(tree.func, tree.stat.mean); 126 | for c in tree.children do 127 | outTree.addChild(fromAccumulatorTree(c)); 128 | return outTree; 129 | } 130 | 131 | proc combineTimingTrees(ref dest, const ref tree) { 132 | dest.stat.update(tree.stat); 133 | for (destChild, child) in zip(dest.children, tree.children) { 134 | combineTimingTrees(destChild, child); 135 | } 136 | } 137 | proc combineTimingTrees(arr : [] TimingTree) { 138 | if arr.isEmpty() then 139 | halt("trying to combine an empty list of timings"); 140 | var dest = arr[0].toAccumulatorTree(); 141 | for tree in arr[1..] do 142 | combineTimingTrees(dest, tree); 143 | return fromAccumulatorTree(dest); 144 | } 145 | 146 | } // module Utils 147 | -------------------------------------------------------------------------------- /test/05_hubbard_tri/HPhi/greenone.def: -------------------------------------------------------------------------------- 1 | =============================== 2 | NCisAjs 144 3 | =============================== 4 | ======== Green functions ====== 5 | =============================== 6 | 0 0 0 0 7 | 0 0 0 1 8 | 0 0 1 0 9 | 0 0 1 1 10 | 0 0 2 0 11 | 0 0 2 1 12 | 0 0 3 0 13 | 0 0 3 1 14 | 0 0 4 0 15 | 0 0 4 1 16 | 0 0 5 0 17 | 0 0 5 1 18 | 0 1 0 0 19 | 0 1 0 1 20 | 0 1 1 0 21 | 0 1 1 1 22 | 0 1 2 0 23 | 0 1 2 1 24 | 0 1 3 0 25 | 0 1 3 1 26 | 0 1 4 0 27 | 0 1 4 1 28 | 0 1 5 0 29 | 0 1 5 1 30 | 1 0 0 0 31 | 1 0 0 1 32 | 1 0 1 0 33 | 1 0 1 1 34 | 1 0 2 0 35 | 1 0 2 1 36 | 1 0 3 0 37 | 1 0 3 1 38 | 1 0 4 0 39 | 1 0 4 1 40 | 1 0 5 0 41 | 1 0 5 1 42 | 1 1 0 0 43 | 1 1 0 1 44 | 1 1 1 0 45 | 1 1 1 1 46 | 1 1 2 0 47 | 1 1 2 1 48 | 1 1 3 0 49 | 1 1 3 1 50 | 1 1 4 0 51 | 1 1 4 1 52 | 1 1 5 0 53 | 1 1 5 1 54 | 2 0 0 0 55 | 2 0 0 1 56 | 2 0 1 0 57 | 2 0 1 1 58 | 2 0 2 0 59 | 2 0 2 1 60 | 2 0 3 0 61 | 2 0 3 1 62 | 2 0 4 0 63 | 2 0 4 1 64 | 2 0 5 0 65 | 2 0 5 1 66 | 2 1 0 0 67 | 2 1 0 1 68 | 2 1 1 0 69 | 2 1 1 1 70 | 2 1 2 0 71 | 2 1 2 1 72 | 2 1 3 0 73 | 2 1 3 1 74 | 2 1 4 0 75 | 2 1 4 1 76 | 2 1 5 0 77 | 2 1 5 1 78 | 3 0 0 0 79 | 3 0 0 1 80 | 3 0 1 0 81 | 3 0 1 1 82 | 3 0 2 0 83 | 3 0 2 1 84 | 3 0 3 0 85 | 3 0 3 1 86 | 3 0 4 0 87 | 3 0 4 1 88 | 3 0 5 0 89 | 3 0 5 1 90 | 3 1 0 0 91 | 3 1 0 1 92 | 3 1 1 0 93 | 3 1 1 1 94 | 3 1 2 0 95 | 3 1 2 1 96 | 3 1 3 0 97 | 3 1 3 1 98 | 3 1 4 0 99 | 3 1 4 1 100 | 3 1 5 0 101 | 3 1 5 1 102 | 4 0 0 0 103 | 4 0 0 1 104 | 4 0 1 0 105 | 4 0 1 1 106 | 4 0 2 0 107 | 4 0 2 1 108 | 4 0 3 0 109 | 4 0 3 1 110 | 4 0 4 0 111 | 4 0 4 1 112 | 4 0 5 0 113 | 4 0 5 1 114 | 4 1 0 0 115 | 4 1 0 1 116 | 4 1 1 0 117 | 4 1 1 1 118 | 4 1 2 0 119 | 4 1 2 1 120 | 4 1 3 0 121 | 4 1 3 1 122 | 4 1 4 0 123 | 4 1 4 1 124 | 4 1 5 0 125 | 4 1 5 1 126 | 5 0 0 0 127 | 5 0 0 1 128 | 5 0 1 0 129 | 5 0 1 1 130 | 5 0 2 0 131 | 5 0 2 1 132 | 5 0 3 0 133 | 5 0 3 1 134 | 5 0 4 0 135 | 5 0 4 1 136 | 5 0 5 0 137 | 5 0 5 1 138 | 5 1 0 0 139 | 5 1 0 1 140 | 5 1 1 0 141 | 5 1 1 1 142 | 5 1 2 0 143 | 5 1 2 1 144 | 5 1 3 0 145 | 5 1 3 1 146 | 5 1 4 0 147 | 5 1 4 1 148 | 5 1 5 0 149 | 5 1 5 1 150 | -------------------------------------------------------------------------------- /test/03_spin_hcor/HPhi/greentwo.def: -------------------------------------------------------------------------------- 1 | ============================================= 2 | NCisAjsCktAltDC 96 3 | ============================================= 4 | ======== Green functions for Sq AND Nq ====== 5 | ============================================= 6 | 0 0 0 0 0 0 0 0 7 | 0 0 0 0 0 1 0 1 8 | 0 0 0 0 1 0 1 0 9 | 0 0 0 0 1 1 1 1 10 | 0 0 0 0 2 0 2 0 11 | 0 0 0 0 2 1 2 1 12 | 0 0 0 0 3 0 3 0 13 | 0 0 0 0 3 1 3 1 14 | 0 0 0 0 4 0 4 0 15 | 0 0 0 0 4 1 4 1 16 | 0 0 0 0 5 0 5 0 17 | 0 0 0 0 5 1 5 1 18 | 0 0 0 0 6 0 6 0 19 | 0 0 0 0 6 1 6 1 20 | 0 0 0 0 7 0 7 0 21 | 0 0 0 0 7 1 7 1 22 | 0 0 0 1 0 1 0 0 23 | 0 0 0 1 1 1 1 0 24 | 0 0 0 1 2 1 2 0 25 | 0 0 0 1 3 1 3 0 26 | 0 0 0 1 4 1 4 0 27 | 0 0 0 1 5 1 5 0 28 | 0 0 0 1 6 1 6 0 29 | 0 0 0 1 7 1 7 0 30 | 0 1 0 0 0 0 0 1 31 | 0 1 0 0 1 0 1 1 32 | 0 1 0 0 2 0 2 1 33 | 0 1 0 0 3 0 3 1 34 | 0 1 0 0 4 0 4 1 35 | 0 1 0 0 5 0 5 1 36 | 0 1 0 0 6 0 6 1 37 | 0 1 0 0 7 0 7 1 38 | 0 1 0 1 0 0 0 0 39 | 0 1 0 1 0 1 0 1 40 | 0 1 0 1 1 0 1 0 41 | 0 1 0 1 1 1 1 1 42 | 0 1 0 1 2 0 2 0 43 | 0 1 0 1 2 1 2 1 44 | 0 1 0 1 3 0 3 0 45 | 0 1 0 1 3 1 3 1 46 | 0 1 0 1 4 0 4 0 47 | 0 1 0 1 4 1 4 1 48 | 0 1 0 1 5 0 5 0 49 | 0 1 0 1 5 1 5 1 50 | 0 1 0 1 6 0 6 0 51 | 0 1 0 1 6 1 6 1 52 | 0 1 0 1 7 0 7 0 53 | 0 1 0 1 7 1 7 1 54 | 1 0 1 0 0 0 0 0 55 | 1 0 1 0 0 1 0 1 56 | 1 0 1 0 1 0 1 0 57 | 1 0 1 0 1 1 1 1 58 | 1 0 1 0 2 0 2 0 59 | 1 0 1 0 2 1 2 1 60 | 1 0 1 0 3 0 3 0 61 | 1 0 1 0 3 1 3 1 62 | 1 0 1 0 4 0 4 0 63 | 1 0 1 0 4 1 4 1 64 | 1 0 1 0 5 0 5 0 65 | 1 0 1 0 5 1 5 1 66 | 1 0 1 0 6 0 6 0 67 | 1 0 1 0 6 1 6 1 68 | 1 0 1 0 7 0 7 0 69 | 1 0 1 0 7 1 7 1 70 | 1 0 1 1 0 1 0 0 71 | 1 0 1 1 1 1 1 0 72 | 1 0 1 1 2 1 2 0 73 | 1 0 1 1 3 1 3 0 74 | 1 0 1 1 4 1 4 0 75 | 1 0 1 1 5 1 5 0 76 | 1 0 1 1 6 1 6 0 77 | 1 0 1 1 7 1 7 0 78 | 1 1 1 0 0 0 0 1 79 | 1 1 1 0 1 0 1 1 80 | 1 1 1 0 2 0 2 1 81 | 1 1 1 0 3 0 3 1 82 | 1 1 1 0 4 0 4 1 83 | 1 1 1 0 5 0 5 1 84 | 1 1 1 0 6 0 6 1 85 | 1 1 1 0 7 0 7 1 86 | 1 1 1 1 0 0 0 0 87 | 1 1 1 1 0 1 0 1 88 | 1 1 1 1 1 0 1 0 89 | 1 1 1 1 1 1 1 1 90 | 1 1 1 1 2 0 2 0 91 | 1 1 1 1 2 1 2 1 92 | 1 1 1 1 3 0 3 0 93 | 1 1 1 1 3 1 3 1 94 | 1 1 1 1 4 0 4 0 95 | 1 1 1 1 4 1 4 1 96 | 1 1 1 1 5 0 5 0 97 | 1 1 1 1 5 1 5 1 98 | 1 1 1 1 6 0 6 0 99 | 1 1 1 1 6 1 6 1 100 | 1 1 1 1 7 0 7 0 101 | 1 1 1 1 7 1 7 1 102 | -------------------------------------------------------------------------------- /haskell/src/LatticeSymmetries/Dense.hs: -------------------------------------------------------------------------------- 1 | -- | 2 | -- Module : LatticeSymmetries.Dense 3 | -- Description : Dense matrices 4 | -- Copyright : (c) Tom Westerhout, 2022 5 | -- Stability : experimental 6 | module LatticeSymmetries.Dense 7 | ( DenseMatrix (..) 8 | , dmShape 9 | , denseMatrixFromList 10 | , denseMatrixToList 11 | , indexDenseMatrix 12 | ) 13 | where 14 | 15 | import Data.Vector.Generic ((!)) 16 | import Data.Vector.Generic qualified as G 17 | import GHC.Exts qualified as GHC (IsList (..)) 18 | 19 | -- | A dense matrix in row-major order (C layout). 20 | data DenseMatrix v a = DenseMatrix 21 | { dmRows :: !Int 22 | -- ^ Number of rows 23 | , dmCols :: !Int 24 | -- ^ Number of columns 25 | , dmData :: !(v a) 26 | -- ^ Matrix elements in row-major order stored in a 'Data.Vector.Generic.Vector' 27 | } 28 | deriving stock (Show, Eq, Generic) 29 | deriving anyclass (NFData) 30 | 31 | -- | Get matrix shape 32 | dmShape :: DenseMatrix v a -> (Int, Int) 33 | dmShape m = (dmRows m, dmCols m) 34 | 35 | -- | Element-wise operations 36 | -- instance (G.Vector v a, Num a) => Num (DenseMatrix v a) where 37 | -- (+) a b = DenseMatrix (dmRows a) (dmCols a) $ G.zipWith (+) (dmData a) (dmData b) 38 | -- (-) a b = DenseMatrix (dmRows a) (dmCols a) $ G.zipWith (-) (dmData a) (dmData b) 39 | -- (*) a b = DenseMatrix (dmRows a) (dmCols a) $ G.zipWith (*) (dmData a) (dmData b) 40 | -- abs a = DenseMatrix (dmRows a) (dmCols a) $ G.map abs (dmData a) 41 | -- signum a = DenseMatrix (dmRows a) (dmCols a) $ G.map signum (dmData a) 42 | -- fromInteger _ = error "Num instance of DenseMatrix does not implement fromInteger" 43 | denseMatrixFromList :: (HasCallStack, G.Vector v a) => [[a]] -> DenseMatrix v a 44 | denseMatrixFromList rs 45 | | G.length elements == nRows * nCols = DenseMatrix nRows nCols elements 46 | | otherwise = error "nested list has irregular shape" 47 | where 48 | !nRows = length rs 49 | !nCols = case rs of 50 | [] -> 0 51 | (r : _) -> length r 52 | elements = G.fromListN (nRows * nCols) $ mconcat rs 53 | 54 | denseMatrixToList :: G.Vector v a => DenseMatrix v a -> [[a]] 55 | denseMatrixToList (DenseMatrix nRows nCols v) = go 0 (G.toList v) 56 | where 57 | go !i elements 58 | | i < nRows = let (row, rest) = splitAt nCols elements in row : go (i + 1) rest 59 | | otherwise = [] 60 | 61 | instance (G.Vector v a) => GHC.IsList (DenseMatrix v a) where 62 | type Item (DenseMatrix v a) = [a] 63 | fromList = denseMatrixFromList 64 | toList = denseMatrixToList 65 | 66 | -- countOffDiagNonZero :: (G.Vector v a, Eq a, Num a) => DenseMatrix v a -> Int 67 | -- countOffDiagNonZero m@(DenseMatrix nRows nCols _) = go1 0 0 68 | -- where 69 | -- go2 !i !j !acc 70 | -- | i == j = go2 i (j + 1) acc 71 | -- | j < nCols = 72 | -- if indexDenseMatrix m (i, j) /= 0 73 | -- then go2 i (j + 1) (acc + 1) 74 | -- else go2 i (j + 1) acc 75 | -- | otherwise = acc 76 | -- go1 !i !acc 77 | -- | i < nRows = let acc' = go2 i 0 acc in go1 (i + 1) acc' 78 | -- | otherwise = acc 79 | 80 | indexDenseMatrix :: (HasCallStack, G.Vector v a) => DenseMatrix v a -> (Int, Int) -> a 81 | indexDenseMatrix (DenseMatrix nRows nCols v) (i, j) 82 | | i < nRows && j < nCols = v ! (nCols * i + j) 83 | | otherwise = error $ "invalid index " <> show (i, j) <> " for a matrix of shape " <> show (nRows, nCols) 84 | 85 | -- extractDiagonal :: (HasCallStack, G.Vector v a, G.Vector v Int) => DenseMatrix v a -> v a 86 | -- extractDiagonal m@(DenseMatrix nRows nCols _) 87 | -- | nRows == nCols = G.map (\i -> indexDenseMatrix m (i, i)) (G.enumFromN 0 nRows) 88 | -- | otherwise = error "cannot extract the diagonal of a non-square matrix" 89 | 90 | -- denseDot :: (G.Vector v a, Num a) => DenseMatrix v a -> DenseMatrix v a -> a 91 | -- denseDot a b = let (DenseMatrix _ _ c) = a * b in G.sum c 92 | 93 | -- denseMatMul :: forall a v. (G.Vector v a, Num a) => DenseMatrix v a -> DenseMatrix v a -> DenseMatrix v a 94 | -- denseMatMul a b = runST $ do 95 | -- let !nRows = dmRows a 96 | -- !nCols = dmCols b 97 | -- cBuffer <- GM.new (nRows * nCols) 98 | -- loopM 0 (< nRows) (+ 1) $ \i -> 99 | -- loopM 0 (< nCols) (+ 1) $ \j -> do 100 | -- !cij <- iFoldM 0 (< dmCols a) (+ 1) (0 :: a) $ \ !acc k -> 101 | -- let !aik = indexDenseMatrix a (i, k) 102 | -- !bkj = indexDenseMatrix b (k, j) 103 | -- in pure (acc + aik * bkj) 104 | -- GM.write cBuffer (i * nCols + j) cij 105 | -- DenseMatrix nRows nCols <$> G.unsafeFreeze cBuffer 106 | 107 | -- denseEye :: (G.Vector v a, Num a) => Int -> DenseMatrix v a 108 | -- denseEye n = runST $ do 109 | -- cBuffer <- G.unsafeThaw $ G.replicate (n * n) 0 110 | -- loopM 0 (< n) (+ 1) $ \i -> 111 | -- GM.write cBuffer (i * n + i) 1 112 | -- c <- G.freeze cBuffer 113 | -- pure $ DenseMatrix n n c 114 | 115 | -- denseIsDiagonal :: (G.Vector v a, Eq a, Num a) => DenseMatrix v a -> Bool 116 | -- denseIsDiagonal m@(DenseMatrix nRows nCols _) = go1 0 117 | -- where 118 | -- go1 !i 119 | -- | i < nRows = go2 i 0 && go1 (i + 1) 120 | -- | otherwise = True 121 | -- go2 !i !j 122 | -- | i == j = go2 i (j + 1) 123 | -- | j < nCols = indexDenseMatrix m (i, j) == 0 && go2 i (j + 1) 124 | -- | otherwise = True 125 | -------------------------------------------------------------------------------- /test/05_hubbard_tri/HPhi/trans.def: -------------------------------------------------------------------------------- 1 | ======================== 2 | NTransfer 72 3 | ======================== 4 | ========i_j_s_tijs====== 5 | ======================== 6 | 1 0 0 0 1.000000000000000 0.000000000000000 7 | 0 0 1 0 1.000000000000000 -0.000000000000000 8 | 1 1 0 1 1.000000000000000 0.000000000000000 9 | 0 1 1 1 1.000000000000000 -0.000000000000000 10 | 3 0 0 0 2.000000000000000 0.000000000000000 11 | 0 0 3 0 2.000000000000000 -0.000000000000000 12 | 3 1 0 1 2.000000000000000 0.000000000000000 13 | 0 1 3 1 2.000000000000000 -0.000000000000000 14 | 4 0 0 0 2.000000000000000 0.000000000000000 15 | 0 0 4 0 2.000000000000000 0.000000000000000 16 | 4 1 0 1 2.000000000000000 0.000000000000000 17 | 0 1 4 1 2.000000000000000 0.000000000000000 18 | 0 0 0 0 1.000000000000000 0.000000000000000 19 | 0 1 0 1 1.000000000000000 0.000000000000000 20 | 2 0 1 0 1.000000000000000 0.000000000000000 21 | 1 0 2 0 1.000000000000000 -0.000000000000000 22 | 2 1 1 1 1.000000000000000 0.000000000000000 23 | 1 1 2 1 1.000000000000000 -0.000000000000000 24 | 4 0 1 0 2.000000000000000 0.000000000000000 25 | 1 0 4 0 2.000000000000000 -0.000000000000000 26 | 4 1 1 1 2.000000000000000 0.000000000000000 27 | 1 1 4 1 2.000000000000000 -0.000000000000000 28 | 5 0 1 0 2.000000000000000 0.000000000000000 29 | 1 0 5 0 2.000000000000000 0.000000000000000 30 | 5 1 1 1 2.000000000000000 0.000000000000000 31 | 1 1 5 1 2.000000000000000 0.000000000000000 32 | 1 0 1 0 1.000000000000000 0.000000000000000 33 | 1 1 1 1 1.000000000000000 0.000000000000000 34 | 0 0 2 0 1.000000000000000 0.000000000000000 35 | 2 0 0 0 1.000000000000000 -0.000000000000000 36 | 0 1 2 1 1.000000000000000 0.000000000000000 37 | 2 1 0 1 1.000000000000000 -0.000000000000000 38 | 5 0 2 0 2.000000000000000 0.000000000000000 39 | 2 0 5 0 2.000000000000000 -0.000000000000000 40 | 5 1 2 1 2.000000000000000 0.000000000000000 41 | 2 1 5 1 2.000000000000000 -0.000000000000000 42 | 3 0 2 0 2.000000000000000 0.000000000000000 43 | 2 0 3 0 2.000000000000000 0.000000000000000 44 | 3 1 2 1 2.000000000000000 0.000000000000000 45 | 2 1 3 1 2.000000000000000 0.000000000000000 46 | 2 0 2 0 1.000000000000000 0.000000000000000 47 | 2 1 2 1 1.000000000000000 0.000000000000000 48 | 4 0 3 0 1.000000000000000 0.000000000000000 49 | 3 0 4 0 1.000000000000000 -0.000000000000000 50 | 4 1 3 1 1.000000000000000 0.000000000000000 51 | 3 1 4 1 1.000000000000000 -0.000000000000000 52 | 1 0 3 0 2.000000000000000 0.000000000000000 53 | 3 0 1 0 2.000000000000000 -0.000000000000000 54 | 1 1 3 1 2.000000000000000 0.000000000000000 55 | 3 1 1 1 2.000000000000000 -0.000000000000000 56 | 3 0 3 0 1.000000000000000 0.000000000000000 57 | 3 1 3 1 1.000000000000000 0.000000000000000 58 | 5 0 4 0 1.000000000000000 0.000000000000000 59 | 4 0 5 0 1.000000000000000 -0.000000000000000 60 | 5 1 4 1 1.000000000000000 0.000000000000000 61 | 4 1 5 1 1.000000000000000 -0.000000000000000 62 | 2 0 4 0 2.000000000000000 0.000000000000000 63 | 4 0 2 0 2.000000000000000 -0.000000000000000 64 | 2 1 4 1 2.000000000000000 0.000000000000000 65 | 4 1 2 1 2.000000000000000 -0.000000000000000 66 | 4 0 4 0 1.000000000000000 0.000000000000000 67 | 4 1 4 1 1.000000000000000 0.000000000000000 68 | 3 0 5 0 1.000000000000000 0.000000000000000 69 | 5 0 3 0 1.000000000000000 -0.000000000000000 70 | 3 1 5 1 1.000000000000000 0.000000000000000 71 | 5 1 3 1 1.000000000000000 -0.000000000000000 72 | 0 0 5 0 2.000000000000000 0.000000000000000 73 | 5 0 0 0 2.000000000000000 -0.000000000000000 74 | 0 1 5 1 2.000000000000000 0.000000000000000 75 | 5 1 0 1 2.000000000000000 -0.000000000000000 76 | 5 0 5 0 1.000000000000000 0.000000000000000 77 | 5 1 5 1 1.000000000000000 0.000000000000000 78 | -------------------------------------------------------------------------------- /haskell/lib/HeaderFileGeneration.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE LambdaCase #-} 2 | {-# LANGUAGE MultiWayIf #-} 3 | {-# LANGUAGE QuasiQuotes #-} 4 | {-# LANGUAGE TemplateHaskell #-} 5 | 6 | module HeaderFileGeneration 7 | ( MutablePtr 8 | , typesTable 9 | , headerFile 10 | , addVerbatimSuffix 11 | , addVerbatimPrefix 12 | , addDeclaration 13 | , addDeclarations 14 | , printDeclarations 15 | ) 16 | where 17 | 18 | import Data.Functor 19 | import Data.Map qualified as Map 20 | import Data.Text (pack, unpack) 21 | import Foreign.C.Types 22 | import Foreign.Ptr 23 | import Language.Haskell.TH 24 | import Language.Haskell.TH.Syntax 25 | import System.Directory 26 | import System.FilePath 27 | import System.IO 28 | import Prelude hiding (Type) 29 | 30 | type MutablePtr = Ptr 31 | 32 | type TypesTable = Map Type String 33 | 34 | data ModuleState = ModuleState 35 | { msTypesTable :: !TypesTable 36 | , msHeaderFile :: FilePath 37 | , msVerbatimPrefix :: [String] 38 | , msVerbatimSuffix :: [String] 39 | , msDeclarations :: [String] 40 | } 41 | deriving stock (Typeable) 42 | 43 | putModuleState :: ModuleState -> Q () 44 | putModuleState = putQ 45 | 46 | getModuleState :: Q ModuleState 47 | getModuleState = do 48 | getQ >>= \case 49 | Just s -> pure s 50 | Nothing -> do 51 | s <- defaultModuleState 52 | addModFinalizer $ do 53 | s' <- getModuleState 54 | runIO $ do 55 | createDirectoryIfMissing True $ takeDirectory (msHeaderFile s') 56 | withFile (msHeaderFile s') WriteMode $ \h -> do 57 | hPutStr h . unpack . unlines . fmap pack $ 58 | [ "/* DO NOT MODIFY: This file is automatically generated */" 59 | , "#pragma once" 60 | , "" 61 | ] 62 | <> msVerbatimPrefix s' 63 | <> msDeclarations s' 64 | <> msVerbatimSuffix s' 65 | putModuleState s 66 | pure s 67 | 68 | defaultModuleState :: Q ModuleState 69 | defaultModuleState = do 70 | table <- Map.fromList <$> processTypePairs baseTypes 71 | pure $ 72 | ModuleState 73 | { msTypesTable = table 74 | , msHeaderFile = "dist-newstyle/foreign_stub.h" 75 | , msVerbatimPrefix = [] 76 | , msVerbatimSuffix = [] 77 | , msDeclarations = [] 78 | } 79 | 80 | baseTypes :: [(Q Type, String)] 81 | baseTypes = [([t|CInt|], "int")] 82 | 83 | typesTable :: [(Q Type, String)] -> DecsQ 84 | typesTable pairs = do 85 | s <- getModuleState 86 | table <- Map.fromList <$> processTypePairs pairs 87 | putModuleState $ s {msTypesTable = table} 88 | pure [] 89 | 90 | headerFile :: FilePath -> DecsQ 91 | headerFile path = do 92 | s <- getModuleState 93 | putModuleState $ s {msHeaderFile = path} 94 | pure [] 95 | 96 | addVerbatimPrefix :: [String] -> DecsQ 97 | addVerbatimPrefix msg = do 98 | s <- getModuleState 99 | putModuleState $ s {msVerbatimPrefix = msVerbatimPrefix s <> msg} 100 | pure [] 101 | 102 | addVerbatimSuffix :: [String] -> DecsQ 103 | addVerbatimSuffix msg = do 104 | s <- getModuleState 105 | putModuleState $ s {msVerbatimSuffix = msVerbatimSuffix s <> msg} 106 | pure [] 107 | 108 | addDeclaration :: String -> DecsQ 109 | addDeclaration function = do 110 | s <- getModuleState 111 | name <- getFunctionName function 112 | tp <- getFunctionType name 113 | decl <- genCSignature function tp 114 | putModuleState $ s {msDeclarations = msDeclarations s <> [decl]} 115 | pure [ForeignD $ ExportF CCall function name tp] 116 | 117 | addDeclarations :: [String] -> DecsQ 118 | addDeclarations = fmap concat . mapM addDeclaration 119 | 120 | printDeclarations :: Q () 121 | printDeclarations = do 122 | s <- getModuleState 123 | forM_ (msDeclarations s) $ \d -> 124 | runIO $ System.IO.putStrLn d 125 | 126 | processTypePairs :: [(Q Type, String)] -> Q [(Type, String)] 127 | processTypePairs = mapM (\(a, b) -> a <&> (,b)) 128 | 129 | lookupTypeInTable :: Type -> Q (Maybe String) 130 | lookupTypeInTable tp = Map.lookup tp . msTypesTable <$> getModuleState 131 | 132 | genCType :: Type -> Q String 133 | genCType (ConT (Name (OccName "Int") _)) = pure "HsInt" 134 | genCType tp = do 135 | lookupTypeInTable tp >>= \case 136 | Just s -> pure s 137 | Nothing -> do 138 | case tp of 139 | AppT cons arg -> do 140 | constPtr <- [t|Ptr|] 141 | mutablePtr <- [t|MutablePtr|] 142 | funPtr <- [t|FunPtr|] 143 | if 144 | | cons == constPtr -> (<> " const*") <$> genCType arg 145 | | cons == mutablePtr -> (<> " *") <$> genCType arg 146 | | cons == funPtr -> genCType arg 147 | | otherwise -> error $ "unknown Haskell type: " <> show tp 148 | _ -> error $ "unknown Haskell type: " <> show tp 149 | 150 | getArgTypes :: Type -> [Type] 151 | getArgTypes (AppT (AppT ArrowT arg) r) = arg : getArgTypes r 152 | getArgTypes _ = [] 153 | 154 | getReturnType :: Type -> Q Type 155 | getReturnType (AppT (AppT ArrowT _) r) = getReturnType r 156 | getReturnType (AppT cons@(ConT _) arg) = do 157 | io <- [t|IO|] 158 | if cons == io 159 | then pure arg 160 | else error $ "unexpected Haskell constructor: " <> show cons 161 | getReturnType r = pure r 162 | 163 | getFunctionName :: String -> Q Name 164 | getFunctionName name = 165 | fromMaybe (error $ "unknown Haskell value: " <> show name) <$> lookupValueName name 166 | 167 | getFunctionType :: Name -> Q Type 168 | getFunctionType name = do 169 | info <- reify name 170 | case info of 171 | VarI _ tp _ -> pure tp 172 | _ -> error $ "unexpected Haskell value: " <> show info 173 | 174 | genCSignature :: String -> Type -> Q String 175 | genCSignature name tp = do 176 | ret <- genCType =<< getReturnType tp 177 | args <- mapM genCType $ getArgTypes tp 178 | pure $ ret <> " " <> name <> "(" <> intercalate ", " args <> ");" 179 | -------------------------------------------------------------------------------- /haskell/lattice-symmetries-haskell.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 3.0 2 | name: lattice-symmetries-haskell 3 | version: 2.2.0 4 | synopsis: See README for more info 5 | description: See README for more info 6 | license: BSD-3-Clause 7 | license-file: LICENSE 8 | author: Tom Westerhout 9 | maintainer: 10 | Tom Westerhout <14264576+twesterhout@users.noreply.github.com> 11 | 12 | copyright: 2021-2023 Tom Westerhout 13 | category: Math 14 | build-type: Simple 15 | 16 | -- extra-doc-files: README.md 17 | tested-with: GHC ==9.6.1 18 | 19 | flag no-standalone 20 | description: 21 | Don't use standalone option for foreign-library (it requires GHC which was built with -fPIC support) 22 | 23 | manual: True 24 | default: False 25 | 26 | common common-options 27 | build-depends: 28 | , base >=4.13.0.0 && <5 29 | , relude 30 | 31 | mixins: 32 | base hiding (Prelude), 33 | relude (Relude as Prelude) 34 | 35 | ghc-options: 36 | -W -Wall -Wcompat -Widentities -Wincomplete-uni-patterns 37 | -Wincomplete-record-updates 38 | 39 | default-language: GHC2021 40 | default-extensions: 41 | AllowAmbiguousTypes 42 | BangPatterns 43 | BinaryLiterals 44 | DataKinds 45 | DeriveAnyClass 46 | DeriveGeneric 47 | DerivingVia 48 | FlexibleContexts 49 | FlexibleInstances 50 | GeneralizedNewtypeDeriving 51 | MultiParamTypeClasses 52 | OverloadedStrings 53 | ScopedTypeVariables 54 | StandaloneDeriving 55 | TypeApplications 56 | TypeFamilies 57 | ViewPatterns 58 | 59 | library 60 | import: common-options 61 | hs-source-dirs: src 62 | exposed-modules: 63 | LatticeSymmetries.Algebra 64 | LatticeSymmetries.Basis 65 | LatticeSymmetries.Benes 66 | LatticeSymmetries.BitString 67 | LatticeSymmetries.ComplexRational 68 | LatticeSymmetries.Context 69 | LatticeSymmetries.Conversion 70 | LatticeSymmetries.Dense 71 | LatticeSymmetries.Expr 72 | LatticeSymmetries.FFI 73 | LatticeSymmetries.Generator 74 | LatticeSymmetries.Group 75 | LatticeSymmetries.NonbranchingTerm 76 | LatticeSymmetries.Operator 77 | LatticeSymmetries.Parser 78 | LatticeSymmetries.Utils 79 | LatticeSymmetries.Yaml 80 | 81 | include-dirs: cbits 82 | 83 | -- build-tool-depends: hsc2hs:hsc2hs 84 | build-depends: 85 | , aeson >=2 86 | , bytestring 87 | , constraints 88 | , containers 89 | , derive-storable 90 | , directory 91 | , inline-c 92 | , megaparsec 93 | , mtl 94 | , parser-combinators 95 | , prettyprinter >=1.7 96 | , primitive 97 | , safe-exceptions 98 | , scientific 99 | , template-haskell 100 | , text 101 | , unliftio-core 102 | , vector 103 | , vector-algorithms 104 | , yaml 105 | 106 | -- , binary 107 | -- , vector-binary-instances 108 | -- , exceptions 109 | -- , co-log-core 110 | -- , vector-algorithms 111 | -- , deepseq 112 | -- , ghc-prim 113 | -- , mtl 114 | -- , random >= 1.2.0 115 | -- , mwc-random 116 | -- , text 117 | -- , ghc-dump-core 118 | -- , ghc-dump-util 119 | -- , template-haskell 120 | -- , inline-c 121 | -- , binary 122 | -- , vector-binary-instances 123 | -- , hdf5-hs 124 | -- , HaskellForMaths 125 | extra-libraries: kernels 126 | 127 | -- pkgconfig-depends: lattice_symmetries 128 | -- c-sources: kernels/indexing.c 129 | -- kernels/reference.c 130 | -- kernels/kernels.c 131 | include-dirs: cbits 132 | cc-options: 133 | -std=c11 -fPIC -O3 -DNDEBUG -Wall -Wextra -Wpedantic -Wconversion 134 | -Wdouble-promotion -Wformat=2 -Wformat-overflow=2 -Winit-self 135 | -Wimplicit-fallthrough -Wunused -Wuninitialized -Wstrict-overflow=2 136 | -Wduplicated-branches -Wfloat-equal -Wshadow -Wunused-macros 137 | -Wmissing-field-initializers -Wno-variadic-macros 138 | 139 | if (os(linux) && !flag(no-standalone)) 140 | ghc-options: -fPIC -fexternal-dynamic-refs 141 | 142 | -- foreign-library foo_bar 143 | -- type: native-shared 144 | -- options: standalone 145 | -- hs-source-dirs: lib 146 | -- other-modules: FooBar 147 | -- default-language: GHC2021 148 | -- build-depends: 149 | -- , base 150 | 151 | foreign-library lattice_symmetries_haskell 152 | import: common-options 153 | type: native-shared 154 | 155 | if ((os(windows) || os(osx)) || os(osx)) 156 | options: standalone 157 | 158 | -- For some reason libffi is not linked properly 159 | if (os(osx) || os(osx)) 160 | extra-libraries: ffi 161 | 162 | if (os(linux) && !flag(no-standalone)) 163 | options: standalone 164 | 165 | -- mod-def-file: MyForeignLib.def 166 | hs-source-dirs: lib 167 | other-modules: 168 | ForeignLibrary 169 | HeaderFileGeneration 170 | 171 | c-sources: cbits/init.c 172 | cc-options: -fPIC -Wall -Wextra 173 | include-dirs: cbits 174 | ghc-options: -Wno-missing-signatures -threaded 175 | build-depends: 176 | , aeson 177 | , bytestring 178 | , containers 179 | , directory 180 | , filepath 181 | , lattice-symmetries-haskell 182 | , prettyprinter 183 | , safe-exceptions 184 | , split 185 | , template-haskell 186 | , text 187 | , vector 188 | 189 | buildable: True 190 | 191 | test-suite lattice-symmetries-haskell-test 192 | import: common-options 193 | type: exitcode-stdio-1.0 194 | hs-source-dirs: test 195 | main-is: Spec.hs 196 | other-modules: 197 | LatticeSymmetries.BenesSpec 198 | LatticeSymmetries.BitStringSpec 199 | LatticeSymmetries.ComplexRationalSpec 200 | LatticeSymmetries.ConversionSpec 201 | LatticeSymmetries.DenseSpec 202 | LatticeSymmetries.GeneratorSpec 203 | LatticeSymmetries.NonbranchingTermSpec 204 | LatticeSymmetries.ParserSpec 205 | 206 | build-depends: 207 | , aeson 208 | , hspec 209 | , lattice-symmetries-haskell 210 | , megaparsec 211 | , prettyprinter 212 | , QuickCheck 213 | , text 214 | , vector 215 | , yaml 216 | 217 | -- , mwc-random 218 | ghc-options: -Wno-orphans -threaded -rtsopts -with-rtsopts=-N 219 | buildable: True 220 | -------------------------------------------------------------------------------- /python/test/test_api.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | import lattice_symmetries as ls 4 | import numpy as np 5 | import scipy.sparse.linalg 6 | from pytest import approx 7 | 8 | 9 | def sum1(xs): 10 | s = None 11 | for x in xs: 12 | if s is not None: 13 | s += x 14 | else: 15 | s = x 16 | return s 17 | 18 | 19 | def test_symmetry(): 20 | a = ls.Symmetry([0, 1, 2], sector=0) 21 | assert a.sector == 0 22 | assert len(a) == 3 23 | assert a.permutation.tolist() == [0, 1, 2] 24 | b = ls.Symmetry(a._payload, None) 25 | assert b.sector == 0 26 | assert len(b) == 3 27 | assert b.permutation.tolist() == [0, 1, 2] 28 | del b 29 | del a 30 | 31 | 32 | def test_symmetries(): 33 | a = ls.Symmetry([1, 2, 3, 0], sector=0) 34 | b = ls.Symmetry([3, 2, 1, 0], sector=0) 35 | c = ls.Symmetries([a, b]) 36 | 37 | 38 | def test_index(): 39 | basis = ls.SpinBasis(4) 40 | basis.build() 41 | assert np.array_equal(basis.index(basis.states), basis.states) 42 | assert np.array_equal(basis.index(basis.states[2]), 2) 43 | 44 | 45 | def test_kagome_symmetries(): 46 | expr = ls.Expr( 47 | "1.0 σᶻ₀ σᶻ₁ + 1.0 σᶻ₀ σᶻ₃ + 1.0 σᶻ₀ σᶻ₈ + 1.0 σᶻ₀ σᶻ₁₀ + 2.0 σ⁺₀ σ⁻₁ + 2.0 σ⁺₀ σ⁻₃ + 2.0 σ⁺₀ σ⁻₈ + 2.0 σ⁺₀ σ⁻₁₀ + 2.0 σ⁻₀ σ⁺₁ + 2.0 σ⁻₀ σ⁺₃ + 2.0 σ⁻₀ σ⁺₈ + 2.0 σ⁻₀ σ⁺₁₀ + 1.0 σᶻ₁ σᶻ₂ + 0.8 σᶻ₁ σᶻ₃ + 0.8 σᶻ₁ σᶻ₉ + 2.0 σ⁺₁ σ⁻₂ + 1.6 σ⁺₁ σ⁻₃ + 1.6 σ⁺₁ σ⁻₉ + 2.0 σ⁻₁ σ⁺₂ + 1.6 σ⁻₁ σ⁺₃ + 1.6 σ⁻₁ σ⁺₉ + 1.0 σᶻ₂ σᶻ₄ + 1.0 σᶻ₂ σᶻ₉ + 1.0 σᶻ₂ σᶻ₁₀ + 2.0 σ⁺₂ σ⁻₄ + 2.0 σ⁺₂ σ⁻₉ + 2.0 σ⁺₂ σ⁻₁₀ + 2.0 σ⁻₂ σ⁺₄ + 2.0 σ⁻₂ σ⁺₉ + 2.0 σ⁻₂ σ⁺₁₀ + 1.0 σᶻ₃ σᶻ₅ + 0.8 σᶻ₃ σᶻ₁₁ + 2.0 σ⁺₃ σ⁻₅ + 1.6 σ⁺₃ σ⁻₁₁ + 2.0 σ⁻₃ σ⁺₅ + 1.6 σ⁻₃ σ⁺₁₁ + 0.8 σᶻ₄ σᶻ₆ + 1.0 σᶻ₄ σᶻ₇ + 0.8 σᶻ₄ σᶻ₁₀ + 1.6 σ⁺₄ σ⁻₆ + 2.0 σ⁺₄ σ⁻₇ + 1.6 σ⁺₄ σ⁻₁₀ + 1.6 σ⁻₄ σ⁺₆ + 2.0 σ⁻₄ σ⁺₇ + 1.6 σ⁻₄ σ⁺₁₀ + 1.0 σᶻ₅ σᶻ₆ + 1.0 σᶻ₅ σᶻ₈ + 1.0 σᶻ₅ σᶻ₁₁ + 2.0 σ⁺₅ σ⁻₆ + 2.0 σ⁺₅ σ⁻₈ + 2.0 σ⁺₅ σ⁻₁₁ + 2.0 σ⁻₅ σ⁺₆ + 2.0 σ⁻₅ σ⁺₈ + 2.0 σ⁻₅ σ⁺₁₁ + 1.0 σᶻ₆ σᶻ₇ + 0.8 σᶻ₆ σᶻ₈ + 2.0 σ⁺₆ σ⁻₇ + 1.6 σ⁺₆ σ⁻₈ + 2.0 σ⁻₆ σ⁺₇ + 1.6 σ⁻₆ σ⁺₈ + 1.0 σᶻ₇ σᶻ₉ + 1.0 σᶻ₇ σᶻ₁₁ + 2.0 σ⁺₇ σ⁻₉ + 2.0 σ⁺₇ σ⁻₁₁ + 2.0 σ⁻₇ σ⁺₉ + 2.0 σ⁻₇ σ⁺₁₁ + 0.8 σᶻ₈ σᶻ₁₀ + 1.6 σ⁺₈ σ⁻₁₀ + 1.6 σ⁻₈ σ⁺₁₀ + 0.8 σᶻ₉ σᶻ₁₁ + 1.6 σ⁺₉ σ⁻₁₁ + 1.6 σ⁻₉ σ⁺₁₁" 48 | ) 49 | # top_shift = ls.Symmetry([5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 11, 10], sector=0) 50 | right_shift = ls.Symmetry([2, 10, 0, 4, 3, 7, 11, 5, 9, 8, 1, 6], sector=1) 51 | assert expr == expr.replace_indices(dict(zip(range(12), right_shift.permutation))) 52 | symmetries = ls.Symmetries([right_shift]) 53 | basis = ls.SpinBasis( 54 | symmetries=symmetries, number_spins=12, hamming_weight=6, spin_inversion=None 55 | ) 56 | basis.build() 57 | # print(basis.states) 58 | # print(basis.state_info(basis.states)) 59 | hamiltonian = ls.Operator(basis, expr) 60 | energy, state = scipy.sparse.linalg.eigsh(hamiltonian, k=1, which="SA") 61 | print(energy) 62 | 63 | 64 | def test_operator_apply(): 65 | basis = ls.SpinBasis(2) 66 | basis.build() 67 | expr = ls.Expr("1.0 σᶻ₀ σᶻ₁ + 2.0 σ⁺₀ σ⁻₁ + 2.0 σ⁻₀ σ⁺₁") 68 | hamiltonian = ls.Operator(basis, expr) 69 | assert len(hamiltonian.apply_off_diag_to_basis_state(basis.states[1])) == 1 70 | 71 | 72 | def test_prepare_hphi(): 73 | basis = ls.SpinBasis(2) 74 | expr = ls.Expr("σᶻ₀ σᶻ₁ + 2 σ⁺₀ σ⁻₁ + 2 σ⁻₀ σ⁺₁") 75 | hamiltonian = ls.Operator(basis, expr) 76 | hamiltonian.prepare_inputs_for_hphi("/tmp/lattice-symmetries-python/hphi") 77 | 78 | 79 | def test_prepare_mvmc(): 80 | # basis = ls.SpinBasis(4) 81 | # expr = ls.Expr("σᶻ₀ σᶻ₁ + 2 σ⁺₀ σ⁻₁ + 2 σ⁻₀ σ⁺₁") 82 | # expr = sum((expr.replace_indices({0: i, 1: j}) for (i, j) in [(0, 1), (1, 2), (2, 3), (3, 0)]), ls.Expr("")) 83 | basis = ls.SpinfulFermionBasis(4, number_particles=4) 84 | 85 | hopping = ls.Expr("- (c†₁↑ c₀↑ + c†₀↑ c₁↑ + c†₁↓ c₀↓ + c†₀↓ c₁↓)") 86 | coulomb = ls.Expr("4.0 n₀↑ n₀↓") 87 | expr = hopping + coulomb 88 | for i, j in [(1, 2), (2, 3), (3, 0)]: 89 | expr += hopping.replace_indices({0: i, 1: j}) 90 | for i in [1, 2, 3]: 91 | expr += coulomb.replace_indices({0: i}) 92 | print(expr) 93 | hamiltonian = ls.Operator(basis, expr) 94 | hamiltonian.prepare_inputs_for_mvmc("/tmp/lattice-symmetries-python/mvmc") 95 | 96 | 97 | def test_anisotropic_kagome_9(): 98 | # fmt: off 99 | nearest = [ 100 | (0, 1), (1, 2), (2, 0), 101 | (3, 4), (4, 5), (5, 3), 102 | (6, 7), (7, 8), (8, 6), 103 | ] 104 | next_nearest = [ 105 | (0, 5), (0, 7), 106 | (1, 3), (1, 8), 107 | (2, 4), (2, 6), 108 | (3, 8), 109 | (4, 6), 110 | (5, 7), 111 | ] 112 | # fmt: on 113 | 114 | basis = ls.SpinfulFermionBasis(number_sites=9, number_particles=3) 115 | basis.build() 116 | hopping = lambda i, j: ls.Expr( 117 | "c†₁↑ c₀↑ + c†₀↑ c₁↑ + c†₁↓ c₀↓ + c†₀↓ c₁↓" 118 | ).replace_indices({0: i, 1: j}) 119 | coulomb = lambda i: ls.Expr("n₀↑ n₀↓").replace_indices({0: i}) 120 | 121 | t1 = -0.3251 122 | t2 = 0.0845 123 | U = 2.8 124 | expr = ( 125 | t1 * sum1((hopping(i, j) for i, j in nearest)) 126 | + t2 * sum1((hopping(i, j) for i, j in next_nearest)) 127 | + U * sum1((coulomb(i) for i in range(9))) 128 | ) 129 | print(expr) 130 | hamiltonian = ls.Operator(basis, expr) 131 | hamiltonian.prepare_inputs_for_hphi("/tmp/kagome") 132 | energy, state = scipy.sparse.linalg.eigsh(hamiltonian, k=1, which="SA", tol=1e-6) 133 | print(energy) 134 | 135 | 136 | def notest_vs_hphi(): 137 | prefix = "../../test" 138 | for folder in os.listdir(prefix): 139 | print(folder) 140 | config = ls.load_yaml_config(os.path.join(prefix, folder, "hamiltonian.yaml")) 141 | config.basis.build() 142 | energy, state = scipy.sparse.linalg.eigsh( 143 | config.hamiltonian, k=1, which="SA", tol=1e-6 144 | ) 145 | with open( 146 | os.path.join(prefix, folder, "HPhi", "output", "zvo_energy.dat") 147 | ) as f: 148 | for line in f.readlines(): 149 | if line.startswith("Energy"): 150 | ref_energy = float(line.strip().split(" ")[-1]) 151 | print(energy, ref_energy) 152 | assert ref_energy is not None 153 | assert energy == approx(ref_energy) 154 | -------------------------------------------------------------------------------- /chapel/src/HashedToBlock.chpl: -------------------------------------------------------------------------------- 1 | module HashedToBlock { 2 | use CommonParameters; 3 | use FFI; 4 | 5 | use BlockDist; 6 | use CTypes; 7 | use RangeChunk; 8 | use Time; 9 | 10 | private proc hashedToBlockComputeCounts(const ref masks : [] ?i, numChunks : int) { 11 | var counts : [0 ..# numLocales, 0 ..# numChunks, 0 ..# numLocales] int; 12 | const countsPtr = c_ptrTo(counts[counts.domain.low]); 13 | coforall loc in Locales do on loc { 14 | const mySubdomain = masks.localSubdomain(loc); 15 | const myRanges : [0 ..# numChunks] range(int) = 16 | chunks(mySubdomain.dim(0), numChunks); 17 | var myCounts : [0 ..# numChunks, 0 ..# numLocales] int; 18 | forall (r, chunkIdx) in zip(myRanges, 0 ..# numChunks) { 19 | foreach key in masks.localAccess(r) { 20 | myCounts[chunkIdx, key:int] += 1; 21 | } 22 | } 23 | const myCountsPtr = c_const_ptrTo(myCounts[myCounts.domain.low]); 24 | const destPtr = countsPtr + loc.id * numChunks * numLocales; 25 | const destSize = (numChunks * numLocales):c_size_t * c_sizeof(int); 26 | PUT(myCountsPtr, 0, destPtr, destSize); 27 | } 28 | return counts; 29 | } 30 | 31 | private proc hashedToBlockComputeSrcOffsets(counts) { 32 | const numChunks = counts.shape[1]; 33 | var offsets : [0 ..# numLocales, 0 ..# numChunks, 0 ..# numLocales] int; 34 | forall localeIdx in 0 ..# numLocales { 35 | var total = 0; 36 | for i in 0 ..# numLocales { 37 | for j in 0 ..# numChunks { 38 | offsets[i, j, localeIdx] = total; 39 | total += counts[i, j, localeIdx]; 40 | } 41 | } 42 | } 43 | return offsets; 44 | } 45 | 46 | private proc hashedToBlockMakeDestArray(arr, masks) { 47 | param rank = arr.innerRank; 48 | const batchSize = if rank == 1 then 1 49 | else arr.innerDom.shape[0]; 50 | const boundingBox = if rank == 1 then {0 ..# masks.size} 51 | else {0 ..# batchSize, 0 ..# masks.size}; 52 | const targetLocales = if rank == 1 then Locales 53 | else reshape(Locales, {0 ..# 1, 0 ..# numLocales}); 54 | const destArrDom = boundingBox dmapped Block(boundingBox, targetLocales); 55 | var destArr : [destArrDom] arr.eltType; 56 | return destArr; 57 | } 58 | 59 | private proc hashedToBlockNumChunks(masks, numChunks) { 60 | const minChunkSize = min reduce [loc in Locales] masks.localSubdomain(loc).size; 61 | return min(numChunks, minChunkSize); 62 | } 63 | 64 | record HashedToBlockTimer { 65 | var total : stopwatch; 66 | var counts : stopwatch; 67 | var distribute : stopwatch; 68 | 69 | proc writeThis(f) throws { 70 | f.write(timingTree( 71 | "arrFromHashedToBlock", total.elapsed(), 72 | [ ("counts", counts.elapsed()) 73 | , ("distribute", distribute.elapsed()) 74 | ] 75 | )); 76 | } 77 | } 78 | 79 | proc arrFromHashedToBlock(const ref arr, const ref masks, 80 | numChunks = hashedToBlockNumChunks(masks, kHashedToBlockNumChunks)) { 81 | var timer = new HashedToBlockTimer(); 82 | timer.total.start(); 83 | 84 | timer.counts.start(); 85 | const counts = hashedToBlockComputeCounts(masks, numChunks); 86 | timer.counts.stop(); 87 | 88 | const srcOffsets = hashedToBlockComputeSrcOffsets(counts); 89 | var destArr = hashedToBlockMakeDestArray(arr, masks); 90 | const countsPtr = c_const_ptrTo(counts[counts.domain.low]); 91 | const srcOffsetsPtr = c_const_ptrTo(srcOffsets[srcOffsets.domain.low]); 92 | const mainLocaleIdx = here.id; 93 | const arrPtrsPtr = c_const_ptrTo(arr._dataPtrs[0]); 94 | param rank = arr.innerRank; 95 | const batchSize = if rank == 1 then 1 else arr.innerDom.shape[0]; 96 | const batchStride = if rank == 1 then 0 else arr.innerDom.shape[1]; 97 | 98 | timer.distribute.start(); 99 | coforall loc in Locales do on loc { 100 | const myDestSubdomain = destArr.localSubdomain(); 101 | const myMasksSubdomain = masks.localSubdomain(); 102 | // const mySize = myMasksSubdomain.size; 103 | const myRanges : [0 ..# numChunks] range(int) = 104 | chunks(myMasksSubdomain.dim(0), numChunks); 105 | 106 | var myCounts : [0 ..# numChunks, 0 ..# numLocales] int; 107 | var mySrcOffsets : [myCounts.domain] int; 108 | var myArrPtrs : [0 ..# numLocales] c_ptr(arr.eltType); 109 | cobegin { 110 | GET(c_ptrTo(myCounts[myCounts.domain.low]), mainLocaleIdx, 111 | countsPtr + loc.id * (numChunks * numLocales), 112 | (numChunks * numLocales):c_size_t * c_sizeof(int)); 113 | GET(c_ptrTo(mySrcOffsets[mySrcOffsets.domain.low]), mainLocaleIdx, 114 | srcOffsetsPtr + loc.id * (numChunks * numLocales), 115 | (numChunks * numLocales):c_size_t * c_sizeof(int)); 116 | GET(c_ptrTo(myArrPtrs[myArrPtrs.domain.low]), mainLocaleIdx, 117 | arrPtrsPtr, numLocales:c_size_t * c_sizeof(myArrPtrs.eltType)); 118 | } 119 | 120 | for batchIdx in 0 ..# batchSize { 121 | forall (r, chunkIdx) in zip(myRanges, 0 ..# numChunks) { 122 | var maxCount = max reduce myCounts[chunkIdx, ..]; 123 | var srcArr : [0 ..# numLocales, 0 ..# maxCount] arr.eltType; 124 | for srcLocaleIdx in 0 ..# numLocales { 125 | const n = myCounts[chunkIdx, srcLocaleIdx]; 126 | const k = mySrcOffsets[chunkIdx, srcLocaleIdx]; 127 | GET(c_ptrTo(srcArr[srcLocaleIdx, 0]), srcLocaleIdx, 128 | myArrPtrs[srcLocaleIdx] + batchIdx * batchStride + k, 129 | n:c_size_t * c_sizeof(srcArr.eltType)); 130 | } 131 | 132 | var written : [0 ..# numLocales] int; 133 | for destIdx in r { 134 | const key = masks.localAccess(destIdx):int; 135 | ref offset = written[key]; 136 | if rank == 1 then 137 | destArr.localAccess(destIdx) = srcArr[key, offset]; 138 | else 139 | destArr.localAccess(batchIdx, destIdx) = srcArr[key, offset]; 140 | offset += 1; 141 | } 142 | } 143 | } 144 | } 145 | timer.distribute.stop(); 146 | timer.total.stop(); 147 | if kDisplayTimings then logDebug(timer); 148 | 149 | return destArr; 150 | } 151 | 152 | } // module HashedToBlock 153 | -------------------------------------------------------------------------------- /test/04_hubbard_square/HPhi/greenone.def: -------------------------------------------------------------------------------- 1 | =============================== 2 | NCisAjs 256 3 | =============================== 4 | ======== Green functions ====== 5 | =============================== 6 | 0 0 0 0 7 | 0 0 0 1 8 | 0 0 1 0 9 | 0 0 1 1 10 | 0 0 2 0 11 | 0 0 2 1 12 | 0 0 3 0 13 | 0 0 3 1 14 | 0 0 4 0 15 | 0 0 4 1 16 | 0 0 5 0 17 | 0 0 5 1 18 | 0 0 6 0 19 | 0 0 6 1 20 | 0 0 7 0 21 | 0 0 7 1 22 | 0 1 0 0 23 | 0 1 0 1 24 | 0 1 1 0 25 | 0 1 1 1 26 | 0 1 2 0 27 | 0 1 2 1 28 | 0 1 3 0 29 | 0 1 3 1 30 | 0 1 4 0 31 | 0 1 4 1 32 | 0 1 5 0 33 | 0 1 5 1 34 | 0 1 6 0 35 | 0 1 6 1 36 | 0 1 7 0 37 | 0 1 7 1 38 | 1 0 0 0 39 | 1 0 0 1 40 | 1 0 1 0 41 | 1 0 1 1 42 | 1 0 2 0 43 | 1 0 2 1 44 | 1 0 3 0 45 | 1 0 3 1 46 | 1 0 4 0 47 | 1 0 4 1 48 | 1 0 5 0 49 | 1 0 5 1 50 | 1 0 6 0 51 | 1 0 6 1 52 | 1 0 7 0 53 | 1 0 7 1 54 | 1 1 0 0 55 | 1 1 0 1 56 | 1 1 1 0 57 | 1 1 1 1 58 | 1 1 2 0 59 | 1 1 2 1 60 | 1 1 3 0 61 | 1 1 3 1 62 | 1 1 4 0 63 | 1 1 4 1 64 | 1 1 5 0 65 | 1 1 5 1 66 | 1 1 6 0 67 | 1 1 6 1 68 | 1 1 7 0 69 | 1 1 7 1 70 | 2 0 0 0 71 | 2 0 0 1 72 | 2 0 1 0 73 | 2 0 1 1 74 | 2 0 2 0 75 | 2 0 2 1 76 | 2 0 3 0 77 | 2 0 3 1 78 | 2 0 4 0 79 | 2 0 4 1 80 | 2 0 5 0 81 | 2 0 5 1 82 | 2 0 6 0 83 | 2 0 6 1 84 | 2 0 7 0 85 | 2 0 7 1 86 | 2 1 0 0 87 | 2 1 0 1 88 | 2 1 1 0 89 | 2 1 1 1 90 | 2 1 2 0 91 | 2 1 2 1 92 | 2 1 3 0 93 | 2 1 3 1 94 | 2 1 4 0 95 | 2 1 4 1 96 | 2 1 5 0 97 | 2 1 5 1 98 | 2 1 6 0 99 | 2 1 6 1 100 | 2 1 7 0 101 | 2 1 7 1 102 | 3 0 0 0 103 | 3 0 0 1 104 | 3 0 1 0 105 | 3 0 1 1 106 | 3 0 2 0 107 | 3 0 2 1 108 | 3 0 3 0 109 | 3 0 3 1 110 | 3 0 4 0 111 | 3 0 4 1 112 | 3 0 5 0 113 | 3 0 5 1 114 | 3 0 6 0 115 | 3 0 6 1 116 | 3 0 7 0 117 | 3 0 7 1 118 | 3 1 0 0 119 | 3 1 0 1 120 | 3 1 1 0 121 | 3 1 1 1 122 | 3 1 2 0 123 | 3 1 2 1 124 | 3 1 3 0 125 | 3 1 3 1 126 | 3 1 4 0 127 | 3 1 4 1 128 | 3 1 5 0 129 | 3 1 5 1 130 | 3 1 6 0 131 | 3 1 6 1 132 | 3 1 7 0 133 | 3 1 7 1 134 | 4 0 0 0 135 | 4 0 0 1 136 | 4 0 1 0 137 | 4 0 1 1 138 | 4 0 2 0 139 | 4 0 2 1 140 | 4 0 3 0 141 | 4 0 3 1 142 | 4 0 4 0 143 | 4 0 4 1 144 | 4 0 5 0 145 | 4 0 5 1 146 | 4 0 6 0 147 | 4 0 6 1 148 | 4 0 7 0 149 | 4 0 7 1 150 | 4 1 0 0 151 | 4 1 0 1 152 | 4 1 1 0 153 | 4 1 1 1 154 | 4 1 2 0 155 | 4 1 2 1 156 | 4 1 3 0 157 | 4 1 3 1 158 | 4 1 4 0 159 | 4 1 4 1 160 | 4 1 5 0 161 | 4 1 5 1 162 | 4 1 6 0 163 | 4 1 6 1 164 | 4 1 7 0 165 | 4 1 7 1 166 | 5 0 0 0 167 | 5 0 0 1 168 | 5 0 1 0 169 | 5 0 1 1 170 | 5 0 2 0 171 | 5 0 2 1 172 | 5 0 3 0 173 | 5 0 3 1 174 | 5 0 4 0 175 | 5 0 4 1 176 | 5 0 5 0 177 | 5 0 5 1 178 | 5 0 6 0 179 | 5 0 6 1 180 | 5 0 7 0 181 | 5 0 7 1 182 | 5 1 0 0 183 | 5 1 0 1 184 | 5 1 1 0 185 | 5 1 1 1 186 | 5 1 2 0 187 | 5 1 2 1 188 | 5 1 3 0 189 | 5 1 3 1 190 | 5 1 4 0 191 | 5 1 4 1 192 | 5 1 5 0 193 | 5 1 5 1 194 | 5 1 6 0 195 | 5 1 6 1 196 | 5 1 7 0 197 | 5 1 7 1 198 | 6 0 0 0 199 | 6 0 0 1 200 | 6 0 1 0 201 | 6 0 1 1 202 | 6 0 2 0 203 | 6 0 2 1 204 | 6 0 3 0 205 | 6 0 3 1 206 | 6 0 4 0 207 | 6 0 4 1 208 | 6 0 5 0 209 | 6 0 5 1 210 | 6 0 6 0 211 | 6 0 6 1 212 | 6 0 7 0 213 | 6 0 7 1 214 | 6 1 0 0 215 | 6 1 0 1 216 | 6 1 1 0 217 | 6 1 1 1 218 | 6 1 2 0 219 | 6 1 2 1 220 | 6 1 3 0 221 | 6 1 3 1 222 | 6 1 4 0 223 | 6 1 4 1 224 | 6 1 5 0 225 | 6 1 5 1 226 | 6 1 6 0 227 | 6 1 6 1 228 | 6 1 7 0 229 | 6 1 7 1 230 | 7 0 0 0 231 | 7 0 0 1 232 | 7 0 1 0 233 | 7 0 1 1 234 | 7 0 2 0 235 | 7 0 2 1 236 | 7 0 3 0 237 | 7 0 3 1 238 | 7 0 4 0 239 | 7 0 4 1 240 | 7 0 5 0 241 | 7 0 5 1 242 | 7 0 6 0 243 | 7 0 6 1 244 | 7 0 7 0 245 | 7 0 7 1 246 | 7 1 0 0 247 | 7 1 0 1 248 | 7 1 1 0 249 | 7 1 1 1 250 | 7 1 2 0 251 | 7 1 2 1 252 | 7 1 3 0 253 | 7 1 3 1 254 | 7 1 4 0 255 | 7 1 4 1 256 | 7 1 5 0 257 | 7 1 5 1 258 | 7 1 6 0 259 | 7 1 6 1 260 | 7 1 7 0 261 | 7 1 7 1 262 | --------------------------------------------------------------------------------