├── .gitignore ├── EXTERNAL.md ├── LICENSE ├── Makefile.in ├── README.md ├── algos └── dmrg │ ├── dmrg.cpp │ └── dmrg.h ├── deprecated-examples ├── dtensor │ ├── Makefile │ ├── main.cpp │ └── test.h5 ├── ezh5 │ ├── Makefile │ ├── main.cpp │ ├── test_Eigen3_matrix.h5 │ └── test_stl_vector.h5 ├── qtt │ ├── Makefile │ └── main.cpp └── tblis │ ├── Makefile │ ├── main.cpp │ └── out.txt ├── dtensor ├── assert.cpp ├── big_dtensor.cpp ├── big_dtensor.h ├── dtensor.cpp ├── dtensor.h ├── dtensor_all.h ├── dtensor_index.cpp ├── dtensor_index.h ├── dtensor_index_op.cpp ├── dtensor_index_op.h ├── dtensor_op.cpp ├── dtensor_op.h ├── tensor_index.cpp ├── tensor_index.h ├── tensor_index_op.cpp └── tensor_index_op.h ├── examples └── denseInput ├── linalg ├── lapack_wrapper.cpp ├── lapack_wrapper.h ├── tensor_davidson.cpp └── tensor_davidson.h ├── logo2.png ├── models ├── hams │ ├── AutoMPO.cpp │ ├── AutoMPO.h │ ├── Heisenberg.cpp │ └── Heisenberg.h ├── lattice │ ├── latticebond.h │ ├── square.h │ └── triangular.h └── sites │ ├── electron.cpp │ ├── electron.h │ ├── sites.h │ ├── spinhalf.cpp │ └── spinhalf.h ├── mps ├── mps_all.h ├── mps_mpo_methods.cpp ├── mps_mpo_methods.h ├── observables.cpp ├── observables.h ├── qstt.cpp ├── qstt.h ├── qtt.cpp ├── qtt.h ├── tt.cpp └── tt.h ├── project └── main.cpp ├── qstensor ├── big_qstensor.cpp ├── big_qstensor.h ├── qstensor.cpp ├── qstensor.h ├── qstensor_all.h ├── qstensor_op.cpp └── qstensor_op.h ├── qtensor ├── big_qtensor.cpp ├── big_qtensor.h ├── qtensor.cpp ├── qtensor.h ├── qtensor_all.h ├── qtensor_index.cpp ├── qtensor_index.h ├── qtensor_index_op.cpp ├── qtensor_index_op.h ├── qtensor_op.cpp └── qtensor_op.h ├── toFix ├── dtensor │ ├── dtensor_view.cpp │ └── dtensor_view.h └── linalg │ ├── tensor_cg.cpp │ └── tensor_cg.h └── util ├── QN.h ├── ezh5.cpp ├── ezh5.h ├── timer.h └── types_and_headers.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /EXTERNAL.md: -------------------------------------------------------------------------------- 1 | Some portions of this code are modified from the ITensor library, which has the original copyright 2 | 3 | ```C++ 4 | // 5 | // Copyright 2018 The Simons Foundation, Inc. - All Rights Reserved. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | ``` 19 | 20 | The list of modified files that include such work are: 21 | - `linalg/tensor_davidson.cpp` 22 | - `tensor_davidsonIT` 23 | - `models` 24 | - `hams/AutoMPO.cpp` 25 | - `hams/Heisenberg.cpp` 26 | - `buildHam(AutoMPO& ampo, MPO& H)`, `buildHam(AutoMPO& ampo, qMPO& H)` 27 | - `lattice` 28 | - `latticebond.h`,`triangular.h`,`square.h` 29 | -------------------------------------------------------------------------------- /Makefile.in: -------------------------------------------------------------------------------- 1 | CC = mpiicpc 2 | CC_FLAGS = -O2 -qopenmp -std=c++11 -W -g 3 | 4 | HDF5_INC = -I/usr/lib/x86_64-linux-gnu/hdf5/serial/include 5 | HDF5_LIB = -L/usr/lib/x86_64-linux-gnu/hdf5/serial/lib -lhdf5 6 | 7 | HPTT_INC = -DUSE_HPTT -I${HOME}/software/ctf/hptt/include 8 | HPTT_LIB = -DUSE_HPTT -L${HOME}/software/ctf/hptt/lib -Wl,-rpath=${HOME}/software/ctf/hptt/lib -lhptt 9 | 10 | EIGEN_INC = -I ${HOME}/software/eigen-3.3.7 11 | 12 | CTF_INC = -I${HOME}/software/ctf/include 13 | CTF_LIB = -L${HOME}/software/ctf/lib -lctf -lmkl_scalapack_lp64 -Wl,--start-group -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -lmkl_blacs_intelmpi_lp64 -Wl,--end-group -lpthread -lm 14 | 15 | # Blue waters with gcc, SciLib 16 | # CC = CC 17 | # CC_FLAGS = -O2 -fopenmp -std=c++11 -W -g -DNDEBUG 18 | # 19 | # # CTF should be handling LAPACK 20 | # #LAPACK_INC = 21 | # #LAPACK_LIB = 22 | # 23 | # HPTT_INC = -DUSE_HPTT -I${HOME}/bin/ctf/hptt/include 24 | # HPTT_LIB = -DUSE_HPTT -L${HOME}/bin/ctf/hptt/lib -Wl,-rpath=${HOME}/bin/ctf/hptt/lib -lhptt 25 | # 26 | # EIGEN_INC = -I ${HOME}/bin/eigen-eigen-b9cd8366d4e8 27 | # 28 | # CTF_INC = -I${HOME}/ctf/include 29 | # CTF_LIB = -L${HOME}/ctf/lib -lctf 30 | 31 | # Stampede2 32 | # CC = mpicxx 33 | # CC_FLAGS = -O2 -fopenmp -std=c++11 -W -g -DNDEBUG 34 | # 35 | # # CTF should be handling LAPACK 36 | # #LAPACK_INC = 37 | # #LAPACK_LIB = 38 | # 39 | # HDF5_INC = -I${TACC_HDF5_INC} 40 | # HDF5_LIB = -Wl,-rpath,${TACC_HDF5_LIB} -L${TACC_HDF5_LIB} -lhdf5 -lz 41 | # 42 | # HPTT_INC = -DUSE_HPTT -I${HOME}/software/ctf/hptt/include 43 | # HPTT_LIB = -DUSE_HPTT -L${HOME}/software/ctf/hptt/lib -Wl,-rpath=${HOME}/software/ctf/hptt/lib -lhptt 44 | # 45 | # EIGEN_INC = -I${HOME}/software/eigen-eigen-323c052e1731 46 | # 47 | # CTF_INC = -I${HOME}/software/ctf/include 48 | # CTF_LIB = -L${MKLROOT}/lib/intel64/ -lmkl_scalapack_lp64 -Wl,--start-group -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -lmkl_blacs_intelmpi_lp64 -Wl,--end-group -lpthread -lm -L${HOME}/software/ctf_nomem/lib -lctf 49 | 50 | 51 | # File names 52 | EXEC = run 53 | SOURCES = $(wildcard ./project/*.cpp ./util/*.cpp ./linalg/*.cpp ./dtensor/*.cpp ./qtensor/*.cpp ./qstensor/*.cpp ./mps/*.cpp ./models/hams/*.cpp ./models/sites/*.cpp ./algos/dmrg/*.cpp) 54 | OBJECTS = $(SOURCES:.cpp=.o) 55 | 56 | # Main target 57 | $(EXEC): $(OBJECTS) 58 | $(CC) $(OBJECTS) $(CC_FLAGS) $(CTF_LIB) $(HPTT_LIB) $(LAPACK_LIB) $(HDF5_LIB) -o $(EXEC) 59 | 60 | # To obtain object files 61 | %.o: %.cpp 62 | $(CC) -c $(CC_FLAGS) $(CTF_INC) $(HPTT_INC) $(LAPACK_INC) $(HDF5_INC) $(EIGEN_INC) $< -o $@ 63 | 64 | # To remove generated files 65 | clean: 66 | rm -f $(EXEC) $(OBJECTS) 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | tensor-tools logo 2 | 3 | # tensor-tools parallel 4 | 5 | 6 | ### What is it? 7 | 8 | The parallel verison of `tensor-tools` is a parallel tensor-network library currently customized for performing DMRG (with quantum numbers) in parallel. The parallelization is done via MPI over nodes, using [CTF tensors](https://github.com/cyclops-community/ctf/). It is particularly powerful for spin-systems or those without conserved U(1) symmetries. 9 | Not only can it reach bond-dimensions which are inaccessible serially, but (if we extrapolate what a serial code could do on a big-enough machine) it achieves a 10x speedup at no extra cost in node-hours. See [arxiv:2007.05540](https://arxiv.org/abs/2007.05540). 10 | 11 | ### Authors 12 | 13 | The parallel version of tensor-tools was developed by [Ryan Levy](https://ryanlevy.github.io/) under the guidance of [Bryan Clark](http://clark.physics.illinois.edu/) with CTF and other help from [Edgar Solomonik](http://solomonik.cs.illinois.edu/). It is built on top of the [serial version of tensor-tools](https://github.com/ClarkResearchGroup/tensor-tools/tree/serial) which was written (circa 2017) by Xiongjie Yu (under the guidance of Clark); the serial code now also has additional contributions/bug-fixes from Ryan Levy. 14 | 15 | 16 | ## Installation and Running 17 | 18 | Requirements: 19 | - [CTF](https://github.com/cyclops-community/ctf/) 20 | - compiled with lapack/scalapack support; hptt support preferred 21 | - example configure line: `./configure --no-dynamic --build-hptt --with-scalapack' 'LIB_PATH=-L${MKLROOT}/lib/intel64/' 'LIBS=-lmkl_scalapack_lp64 -Wl,--start-group -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -lmkl_blacs_intelmpi_lp64 -Wl,--end-group -lpthread -lm'` 22 | - If using sparse tensors, intel MKL is strongly suggested 23 | - HDF5 24 | - [Eigen3](http://eigen.tuxfamily.org/index.php?title=Main_Page) 25 | - C++11 support (GCC 6.3.0/8.2.0, Intel 18.0.2/18.0.3.222 compilers tested) 26 | 27 | After installing the required libraries, simply make a copy of `Makefile.in` and adjust the variables to their pointed location. Examples of a linux system, Blue Waters, and Stampede2 are provided. Then build (`make -j`) which will create an executable `run` based on the `project/main.cpp` file. 28 | 29 | To execute, launch with MPI using `mpirun -n [# of procs] run [inputFile]` and follow CTF good practice such as `export OMP_NUM_THREADS=1` and `CTF_PPN=[# of procs/node]`. 30 | 31 | ## Conversion 32 | 33 | Conversion to and from ITensor files is fully supported for v2 and v3.1.x (to be determined). See [link repository here]. 34 | 35 | ----------------- 36 | 37 | ### External Code 38 | We utilize both the AutoMPO system from [ITensor](https://github.com/ITensor/ITensor/) and some of their lattice code, to have better interoperability between the two. See [EXTERNAL.md](EXTERNAL.md) for more. 39 | 40 | Some of the general tensor-tools interface/API was also inspired by ITensor. 41 | -------------------------------------------------------------------------------- /algos/dmrg/dmrg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef DMRG_CLASS_HEADER 19 | #define DMRG_CLASS_HEADER 20 | 21 | #include "../../mps/tt.h" 22 | #include "../../mps/qtt.h" 23 | #include "../../mps/observables.h" 24 | #include "../../linalg/tensor_davidson.h" 25 | 26 | #include "../../util/timer.h" 27 | //------------------------------------------------------------------------------------------- 28 | // MPS, MPO 29 | template 30 | void buildEnv(MPS& psi, MPO& H, std::vector>& TR, std::vector>& TL); 31 | template 32 | void updateSite(MPS& psi, MPO& H, std::vector>& TR, std::vector>& TL, const unsigned& site, T& energy, int& direction, int max_bd, double cutoff, char mode, int search_space_size, int max_restart, Timer &davidson); 33 | template 34 | void updateEnv(MPS& psi, MPO& H, std::vector>& TR, std::vector>& TL, const unsigned& site, int& direction); 35 | template 36 | T dmrg(MPS& psi, MPO& H, int num_sweeps, int max_bd = 100, double cutoff=1e-12, char mode='S', int search_space_size=3, int max_restart=1,int start_sweep=0); 37 | 38 | template 39 | T dmrg(MPS& psi, MPO& H, int num_sweeps, const std::vector& max_bd, const std::vector& cutoff, const std::vector& max_restart); 40 | //------------------------------------------------------------------------------------------- 41 | // qMPS, qMPO 42 | template 43 | void buildEnv(qMPS& psi, qMPO& H, std::vector>& TR, std::vector>& TL); 44 | template 45 | void buildEnv(qMPS& psi, qMPO& H, std::vector>& TR, std::vector>& TL, unsigned start, unsigned stop); 46 | template 47 | void updateSite(qMPS& psi, qMPO& H, std::vector>& TR, std::vector>& TL, const unsigned& site, T& energy, int& direction, int max_bd, double cutoff, char mode, int search_space_size, int max_restart); 48 | template 49 | void updateEnv(qMPS& psi, qMPO& H, std::vector>& TR, std::vector>& TL, const unsigned& site, int& direction); 50 | template 51 | T dmrg(qMPS& psi, qMPO& H, int num_sweeps, int max_bd = 100, double cutoff=1e-12, char mode='S', int search_space_size=3, int max_restart=1,int start_sweep=0); 52 | 53 | template 54 | T dmrg(qMPS& psi, qMPO& H, int num_sweeps, const std::vector& max_bd, const std::vector& cutoff, const std::vector& max_restart); 55 | template 56 | T dmrg(qMPS& psi, qMPO& H, unsigned start, unsigned stop, int num_sweeps, const std::vector& max_bd, const std::vector& cutoff, const std::vector& max_restart); 57 | //------------------------------------------------------------------------------------------- 58 | // qsMPS, qsMPO 59 | template 60 | void buildEnv(qsMPS& psi, qsMPO& H, std::vector>& TR, std::vector>& TL); 61 | template 62 | void buildEnv(qsMPS& psi, qsMPO& H, std::vector>& TR, std::vector>& TL, unsigned start, unsigned stop); 63 | template 64 | void updateSite(qsMPS& psi, qsMPO& H, std::vector>& TR, std::vector>& TL, const unsigned& site, T& energy, int& direction, int max_bd, double cutoff, char mode, int search_space_size, int max_restart); 65 | template 66 | void updateEnv(qsMPS& psi, qsMPO& H, std::vector>& TR, std::vector>& TL, const unsigned& site, int& direction); 67 | template 68 | T dmrg(qsMPS& psi, qsMPO& H, int num_sweeps, int max_bd = 100, double cutoff=1e-12, char mode='S', int search_space_size=3, int max_restart=1,int start_sweep=0); 69 | 70 | template 71 | T dmrg(qsMPS& psi, qsMPO& H, int num_sweeps, const std::vector& max_bd, const std::vector& cutoff, const std::vector& max_restart); 72 | template 73 | T dmrg(qsMPS& psi, qsMPO& H, unsigned start, unsigned stop, int num_sweeps, const std::vector& max_bd, const std::vector& cutoff, const std::vector& max_restart); 74 | #endif 75 | -------------------------------------------------------------------------------- /deprecated-examples/dtensor/Makefile: -------------------------------------------------------------------------------- 1 | CC = icpc 2 | CC_FLAGS = -O2 -qopenmp -qoverride-limits -xhost -DNDEBUG -std=c++11 -W 3 | 4 | LAPACK_INC = -DMKL_Complex16="std::complex" 5 | LAPACK_LIB = -mkl=parallel 6 | 7 | HDF5_INC = -DUSE_EZH5 -I/usr/local/opt/hdf5/include 8 | HDF5_LIB = -L/usr/local/opt/hdf5/lib -lhdf5 9 | 10 | TBLIS_INC = -DUSE_TBLIS -I/usr/local/include -I/usr/local/include/tblis 11 | TBLIS_LIB = -L/usr/local/lib -ltblis 12 | 13 | HPTT_INC = -DUSE_HPTT -I/Volumes/CoolStuff/MyLibrary/hptt/src 14 | HPTT_LIB = -L/Volumes/CoolStuff/MyLibrary/hptt/lib -lhptt 15 | 16 | 17 | # CC = g++-7 18 | # CC_FLAGS = -O2 -g -march=native -fopenmp -ffast-math -std=c++11 -W 19 | # 20 | # LAPACK_INC = -framework Accelerate 21 | # LAPACK_LIB = -framework Accelerate 22 | # 23 | # HDF5_INC = -DUSE_EZH5 -I/usr/local/opt/hdf5/include 24 | # HDF5_LIB = -L/usr/local/opt/hdf5/lib -lhdf5 25 | # 26 | # TBLIS_INC = -DUSE_TBLIS -I/usr/local/include -I/usr/local/include/tblis 27 | # TBLIS_LIB = -L/usr/local/lib -ltblis 28 | # 29 | # HPTT_INC = -DUSE_HPTT -I/Volumes/CoolStuff/MyLibrary/hptt/src 30 | # HPTT_LIB = -L/Volumes/CoolStuff/MyLibrary/hptt/lib -lhptt 31 | 32 | 33 | # CC = g++ 34 | # CC_FLAGS = -O2 -DNDEBUG -march=native -fopenmp -ffast-math -std=c++11 -W 35 | # 36 | # LAPACK_INC = -I/usr/include/openblas 37 | # LAPACK_LIB = -lpthread -L/usr/lib/openblas-base -lopenblas 38 | # 39 | # HDF5_INC = -DUSE_EZH5 -I/usr/lib/x86_64-linux-gnu/hdf5/serial/include 40 | # HDF5_LIB = -L/usr/lib/x86_64-linux-gnu/hdf5/serial/lib -lhdf5 41 | # 42 | # TBLIS_INC = -I/usr/local/include -I/usr/local/include/tblis 43 | # TBLIS_LIB = -L/usr/local/lib -ltblis 44 | # 45 | # HPTT_INC = -DUSE_HPTT -I/home/xiongjie/CodeDoc/libraries/hptt/src 46 | # HPTT_LIB = -L/home/xiongjie/CodeDoc/libraries/hptt/lib -Wl,-rpath=/home/xiongjie/CodeDoc/libraries/hptt/lib -lhptt 47 | 48 | # File names 49 | EXEC = run 50 | SOURCES = $(wildcard ./main.cpp) 51 | OBJECTS = $(SOURCES:.cpp=.o) 52 | 53 | # Main target 54 | $(EXEC): $(OBJECTS) 55 | $(CC) $(OBJECTS) $(CC_FLAGS) $(TBLIS_LIB) $(HPTT_LIB) $(LAPACK_LIB) $(HDF5_LIB) -o $(EXEC) 56 | 57 | # To obtain object files 58 | %.o: %.cpp 59 | $(CC) -c $(CC_FLAGS) $(TBLIS_INC) $(HPTT_INC) $(LAPACK_INC) $(HDF5_INC) $< -o $@ 60 | 61 | # To remove generated files 62 | clean: 63 | rm -f $(EXEC) $(OBJECTS) 64 | -------------------------------------------------------------------------------- /deprecated-examples/dtensor/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include "../../dtensor/dtensor_index.cpp" 19 | #include "../../dtensor/dtensor_index_op.cpp" 20 | #include "../../dtensor/dtensor.cpp" 21 | #include "../../dtensor/dtensor_view.cpp" 22 | #include "../../dtensor/dtensor_op.cpp" 23 | #include "../../dtensor/big_dtensor.cpp" 24 | #include "../../linalg/lapack_wrapper.cpp" 25 | #include "../../linalg/tensor_cg.cpp" 26 | #include "../../linalg/tensor_davidson.cpp" 27 | #include "../../util/ezh5.cpp" 28 | #include "../../util/timer.h" 29 | int main(int argc, char const *argv[]) { 30 | //------------------------------------------ 31 | std::cout << "Hello Tensor!" << '\n'; 32 | 33 | unsigned s1=100, s2=100; 34 | Eigen::MatrixXd Id(s1,s2); Id.setIdentity(); 35 | Eigen::MatrixXd mA(s1,s2); mA.setRandom(); 36 | Eigen::MatrixXd tp = mA + mA.transpose(); 37 | mA = tp; 38 | Eigen::MatrixXd mB(s1,1); mB.setRandom(); 39 | // std::cout << mA << '\n' << '\n'; 40 | // std::cout << mB.transpose() << '\n' << '\n'; 41 | std::cout << (mA*mB).transpose() << '\n' << '\n'; 42 | std::cout << mB.transpose()*mA*mB << '\n' << '\n'; 43 | std::cout << mA.fullPivLu().solve(mB).transpose() << '\n' << '\n'; 44 | Eigen::SelfAdjointEigenSolver es(mA); 45 | std::cout< A({s1,s2},{"a","a"},{Link,Link},{1,0},mA.data()); 50 | dtensor B({s1},{"a"},{Link},{0},mB.data()); 51 | A.print(); 52 | B.print(); 53 | big_dtensor M; 54 | M.addMid(&A); 55 | dtensor C = M.product(B); 56 | C.print(1); 57 | std::cout << M.expec(B) << '\n'; 58 | C.setRandom(); 59 | tensor_CG(M, C, B, 300, 1e-10, false); 60 | C.print(1); 61 | std::cout << tensor_davidson(M, B, 5, 100, 1e-10, 'S') << '\n'; 62 | B.print(1); 63 | //------------------------------------------ 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /deprecated-examples/dtensor/test.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClarkResearchGroup/tensor-tools/25fe4553991d2680b43301aef1960e4c20f1e146/deprecated-examples/dtensor/test.h5 -------------------------------------------------------------------------------- /deprecated-examples/ezh5/Makefile: -------------------------------------------------------------------------------- 1 | CC = icpc 2 | CC_FLAGS = -O2 -qopenmp -qoverride-limits -xhost -DNDEBUG -std=c++11 -W 3 | 4 | LAPACK_INC = -DMKL_Complex16="std::complex" 5 | LAPACK_LIB = -mkl=parallel 6 | 7 | HDF5_INC = -DUSE_EZH5 -I/usr/local/opt/hdf5/include 8 | HDF5_LIB = -L/usr/local/opt/hdf5/lib -lhdf5 9 | 10 | TBLIS_INC = -DUSE_TBLIS -I/usr/local/include -I/usr/local/include/tblis 11 | TBLIS_LIB = -L/usr/local/lib -ltblis 12 | 13 | HPTT_INC = -DUSE_HPTT -I/Volumes/CoolStuff/MyLibrary/hptt/src 14 | HPTT_LIB = -L/Volumes/CoolStuff/MyLibrary/hptt/lib -lhptt 15 | 16 | 17 | # CC = g++-7 18 | # CC_FLAGS = -O2 -g -march=native -fopenmp -ffast-math -std=c++11 -W 19 | # 20 | # LAPACK_INC = -framework Accelerate 21 | # LAPACK_LIB = -framework Accelerate 22 | # 23 | # HDF5_INC = -DUSE_EZH5 -I/usr/local/opt/hdf5/include 24 | # HDF5_LIB = -L/usr/local/opt/hdf5/lib -lhdf5 25 | # 26 | # TBLIS_INC = -DUSE_TBLIS -I/usr/local/include -I/usr/local/include/tblis 27 | # TBLIS_LIB = -L/usr/local/lib -ltblis 28 | # 29 | # HPTT_INC = -DUSE_HPTT -I/Volumes/CoolStuff/MyLibrary/hptt/src 30 | # HPTT_LIB = -L/Volumes/CoolStuff/MyLibrary/hptt/lib -lhptt 31 | 32 | 33 | # CC = g++ 34 | # CC_FLAGS = -O2 -DNDEBUG -march=native -fopenmp -ffast-math -std=c++11 -W 35 | # 36 | # LAPACK_INC = -I/usr/include/openblas 37 | # LAPACK_LIB = -lpthread -L/usr/lib/openblas-base -lopenblas 38 | # 39 | # HDF5_INC = -DUSE_EZH5 -I/usr/lib/x86_64-linux-gnu/hdf5/serial/include 40 | # HDF5_LIB = -L/usr/lib/x86_64-linux-gnu/hdf5/serial/lib -lhdf5 41 | # 42 | # TBLIS_INC = -I/usr/local/include -I/usr/local/include/tblis 43 | # TBLIS_LIB = -L/usr/local/lib -ltblis 44 | # 45 | # HPTT_INC = -DUSE_HPTT -I/home/xiongjie/CodeDoc/libraries/hptt/src 46 | # HPTT_LIB = -L/home/xiongjie/CodeDoc/libraries/hptt/lib -Wl,-rpath=/home/xiongjie/CodeDoc/libraries/hptt/lib -lhptt 47 | 48 | # File names 49 | EXEC = run 50 | SOURCES = $(wildcard ./main.cpp) 51 | OBJECTS = $(SOURCES:.cpp=.o) 52 | 53 | # Main target 54 | $(EXEC): $(OBJECTS) 55 | $(CC) $(OBJECTS) $(CC_FLAGS) $(TBLIS_LIB) $(HPTT_LIB) $(LAPACK_LIB) $(HDF5_LIB) -o $(EXEC) 56 | 57 | # To obtain object files 58 | %.o: %.cpp 59 | $(CC) -c $(CC_FLAGS) $(TBLIS_INC) $(HPTT_INC) $(LAPACK_INC) $(HDF5_INC) $< -o $@ 60 | 61 | # To remove generated files 62 | clean: 63 | rm -f $(EXEC) $(OBJECTS) 64 | -------------------------------------------------------------------------------- /deprecated-examples/ezh5/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "../../util/ezh5.cpp" 24 | 25 | typedef Eigen::MatrixXd Mxd; 26 | 27 | using namespace std; 28 | 29 | void save_by_handle(ezh5::Node& f, double val){ 30 | f["pi"] = val; 31 | } 32 | 33 | void read_by_handle(ezh5::Node& f, double& val){ 34 | f["pi"] >> val; 35 | } 36 | 37 | int main(int argc, char const *argv[]) { 38 | cout<<"//------------------------------------"<>mode; 50 | //------------------------------------ 51 | string fn1 = "test_stl_vector.h5"; 52 | string fn2 = "test_Eigen3_matrix.h5"; 53 | //------------------------------------ 54 | if (mode == writing_mode) { 55 | cout<<"Please specify vector/matrix size: "; 56 | cin>>N; 57 | //------------------------------------ 58 | cout<<"//------------------------------------"< v(N); 60 | for (int i = 0; i < N; i++) v[i] = drand48(); 61 | cout<<"Random vector of length "< v; 85 | ezh5::File f1 (fn1, H5F_ACC_RDONLY); 86 | f1["my_random_vector"] >> v; 87 | for(auto val : v) cout<> M; 99 | cout<" 5 | # LAPACK_LIB = -mkl=parallel 6 | # 7 | # HDF5_INC = -DUSE_EZH5 -I/usr/local/opt/hdf5/include 8 | # HDF5_LIB = -L/usr/local/opt/hdf5/lib -lhdf5 9 | # 10 | # TBLIS_INC = -DUSE_TBLIS -I/usr/local/include -I/usr/local/include/tblis 11 | # TBLIS_LIB = -L/usr/local/lib -ltblis 12 | # 13 | # HPTT_INC = -DUSE_HPTT -I/Volumes/CoolStuff/MyLibrary/hptt/src 14 | # HPTT_LIB = -L/Volumes/CoolStuff/MyLibrary/hptt/lib -lhptt 15 | 16 | 17 | # CC = g++-7 18 | # CC_FLAGS = -O2 -g -march=native -fopenmp -ffast-math -std=c++11 -W 19 | # 20 | # LAPACK_INC = -framework Accelerate 21 | # LAPACK_LIB = -framework Accelerate 22 | # 23 | # HDF5_INC = -DUSE_EZH5 -I/usr/local/opt/hdf5/include 24 | # HDF5_LIB = -L/usr/local/opt/hdf5/lib -lhdf5 25 | # 26 | # TBLIS_INC = -DUSE_TBLIS -I/usr/local/include -I/usr/local/include/tblis 27 | # TBLIS_LIB = -L/usr/local/lib -ltblis 28 | # 29 | # HPTT_INC = -DUSE_HPTT -I/Volumes/CoolStuff/MyLibrary/hptt/src 30 | # HPTT_LIB = -L/Volumes/CoolStuff/MyLibrary/hptt/lib -lhptt 31 | 32 | 33 | CC = g++ 34 | CC_FLAGS = -O2 -DNDEBUG -march=native -fopenmp -ffast-math -std=c++11 -W 35 | 36 | LAPACK_INC = -I/usr/include/openblas 37 | LAPACK_LIB = -lpthread -L/usr/lib/openblas-base -lopenblas 38 | 39 | HDF5_INC = -DUSE_EZH5 -I/usr/lib/x86_64-linux-gnu/hdf5/serial/include 40 | HDF5_LIB = -L/usr/lib/x86_64-linux-gnu/hdf5/serial/lib -lhdf5 41 | 42 | TBLIS_INC = -I/usr/local/include -I/usr/local/include/tblis 43 | TBLIS_LIB = -L/usr/local/lib -ltblis 44 | 45 | HPTT_INC = -DUSE_HPTT -I/home/xiongjie/CodeDoc/libraries/hptt/src 46 | HPTT_LIB = -L/home/xiongjie/CodeDoc/libraries/hptt/lib -Wl,-rpath=/home/xiongjie/CodeDoc/libraries/hptt/lib -lhptt 47 | 48 | # File names 49 | EXEC = run 50 | SOURCES = $(wildcard ./main.cpp) 51 | OBJECTS = $(SOURCES:.cpp=.o) 52 | 53 | # Main target 54 | $(EXEC): $(OBJECTS) 55 | $(CC) $(OBJECTS) $(CC_FLAGS) $(TBLIS_LIB) $(HPTT_LIB) $(LAPACK_LIB) $(HDF5_LIB) -o $(EXEC) 56 | 57 | # To obtain object files 58 | %.o: %.cpp 59 | $(CC) -c $(CC_FLAGS) $(TBLIS_INC) $(HPTT_INC) $(LAPACK_INC) $(HDF5_INC) $< -o $@ 60 | 61 | # To remove generated files 62 | clean: 63 | rm -f $(EXEC) $(OBJECTS) 64 | -------------------------------------------------------------------------------- /deprecated-examples/tblis/Makefile: -------------------------------------------------------------------------------- 1 | # CC = icpc 2 | # CC_FLAGS = -O2 -qopenmp -qoverride-limits -xhost -DNDEBUG -std=c++11 -W 3 | # 4 | # LAPACK_INC = -DMKL_Complex16="std::complex" 5 | # LAPACK_LIB = -mkl=parallel 6 | # 7 | # HDF5_INC = -DUSE_EZH5 -I/usr/local/opt/hdf5/include 8 | # HDF5_LIB = -L/usr/local/opt/hdf5/lib -lhdf5 9 | # 10 | # TBLIS_INC = -DUSE_TBLIS -I/usr/local/include -I/usr/local/include/tblis 11 | # TBLIS_LIB = -L/usr/local/lib -ltblis 12 | # 13 | # HPTT_INC = -DUSE_HPTT -I/Volumes/CoolStuff/MyLibrary/hptt/src 14 | # HPTT_LIB = -L/Volumes/CoolStuff/MyLibrary/hptt/lib -lhptt 15 | 16 | 17 | # CC = g++-7 18 | # CC_FLAGS = -O2 -g -march=native -fopenmp -ffast-math -std=c++11 -W 19 | # 20 | # LAPACK_INC = -framework Accelerate 21 | # LAPACK_LIB = -framework Accelerate 22 | # 23 | # HDF5_INC = -DUSE_EZH5 -I/usr/local/opt/hdf5/include 24 | # HDF5_LIB = -L/usr/local/opt/hdf5/lib -lhdf5 25 | # 26 | # TBLIS_INC = -DUSE_TBLIS -I/usr/local/include -I/usr/local/include/tblis 27 | # TBLIS_LIB = -L/usr/local/lib -ltblis 28 | # 29 | # HPTT_INC = -DUSE_HPTT -I/Volumes/CoolStuff/MyLibrary/hptt/src 30 | # HPTT_LIB = -L/Volumes/CoolStuff/MyLibrary/hptt/lib -lhptt 31 | 32 | 33 | CC = g++ 34 | CC_FLAGS = -O2 -DNDEBUG -march=native -fopenmp -ffast-math -std=c++11 -W 35 | 36 | LAPACK_INC = -I/usr/include/openblas 37 | LAPACK_LIB = -lpthread -L/usr/lib/openblas-base -lopenblas 38 | 39 | HDF5_INC = -DUSE_EZH5 -I/usr/lib/x86_64-linux-gnu/hdf5/serial/include 40 | HDF5_LIB = -L/usr/lib/x86_64-linux-gnu/hdf5/serial/lib -lhdf5 41 | 42 | TBLIS_INC = -I/usr/local/include -I/usr/local/include/tblis 43 | TBLIS_LIB = -L/usr/local/lib -ltblis 44 | 45 | HPTT_INC = -DUSE_HPTT -I/home/xiongjie/CodeDoc/libraries/hptt/src 46 | HPTT_LIB = -L/home/xiongjie/CodeDoc/libraries/hptt/lib -Wl,-rpath=/home/xiongjie/CodeDoc/libraries/hptt/lib -lhptt 47 | 48 | # File names 49 | EXEC = run 50 | SOURCES = $(wildcard ./main.cpp) 51 | OBJECTS = $(SOURCES:.cpp=.o) 52 | 53 | # Main target 54 | $(EXEC): $(OBJECTS) 55 | $(CC) $(OBJECTS) $(CC_FLAGS) $(TBLIS_LIB) $(HPTT_LIB) $(LAPACK_LIB) $(HDF5_LIB) -o $(EXEC) 56 | 57 | # To obtain object files 58 | %.o: %.cpp 59 | $(CC) -c $(CC_FLAGS) $(TBLIS_INC) $(HPTT_INC) $(LAPACK_INC) $(HDF5_INC) $< -o $@ 60 | 61 | # To remove generated files 62 | clean: 63 | rm -f $(EXEC) $(OBJECTS) 64 | -------------------------------------------------------------------------------- /deprecated-examples/tblis/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "tblis.h" 23 | 24 | int main(int argc, char const *argv[]) { 25 | int s1=2, s2=3, s3=4; 26 | Eigen::MatrixXcd mA(s1,s2); 27 | mA.setRandom(); 28 | Eigen::MatrixXcd mB(s2,s3); 29 | mB.setRandom(); 30 | Eigen::MatrixXcd mC(s1,s3); 31 | mC.setRandom(); 32 | std::cout << "/-------------------------------------------------/" << '\n'; 33 | std::cout << "Matrix mA:" << '\n'; 34 | std::cout << mA << '\n' << '\n'; 35 | std::cout << "Matrix mB:" << '\n'; 36 | std::cout << mB << '\n' << '\n'; 37 | std::cout << "Matrix mA*mB+mC:" << '\n'; 38 | std::cout << mA*mB+mC << '\n' << '\n'; 39 | std::cout << "/-------------------------------------------------/" << '\n'; 40 | 41 | tblis::tensor_view< std::complex > A({s1,s2}, mA.data()); 42 | tblis::tensor_view< std::complex > B({s2,s3}, mB.data()); 43 | tblis::tensor_view< std::complex > C({s1,s3}, mC.data()); 44 | 45 | tblis::mult(std::complex(1.0),A,"ab",B,"bc",std::complex(1.0),C,"ac"); 46 | 47 | std::cout << "tblis results:" << '\n'; 48 | std::cout << mC << '\n' << '\n'; 49 | 50 | std::cout << "/-------------------------------------------------/" << '\n'; 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /dtensor/big_dtensor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef BIG_DENSE_TENSOR_CLASS 19 | #define BIG_DENSE_TENSOR_CLASS 20 | 21 | #include "big_dtensor.h" 22 | 23 | template 24 | dtensor big_dtensor::product(dtensor& v){ 25 | //assert(1==2); 26 | // contract pattern: 27 | // L-v-mid-R 28 | 29 | dtensor res; 30 | if(L!=nullptr) res = std::move((*L)*v); 31 | for(auto m : mid){ 32 | if(res.rank>0) 33 | res = std::move(res*(*m)); 34 | else 35 | res = std::move(v*(*m)); 36 | } 37 | if(R!=nullptr) res = std::move(res*(*R)); 38 | res.prime(-1); 39 | 40 | return res; 41 | } 42 | template dtensor big_dtensor::product(dtensor& v); 43 | template dtensor< std::complex > big_dtensor< std::complex >::product(dtensor< std::complex >& v); 44 | 45 | /*template 46 | dtensor big_dtensor::product(dtensor_view& v){ 47 | assert(1==2); 48 | // contract pattern: 49 | // L-v-mid-R 50 | dtensor res; 51 | if(L!=nullptr) res = std::move((*L)*v); 52 | for(auto m : mid){ 53 | if(res.rank>0) 54 | res = std::move(res*(*m)); 55 | else 56 | res = std::move(v*(*m)); 57 | } 58 | if(R!=nullptr) res = std::move(res*(*R)); 59 | res.prime(-1); 60 | return res; 61 | } 62 | template dtensor big_dtensor::product(dtensor_view& v); 63 | template dtensor< std::complex > big_dtensor< std::complex >::product(dtensor_view< std::complex >& v);*/ 64 | 65 | template 66 | T big_dtensor::expec(dtensor& v){ 67 | // contract pattern: 68 | // L-v-mid-R 69 | /*dtensor res; 70 | if(L!=nullptr) res = std::move((*L)*v); 71 | for(auto m : mid){ 72 | if(res.rank>0) 73 | res = std::move(res*(*m)); 74 | else 75 | res = std::move(v*(*m)); 76 | } 77 | if(R!=nullptr) res = std::move(res*(*R)); 78 | res.prime(-1);*/ 79 | dtensor res = std::move(product(v)); 80 | return res.contract(v); 81 | } 82 | template double big_dtensor::expec(dtensor& v); 83 | template std::complex big_dtensor< std::complex >::expec(dtensor< std::complex >& v); 84 | 85 | /*template 86 | T big_dtensor::expec(dtensor_view& v){ 87 | assert(1==2); 88 | // contract pattern: 89 | // L-v-mid-R 90 | dtensor res; 91 | if(L!=nullptr) res = std::move((*L)*v); 92 | for(auto m : mid){ 93 | if(res.rank>0) 94 | res = std::move(res*(*m)); 95 | else 96 | res = std::move(v*(*m)); 97 | } 98 | if(R!=nullptr) res = std::move(res*(*R)); 99 | res.prime(-1); 100 | v.conj(); 101 | T ans = res.contract(v); 102 | v.conj(); 103 | return ans; 104 | } 105 | template double big_dtensor::expec(dtensor_view& v); 106 | template std::complex big_dtensor< std::complex >::expec(dtensor_view< std::complex >& v);*/ 107 | 108 | template 109 | dtensor big_dtensor::diagonal(){ 110 | 111 | // assert(1==2); 112 | dtensor res; 113 | // if(L!=nullptr) (*L).print(); 114 | if(L!=nullptr) res = std::move((*L).diagonal(Link)); 115 | for(auto m : mid){ 116 | dtensor dm = m->diagonal(Site); 117 | res = std::move(res*dm); 118 | } 119 | //res = std::move(res.diagonal(Site)); 120 | // if(R!=nullptr) (*R).print(); 121 | if(R!=nullptr){ 122 | dtensor dR = R->diagonal(Link); 123 | res = std::move(res*dR); 124 | } 125 | //res = std::move(res.diagonal(Link)); 126 | 127 | return res; 128 | } 129 | template dtensor big_dtensor::diagonal(); 130 | template dtensor< std::complex > big_dtensor< std::complex >::diagonal(); 131 | 132 | 133 | template 134 | size_t big_dtensor::size() const{ 135 | if(size_ == 0){ 136 | size_ = 1; 137 | if(L!=nullptr){ 138 | for(unsigned l=0; l< L->rank; l++){ 139 | if(L->idx_set[l].level() > 0) 140 | size_ *= L->idx_set[l].size(); 141 | } 142 | } 143 | if(R!=nullptr){ 144 | for(unsigned l=0; l< R->rank; l++){ 145 | if(R->idx_set[l].level() > 0) 146 | size_ *= R->idx_set[l].size(); 147 | } 148 | } 149 | } 150 | /*for(int l=0;lrank;l++){ 156 | if(m->idx_set[l].type() == Site) 157 | size_*= m->idx_set[l].size(); 158 | } 159 | } 160 | return size_; 161 | } 162 | 163 | template size_t big_dtensor::size() const; 164 | template size_t big_dtensor< std::complex >::size() const; 165 | #endif 166 | -------------------------------------------------------------------------------- /dtensor/big_dtensor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef BIG_DENSE_TENSOR_CLASS_HEADER 19 | #define BIG_DENSE_TENSOR_CLASS_HEADER 20 | 21 | #include "dtensor.h" 22 | //#include "dtensor_view.h" 23 | 24 | /* 25 | Big dtensor class: 26 | 1. Purpose: 27 | Assume we need to multiply a tensor structure (composed of several tensors, 28 | say, A*B*C*D) by some other tensors (E_i, i=1,2,3,...) for a lot of times, 29 | like in any iterative solver, where A*B*C*D are identified as a "matrix". 30 | Often it happens that contracting A*B*C*D into a single tensor is very costly, 31 | probably due to its large tensor rank. And often we would be better off 32 | doing A*B*E_i*C*D, because contracting E_i in the middle makes the tensor rank 33 | small throughout the process. 34 | 35 | So, in some situation, we do not want to contract A,B,C,D first. But in order 36 | to make the the solver code more coherent, it is helpful to hold them in a 37 | single object that we can identify as a "matrix". Then we can use it to perform 38 | "matrix-vector" multiplication in the old style. 39 | big_dtensor class is designed exactly to fullfill this purpose. 40 | 41 | "matrix", when contracted, must produce indices in pairs of prime levels 42 | of 0 and 1. 43 | 44 | 2. Usage: 45 | The big_tensor class provides a uniform interface for performing the following 46 | operations: 47 | 48 | |-- --| 49 | | | | 50 | y = L--mid--R 51 | | | | 52 | |-- x --| 53 | 54 | where effectively, our "matrix" A is of the structure 55 | 56 | |-- --| 57 | | | | 58 | A = L--mid--R 59 | | | | 60 | |-- --| 61 | 62 | Special case: 63 | L and R are initialized to be nullptrs. When not set, they are effectively 64 | 1 (scalar). 65 | 66 | */ 67 | 68 | template 69 | class big_dtensor{ 70 | public: 71 | big_dtensor(){ 72 | L=nullptr; 73 | R=nullptr; 74 | size_=0; 75 | } 76 | ~big_dtensor(){} 77 | 78 | void setLeft(dtensor* Left) {L=Left;} 79 | void setRight(dtensor* Right) {R=Right;} 80 | void addMid(dtensor* m) {mid.push_back(m);} 81 | 82 | dtensor product(dtensor& v); 83 | //dtensor product(dtensor_view& v); 84 | 85 | dtensor diagonal(); // does not include bias term 86 | 87 | T expec(dtensor& v); 88 | //T expec(dtensor_view& v); 89 | size_t size() const; 90 | 91 | private: 92 | // Left/Right environment 93 | dtensor* L; 94 | dtensor* R; 95 | // Ops between L and R 96 | vector< dtensor* > mid; 97 | mutable size_t size_; 98 | }; 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /dtensor/dtensor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef DENSE_TENSOR_CLASS_HEADER 19 | #define DENSE_TENSOR_CLASS_HEADER 20 | 21 | #include "../util/types_and_headers.h" 22 | #include "../util/ezh5.h" 23 | #include "dtensor_index.h" 24 | #include "dtensor_index_op.h" 25 | //#include "dtensor_view.h" 26 | #include 27 | 28 | string indToStr(vector &indices,unordered_map &charMap); 29 | string indicesToChar(vector &indices, unordered_map &charMap); 30 | unsigned indicesToSize(vector &indices); 31 | 32 | /* 33 | Design of the templated dtensor class: 34 | 35 | (1) dtensor's underlying storage and algorithms are provided 36 | by TBLIS. 37 | TBLIS is a library and framework for performing tensor operations, 38 | especially tensor contraction, using efficient native algorithms. 39 | https://github.com/devinamatthews/tblis 40 | 41 | (2) Tensor ordering scheme 42 | dtensor's elements are basically stored in an (hidden) array contiguous in memory. 43 | Assume that we label the elements of a rank-4 dtensor as T(i1,i2,i3,i4), 44 | where i1 \in [0,s1), i2 \in [0,s2), i3 \in [0,s3), i4 \in [0,s4). 45 | When first index i1 increases by 1, the tensor element moves to the next 1 46 | in the underlying array, so i1 has stride 1. 47 | Similarly, i2 has stride s1, i3 has stride s1*s2, i4 has stride s1*s2*s3. 48 | 49 | (3) Tensor multiplication 50 | operator * assumes Einstein summation rule, with one caveat. 51 | Normally, we would only sum over an index if it is repeated 2 times. 52 | And we would frown at an expression where an index is repeated more than 2 times, 53 | treating it as a mistake. 54 | However, under the current implementation, summation is applied even if an index 55 | is repeated more than 2 times. 56 | 57 | (3) When performing dtensor contraction, Einstein summation rule is assumed. 58 | Repeated indices will be summed over. 59 | */ 60 | 61 | template class dtensor_view; 62 | 63 | 64 | template 65 | class dtensor{ 66 | public: 67 | //--------------------------------------------------------------------------- 68 | // Constructors 69 | dtensor(); // default constructor 70 | dtensor(uint_list idx_sizes); // given idx_sizes, random names, default to type Link 71 | dtensor(uint_vec& idx_sizes); // given idx_sizes, random names, default to type Link 72 | dtensor(uint_list idx_sizes, str_list names); // given idx_sizes and names, default to type Link 73 | dtensor(uint_vec& idx_sizes, str_vec& names); // given idx_sizes and names, default to type Link 74 | dtensor(uint_list idx_sizes, str_list names, typ_list types); // given idx_sizes, names, and types 75 | dtensor(uint_vec& idx_sizes, str_vec& names, typ_vec& types); // given idx_sizes, names, and types 76 | dtensor(uint_list idx_sizes, str_list names, typ_list types, uint_list levels); // given idx_sizes, names, types, levels 77 | dtensor(uint_vec& idx_sizes, str_vec& names, typ_vec& types, uint_vec& levels); // given idx_sizes, names, types, levels 78 | dtensor(uint_list idx_sizes, str_list names, typ_list types, uint_list levels, T* data_array); // given idx_sizes, names, types, levels, data 79 | dtensor(uint_vec& idx_sizes, str_vec& names, typ_vec& types, uint_vec& levels, T* data_array); // given idx_sizes, names, types, levels, data 80 | dtensor(vector& idx_vec); 81 | dtensor(initializer_list idx_list); 82 | dtensor(vector& idx_vec, T* data_array); 83 | dtensor(vector& idx_vec, CTF::Tensor& data_array); 84 | dtensor(const dtensor& other); // copy constructor 85 | //dtensor(const dtensor_view& other); // copy constructor 86 | dtensor(dtensor&& other); // move constructor 87 | //--------------------------------------------------------------------------- 88 | // Destructor 89 | ~dtensor(){} 90 | //--------------------------------------------------------------------------- 91 | // Reset 92 | void reset(vector& idx_vec, bool makeZero=true); 93 | //--------------------------------------------------------------------------- 94 | // Resize indices 95 | // (data preserved when dimension of indices lowered, filled with val when enlarged) 96 | void resize(uint_vec& new_sizes, T val=T()); 97 | void resize(uint_list new_sizes, T val=T()); 98 | void resize(vector& new_idx_set, T val=T()); 99 | 100 | //--------------------------------------------------------------------------- 101 | // Storage 102 | unsigned size; // total size (number of elements) of the tensor 103 | unsigned rank; // number of indices 104 | vector idx_set; // full set of tensor indices (dtensor_index.h) 105 | //tblis::tensor _T; // tblis::tensor_view, provide tensor functionality (does not own data) 106 | CTF::Tensor __T; 107 | bool _initted; // initilization flag 108 | 109 | //--------------------------------------------------------------------------- 110 | // Initializer 111 | void setRandom(); 112 | void setZero(); 113 | void setOne(); 114 | 115 | //--------------------------------------------------------------------------- 116 | // Permutate 117 | void permute(uint_vec& perm); 118 | void permute(uint_list perm); 119 | 120 | //--------------------------------------------------------------------------- 121 | // Overloaded operator 122 | dtensor& operator = (const dtensor& other); // copy assignment 123 | //dtensor& operator = (const dtensor_view& other); // copy assignment 124 | dtensor& operator = (dtensor&& other); // move assignment 125 | dtensor operator * (dtensor& A); // repeated indices are summed over 126 | //dtensor operator * (dtensor_view& A); // repeated indices are summed over 127 | dtensor& operator += (dtensor& A); // 128 | //dtensor& operator += (dtensor_view& A); // 129 | dtensor& operator -= (dtensor& A); // 130 | //dtensor& operator -= (dtensor_view& A); // 131 | dtensor operator + (dtensor& A); // 132 | //dtensor operator + (dtensor_view& A); // 133 | dtensor operator - (dtensor& A); // 134 | //dtensor operator - (dtensor_view& A); // 135 | dtensor& operator *= (const T c); // scaling 136 | dtensor& operator /= (const T c); // scaling 137 | dtensor operator * (const T c); // scaling 138 | dtensor operator / (const T c); // scaling 139 | 140 | //--------------------------------------------------------------------------- 141 | // Full contraction (ends in a scalar) 142 | T contract(dtensor& A); 143 | //T contract(dtensor_view& A); 144 | 145 | //--------------------------------------------------------------------------- 146 | // Get diagonal subtensor 147 | // only possible when tensor indices come in "pairs", 148 | // meaning same name string but different prime level 149 | //dtensor diagonal(); 150 | dtensor diagonal(index_type type=All); 151 | 152 | //--------------------------------------------------------------------------- 153 | // Prime level manipulation 154 | void prime(int inc=1); 155 | void primeLink(int inc=1); 156 | void primeSite(int inc=1); 157 | void mapPrime(unsigned from, unsigned to); 158 | void mapPrime(unsigned from, unsigned to, index_type type); 159 | 160 | void dag(){}; 161 | void conj(); 162 | 163 | //--------------------------------------------------------------------------- 164 | // Save/Load 165 | void save(string fn); 166 | void load(string fn); 167 | void save(ezh5::Node& fW); 168 | void load(ezh5::Node& fR); 169 | 170 | //--------------------------------------------------------------------------- 171 | // Get norm 172 | double norm(); 173 | double normalize(); 174 | 175 | //--------------------------------------------------------------------------- 176 | // special arithmetic operations with another tensor in the same format/pattern 177 | void add(dtensor& A, T c = T(1)); 178 | T inner_product(dtensor& A); 179 | 180 | //--------------------------------------------------------------------------- 181 | // Print 182 | void print(unsigned print_level=0); 183 | 184 | //--------------------------------------------------------------------------- 185 | // index functions for CTF 186 | string getIndices(); //prints string based on rank 187 | string getIndices(unordered_map &charMap); 188 | 189 | private: 190 | string _indices; 191 | 192 | }; 193 | 194 | //Calculate Entanglement Entropy from a rank 1 CTF tensor 195 | 196 | template 197 | double calcEntropy(dtensor& S, double cutoff=1e-24){ 198 | assert(S.rank==1); assert(S._initted==true); 199 | CTF::Scalar vNEE = 0.0; 200 | vNEE[""] += CTF::Function([cutoff](T sg){ if(real(sg)>cutoff) return -norm(sg)*std::log(norm(sg)); else return 0.0; })(S.__T["i"]); 201 | return vNEE; 202 | } 203 | #endif 204 | -------------------------------------------------------------------------------- /dtensor/dtensor_all.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef ALL_DTENSOR_RELATED_HEADERS 19 | #define ALL_DTENSOR_RELATED_HEADERS 20 | 21 | #include "dtensor_index.h" 22 | #include "dtensor_index_op.h" 23 | #include "dtensor.h" 24 | //#include "dtensor_view.h" 25 | #include "dtensor_op.h" 26 | #include "big_dtensor.h" 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /dtensor/dtensor_index.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef INDEX_CLASS_FOR_DENSE_TENSOR 19 | #define INDEX_CLASS_FOR_DENSE_TENSOR 20 | 21 | #include "dtensor_index.h" 22 | 23 | dtensor_index::dtensor_index(){ 24 | _size = 1; 25 | _level = 0; 26 | _name = "i"+to_string(int(1e8*thread_safe_random_double()+1e6*thread_safe_random_double())); 27 | _type = Link; 28 | setTag(); 29 | } 30 | 31 | dtensor_index::dtensor_index(int64_t size){ 32 | _size = size; 33 | _level = 0; 34 | _name = "i"+to_string(int(1e8*thread_safe_random_double()+1e5*thread_safe_random_double())); 35 | _type = Link; 36 | setTag(); 37 | } 38 | 39 | dtensor_index::dtensor_index(int64_t size, string name){ 40 | _size = size; 41 | _level = 0; 42 | _name = name; 43 | _type = Link; 44 | setTag(); 45 | } 46 | 47 | dtensor_index::dtensor_index(int64_t size, string name, index_type type){ 48 | _size = size; 49 | _level = 0; 50 | _name = name; 51 | _type = type; 52 | setTag(); 53 | } 54 | 55 | dtensor_index::dtensor_index(int64_t size, string name, index_type type, unsigned level){ 56 | _size = size; 57 | _level = level; 58 | _name = name; 59 | _type = type; 60 | setTag(); 61 | } 62 | 63 | dtensor_index::dtensor_index(const dtensor_index& other){ 64 | _size = other._size; 65 | _level = other._level; 66 | _name = other._name; 67 | _type = other._type; 68 | _tag = other._tag; 69 | } 70 | 71 | dtensor_index dtensor_index::operator = (const dtensor_index& other){ 72 | if(this!=&other){ 73 | _size = other._size; 74 | _level = other._level; 75 | _name = other._name; 76 | _type = other._type; 77 | _tag = other._tag; 78 | } 79 | return *this; 80 | } 81 | 82 | bool dtensor_index::operator == (const dtensor_index& A) const{ 83 | // return (_size==A._size)&&(_name==A._name)&&(_type==A._type)&&(_level==A._level); 84 | return (_tag==A._tag && _level==A._level); 85 | } 86 | 87 | bool dtensor_index::operator != (const dtensor_index& A) const{ 88 | // return (_size!=A._size)||(_name!=A._name)||(_type!=A._type)||(_level!=A._level); 89 | return (_tag!=A._tag || _level!=A._level); 90 | } 91 | 92 | bool dtensor_index::operator < (const dtensor_index& A) const{ 93 | //return (_tag& from, vector& to, vector& perm){ 24 | assert(from.size()==to.size()); 25 | if(perm.size()>0) perm.clear(); 26 | // brute force O(n^2) 27 | int n = to.size(); 28 | for (int i = 0; i < n; i++) { 29 | for (int j = 0; j < n; j++) { 30 | if(to[i] == from[j]){ 31 | perm.push_back(j); 32 | break; 33 | } 34 | } 35 | } 36 | assert(int(perm.size())==n); 37 | } 38 | 39 | void index_sets_union(const vector& Ac, const vector& Bc, vector& res){ 40 | res.resize(Ac.size()+Bc.size()); 41 | vector::iterator it; 42 | vector A(Ac.begin(), Ac.end()); 43 | vector B(Bc.begin(), Bc.end()); 44 | std::sort(A.begin(), A.end()); 45 | std::sort(B.begin(), B.end()); 46 | // make sure indices are unique 47 | it = std::unique (A.begin(), A.end()); 48 | A.resize(std::distance(A.begin(),it)); 49 | it = std::unique (B.begin(), B.end()); 50 | B.resize(std::distance(B.begin(),it)); 51 | it = std::set_union(A.begin(), A.end(), B.begin(), B.end(), res.begin()); 52 | res.resize(it-res.begin()); 53 | } 54 | 55 | void index_sets_difference(const vector& Ac, const vector& Bc, vector& res){ 56 | vector::iterator it; 57 | vector A(Ac.begin(), Ac.end()); 58 | vector B(Bc.begin(), Bc.end()); 59 | // make sure indices are unique 60 | it = std::unique (A.begin(), A.end()); 61 | A.resize(std::distance(A.begin(),it)); 62 | it = std::unique (B.begin(), B.end()); 63 | B.resize(std::distance(B.begin(),it)); 64 | res.clear(); 65 | for (size_t i = 0; i < A.size(); i++) { 66 | bool duplicated = false; 67 | for (size_t j = 0; j < B.size(); j++) { 68 | if(A[i]==B[j]){ 69 | duplicated = true; 70 | break; 71 | } 72 | } 73 | if(!duplicated){ 74 | res.push_back(A[i]); 75 | } 76 | } 77 | for (size_t i = 0; i < B.size(); i++) { 78 | bool duplicated = false; 79 | for (size_t j = 0; j < A.size(); j++) { 80 | if(B[i]==A[j]){ 81 | duplicated = true; 82 | break; 83 | } 84 | } 85 | if(!duplicated){ 86 | res.push_back(B[i]); 87 | } 88 | } 89 | } 90 | 91 | void index_sets_intersection(const vector& Ac, const vector& Bc, vector& res){ 92 | vector::iterator it; 93 | vector A(Ac.begin(), Ac.end()); 94 | vector B(Bc.begin(), Bc.end()); 95 | std::sort(A.begin(), A.end()); 96 | std::sort(B.begin(), B.end()); 97 | // make sure indices are unique 98 | it = std::unique (A.begin(), A.end()); 99 | A.resize(std::distance(A.begin(),it)); 100 | it = std::unique (B.begin(), B.end()); 101 | B.resize(std::distance(B.begin(),it)); 102 | res.resize(Ac.size()+Bc.size()); 103 | it = std::set_intersection(A.begin(), A.end(), B.begin(), B.end(), res.begin()); 104 | res.resize(it-res.begin()); 105 | } 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /dtensor/dtensor_index_op.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef INDEX_OP_CLASS_FOR_DENSE_TENSOR_HEADER 19 | #define INDEX_OP_CLASS_FOR_DENSE_TENSOR_HEADER 20 | 21 | #include "dtensor_index.h" 22 | 23 | void find_index_permutation(vector& from, vector& to, vector& perm); 24 | 25 | void index_sets_union(const vector& Ac, const vector& Bc, vector& res); 26 | 27 | void index_sets_difference(const vector& Ac, const vector& Bc, vector& res); 28 | 29 | void index_sets_intersection(const vector& Ac, const vector& Bc, vector& res); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /dtensor/dtensor_op.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef DENSE_TENSOR_OPERATIONS_HEADER 19 | #define DENSE_TENSOR_OPERATIONS_HEADER 20 | 21 | #include "../util/types_and_headers.h" 22 | #include "../linalg/lapack_wrapper.h" 23 | #include "dtensor_index.h" 24 | #include "dtensor_index_op.h" 25 | #include "dtensor.h" 26 | //#include "dtensor_view.h" 27 | 28 | string indToStr(vector &indices,unordered_map &charMap); 29 | string indicesToChar(vector &indices, unordered_map &charMap); 30 | unsigned indicesToSize(vector &indices); 31 | 32 | template 33 | void qr(dtensor& A, 34 | vector& left, vector& right, 35 | dtensor& Q, dtensor& R); 36 | 37 | /*template 38 | void qr(dtensor_view& A, 39 | vector& left, vector& right, 40 | dtensor& Q, dtensor& R);*/ 41 | 42 | /*template 43 | void svd(dtensor& A, 44 | vector& left, vector& right, 45 | dtensor& U, dtensor& V, vector& S, 46 | int direction); 47 | 48 | template 49 | void svd(dtensor& A, 50 | vector& left, 51 | vector& right, 52 | dtensor& U, dtensor& V, dtensor& S, 53 | int direction);*/ 54 | 55 | /*template 56 | void svd(dtensor_view& A, 57 | vector& left, vector& right, 58 | dtensor& U, dtensor& V, vector& S, 59 | int direction);*/ 60 | 61 | /*template 62 | void svd(dtensor& A, 63 | vector& left, vector& right, 64 | dtensor& U, dtensor& V, vector& S, 65 | int direction, double cutoff);*/ 66 | 67 | /*template 68 | void svd(dtensor_view& A, 69 | vector& left, vector& right, 70 | dtensor& U, dtensor& V, vector& S, 71 | int direction, double cutoff);*/ 72 | 73 | template 74 | void svd(dtensor& A, 75 | vector& left, vector& right, 76 | dtensor& U, dtensor& V, vector& S, 77 | int direction, double cutoff=0, long unsigned K=0); 78 | 79 | /*template 80 | void svd(dtensor_view& A, 81 | vector& left, vector& right, 82 | dtensor& U, dtensor& V, vector& S, 83 | int direction, double cutoff, long unsigned K);*/ 84 | 85 | template 86 | void svd(dtensor& A, 87 | vector& left, 88 | vector& right, 89 | dtensor& U, dtensor& V, dtensor& S, 90 | int direction,double cutoff=0, long unsigned K=0); 91 | 92 | /*template 93 | void svd_bond(dtensor& A_left, dtensor& A_right, 94 | dtensor_index& mid, vector& S, 95 | int direction);*/ 96 | 97 | /*template 98 | void svd_bond(dtensor_view& A_left, dtensor_view& A_right, 99 | dtensor_index& mid, vector& S, 100 | int direction);*/ 101 | 102 | template 103 | void svd_bond(dtensor& A_left, dtensor& A_right, 104 | dtensor_index& mid, vector& S, 105 | int direction, double cutoff=0, long unsigned K=0); 106 | 107 | template 108 | void svd_bond(dtensor& combined, dtensor& A_left, dtensor& A_right, 109 | dtensor_index& mid, dtensor& S, 110 | int direction, double cutoff=0, long unsigned K=0); 111 | 112 | /*template 113 | void svd_bond(dtensor_view& A_left, dtensor_view& A_right, 114 | dtensor_index& mid, vector& S, 115 | int direction, double cutoff, long unsigned K);*/ 116 | 117 | template 118 | void svd_bond(dtensor& combined, dtensor& A_left, dtensor& A_right, 119 | dtensor_index& mid, vector& S, 120 | int direction, double cutoff=0, long unsigned K=0); 121 | 122 | /*template 123 | void svd_bond(dtensor& combined, dtensor_view& A_left, dtensor_view& A_right, 124 | dtensor_index& mid, vector& S, 125 | int direction, double cutoff, long unsigned K);*/ 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /dtensor/tensor_index.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef INDEX_CLASS_FOR_DENSE_TENSOR 19 | #define INDEX_CLASS_FOR_DENSE_TENSOR 20 | 21 | #include "tensor_index.h" 22 | 23 | tensor_index::tensor_index(unsigned size){ 24 | _size = size; 25 | _level = 0; 26 | _name = "i"+to_string(int(1e8*drand48()+1e5*drand48())); 27 | _type = Link; 28 | _tag = to_string(_size)+" "+_name+" "+to_string(_type)+" "+to_string(_level); 29 | } 30 | 31 | tensor_index::tensor_index(unsigned size, string name){ 32 | _size = size; 33 | _level = 0; 34 | _name = name; 35 | _type = Link; 36 | _tag = to_string(_size)+" "+_name+" "+to_string(_type)+" "+to_string(_level); 37 | } 38 | 39 | tensor_index::tensor_index(unsigned size, string name, index_type type){ 40 | _size = size; 41 | _level = 0; 42 | _name = name; 43 | _type = type; 44 | _tag = to_string(_size)+" "+_name+" "+to_string(_type)+" "+to_string(_level); 45 | } 46 | 47 | tensor_index::tensor_index(unsigned size, string name, index_type type, unsigned level){ 48 | _size = size; 49 | _level = level; 50 | _name = name; 51 | _type = type; 52 | _tag = to_string(_size)+" "+_name+" "+to_string(_type)+" "+to_string(_level); 53 | } 54 | 55 | tensor_index::tensor_index(const tensor_index& other){ 56 | _size = other._size; 57 | _level = other._level; 58 | _name = other._name; 59 | _type = other._type; 60 | _tag = other._tag; 61 | } 62 | 63 | bool tensor_index::operator == (const tensor_index& A) const{ 64 | // return (_size==A._size)&&(_name==A._name)&&(_type==A._type)&&(_level==A._level); 65 | return (_tag==A._tag); 66 | } 67 | 68 | bool tensor_index::operator != (const tensor_index& A) const{ 69 | // return (_size!=A._size)||(_name!=A._name)||(_type!=A._type)||(_level!=A._level); 70 | return (_tag!=A._tag); 71 | } 72 | 73 | bool tensor_index::operator < (const tensor_index& A) const{ 74 | return (_tag& Ac, const vector& Bc, vector& res){ 24 | res.resize(Ac.size()+Bc.size()); 25 | vector::iterator it; 26 | vector A(Ac.begin(), Ac.end()); 27 | vector B(Bc.begin(), Bc.end()); 28 | std::sort(A.begin(), A.end()); 29 | std::sort(B.begin(), B.end()); 30 | // make sure indices are unique 31 | it = std::unique (A.begin(), A.end()); 32 | A.resize(std::distance(A.begin(),it)); 33 | it = std::unique (B.begin(), B.end()); 34 | B.resize(std::distance(B.begin(),it)); 35 | it = std::set_union(A.begin(), A.end(), B.begin(), B.end(), res.begin()); 36 | res.resize(it-res.begin()); 37 | } 38 | 39 | void index_sets_difference(const vector& Ac, const vector& Bc, vector& res){ 40 | vector::iterator it; 41 | vector A(Ac.begin(), Ac.end()); 42 | vector B(Bc.begin(), Bc.end()); 43 | // make sure indices are unique 44 | it = std::unique (A.begin(), A.end()); 45 | A.resize(std::distance(A.begin(),it)); 46 | it = std::unique (B.begin(), B.end()); 47 | B.resize(std::distance(B.begin(),it)); 48 | res.clear(); 49 | for (size_t i = 0; i < A.size(); i++) { 50 | bool duplicated = false; 51 | for (size_t j = 0; j < B.size(); j++) { 52 | if(A[i]==B[j]){ 53 | duplicated = true; 54 | break; 55 | } 56 | } 57 | if(!duplicated){ 58 | res.push_back(A[i]); 59 | } 60 | } 61 | for (size_t i = 0; i < B.size(); i++) { 62 | bool duplicated = false; 63 | for (size_t j = 0; j < A.size(); j++) { 64 | if(B[i]==A[j]){ 65 | duplicated = true; 66 | break; 67 | } 68 | } 69 | if(!duplicated){ 70 | res.push_back(B[i]); 71 | } 72 | } 73 | } 74 | 75 | void index_sets_intersection(const vector& Ac, const vector& Bc, vector& res){ 76 | res.resize(Ac.size()+Bc.size()); 77 | vector::iterator it; 78 | vector A(Ac.begin(), Ac.end()); 79 | vector B(Bc.begin(), Bc.end()); 80 | std::sort(A.begin(), A.end()); 81 | std::sort(B.begin(), B.end()); 82 | // make sure indices are unique 83 | it = std::unique (A.begin(), A.end()); 84 | A.resize(std::distance(A.begin(),it)); 85 | it = std::unique (B.begin(), B.end()); 86 | B.resize(std::distance(B.begin(),it)); 87 | it = std::set_intersection(A.begin(), A.end(), B.begin(), B.end(), res.begin()); 88 | res.resize(it-res.begin()); 89 | } 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /dtensor/tensor_index_op.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef INDEX_OP_CLASS_FOR_DENSE_TENSOR_HEADER 19 | #define INDEX_OP_CLASS_FOR_DENSE_TENSOR_HEADER 20 | 21 | #include "tensor_index.h" 22 | 23 | void index_sets_union(const vector& Ac, const vector& Bc, vector& res); 24 | 25 | void index_sets_difference(const vector& Ac, const vector& Bc, vector& res); 26 | 27 | void index_sets_intersection(const vector& Ac, const vector& Bc, vector& res); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /examples/denseInput: -------------------------------------------------------------------------------- 1 | d 2 | 1 20 3 | 1 1 4 | 5 | 6 | 2 7 | 50 100 8 | 1E-6 1E-10 9 | 4 2 10 | -------------------------------------------------------------------------------- /linalg/lapack_wrapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef My_LAPACK_WRAPPERS_H 19 | #define My_LAPACK_WRAPPERS_H 20 | 21 | #include "../util/types_and_headers.h" 22 | 23 | // extern "C" void dgemm_(char*,cmakehar*,int*,int*,int*,double*,double*,int*,double*,int*,double*,double*,int*); 24 | extern "C" void dgeqrf_(int*, int*, double*, int*, double*, double*, int*, int*); 25 | extern "C" void dorgqr_(int*, int*, int*, double*, int*, double*, double*, int*, int*); 26 | extern "C" void dgesvd_(char*, char*, int*, int*, double*, int*, double*, double*, int*, double*, int*, double*, int*, int*); 27 | extern "C" void dsytrs_(char*,int*,int*,double*,int*,int*,double*,int*,int*); // broken? 28 | extern "C" void dsysv_(char*,int*,int*,double*,int*,int*,double*,int*,double*,int*,int*); // the only safe one to use 29 | extern "C" void dposv_(char*,int*,int*,double*,int*,double*,int*,int*); 30 | extern "C" void dgesv_(int*,int*,double*,int*,int*,double*,int*,int*); // the only safe one to use 31 | extern "C" void dsposv_(char*,int*,int*,double*,int*,double*,int*,double*,int*,double*,float*,int*,int*); 32 | extern "C" void dsysvx_(char*,char*,int*,int*,double*,int*,double*,int*,int*,double*,int*,double*,int*,double*,double*,double*,double*,int*,int*,int*); 33 | extern "C" void dposvx_(char*,char*,int*,int*,double*,int*,double*,int*,char*,double*,double*,int*,double*,int*,double*,double*,double*,double*,int*,int*); 34 | extern "C" void dsyev_(char*,char*,int*,double*,int*,double*,double*,int*,int*); 35 | extern "C" void dgemm_(char*,char*,int*,int*,int*,double*,double*,int*,double*,int*,double*,double*,int*); 36 | extern "C" void zgemm_(char*,char*,int*,int*,int*,std::complex*,std::complex*,int*,std::complex*,int*,std::complex*,std::complex*,int*); 37 | extern "C" void zgeqrf_(int*, int*, std::complex*, int*, std::complex*, std::complex*, int*, int*); 38 | extern "C" void zungqr_(int*, int*, int*, std::complex*, int*, std::complex*, std::complex*, int*, int*); 39 | extern "C" void zgesvd_(char*, char*, int*, int*, std::complex*, int*, double*, std::complex*, int*, std::complex*, int*, std::complex*, int*, double*, int*); 40 | extern "C" void zheev_(char*,char*,int*,std::complex*,int*,double*,std::complex*,int*,double*,int*); 41 | extern "C" void zhesv_(char*,int*,int*,std::complex*,int*,int*,std::complex*,int*,std::complex*,int*,int*); 42 | extern "C" void zgesv_(int*, int*, std::complex*, int*, int*, std::complex*, int*, int*); 43 | extern "C" void zhegv_(int*,char*,char*,int*,std::complex*,int*,std::complex*,int*,double*,std::complex*,int*,double*,int*); 44 | 45 | 46 | 47 | 48 | void MAT_VEC(int& m, int& k, int& n, double* A, double* B, double* C); 49 | void MAT_VEC(int& m, int& k, int& n, std::complex* A, std::complex* B, std::complex* C); 50 | 51 | void DIAG(int m, double* A, double* evals); 52 | void DIAG(int m, std::complex* A, double* evals); 53 | 54 | void ORTHO(int r, int c, double* A); 55 | void ORTHO(int r, int c, std::complex* A); 56 | 57 | void QR(int r, int c, double* A, double* Q, double* R); 58 | void QR(int r, int c, std::complex* A, std::complex* Q, std::complex* R); 59 | 60 | void SVD(int r, int c, double* A, double* U, vector& S, double* V); 61 | void SVD(int r, int c, std::complex* A, std::complex* U, vector& S, std::complex* V); 62 | void SVD(int r, int c, double* A, double* U, vector& S, double* V, char direction); 63 | void SVD(int r, int c, std::complex* A, std::complex* U, vector& S, std::complex* V, char direction); 64 | void SVD(int r, int c, double* A, double* U, vector& S, double* V, char direction, double cutoff); 65 | void SVD(int r, int c, std::complex* A, std::complex* U, vector& S, std::complex* V, char direction, double cutoff); 66 | void SVD(int r, int c, double* A, double* U, vector& S, double* V, char direction, int max_size); 67 | void SVD(int r, int c, std::complex* A, std::complex* U, vector& S, std::complex* V, char direction, int max_size); 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /linalg/tensor_davidson.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef DENSE_TENSOR_BASED_DAVIDSON_SOLVER_HEADER 19 | #define DENSE_TENSOR_BASED_DAVIDSON_SOLVER_HEADER 20 | 21 | #include "../linalg/lapack_wrapper.h" 22 | 23 | #include "../dtensor/dtensor_index.h" 24 | #include "../dtensor/dtensor_index_op.h" 25 | #include "../dtensor/dtensor.h" 26 | //#include "../dtensor/dtensor_view.h" 27 | 28 | #include "../qtensor/qtensor_index.h" 29 | #include "../qtensor/qtensor_index_op.h" 30 | #include "../qtensor/qtensor.h" 31 | 32 | #include "../qstensor/qstensor.h" 33 | 34 | #include "../dtensor/big_dtensor.h" 35 | #include "../qtensor/big_qtensor.h" 36 | #include "../qstensor/big_qstensor.h" 37 | 38 | //#include "tensor_cg.h" 39 | 40 | template 41 | void elemWiseDivide(dtensor& A, double theta, dtensor& B); 42 | 43 | template 44 | void elemWiseDivide(qtensor& A, double theta, qtensor& B); 45 | 46 | template 47 | void elemWiseDivide(qstensor& A, double theta, qstensor& B); 48 | 49 | // Restarted Davidson method to find the smallest/largest (algebraically) eigenvalue 50 | template class BigTensorType, template class TensorType> 51 | double tensor_davidson(BigTensorType& A, TensorType& x, int m, int max_restart, double tol, char mode='S'); 52 | //recreated ITensor version 53 | template class BigTensorType, template class TensorType> 54 | double tensor_davidsonIT(BigTensorType& A, TensorType& x, int m, int max_restart, double tol, char mode='S'); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClarkResearchGroup/tensor-tools/25fe4553991d2680b43301aef1960e4c20f1e146/logo2.png -------------------------------------------------------------------------------- /models/hams/AutoMPO.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Originally copyright 2018 The Simons Foundation, Inc., 3 | * with modifications by Ryan Levy 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 19 | #ifndef AUTOMPO_H 20 | #define AUTOMPO_H 21 | 22 | #include 23 | #include "../sites/sites.h" 24 | 25 | 26 | class AutoMPO; 27 | 28 | using Cplx = std::complex; 29 | using Real = double; 30 | 31 | // 32 | // Given an AutoMPO representing a Hamiltonian H, 33 | // returns an IQMPO which approximates exp(-tau*H) 34 | // 35 | // Although the tau argument is of Complex type, passing a Real 36 | // tau (Real is auto convertible to Complex) will 37 | // result in a real-valued MPO. 38 | 39 | struct SiteTerm 40 | { 41 | std::string op; 42 | int i; 43 | 44 | SiteTerm(); 45 | 46 | SiteTerm(std::string const& op, 47 | int i); 48 | 49 | bool 50 | operator==(SiteTerm const& o) const { return (op == o.op && i == o.i); } 51 | 52 | bool 53 | operator!=(SiteTerm const& other) const { return !operator==(other); } 54 | 55 | bool 56 | operator<(SiteTerm const& o) const 57 | { 58 | if(i != o.i) return i < o.i; 59 | return op < o.op; 60 | } 61 | 62 | bool 63 | operator>(SiteTerm const& o) const 64 | { 65 | if(i != o.i) return i > o.i; 66 | return op > o.op; 67 | } 68 | }; 69 | 70 | using SiteTermProd = std::vector; 71 | 72 | bool 73 | isFermionic(SiteTerm const& st); 74 | 75 | struct HTerm 76 | { 77 | Cplx coef = 0.; 78 | SiteTermProd ops; 79 | 80 | HTerm() : coef(1.) { } 81 | 82 | HTerm(Cplx z, SiteTermProd const& prod) : coef(z), ops(prod) { } 83 | 84 | HTerm(Cplx z, SiteTermProd && prod) : coef(z), ops(std::move(prod)) { } 85 | 86 | void 87 | add(std::string const& op, 88 | int i, 89 | Real x = 1); 90 | 91 | explicit 92 | operator bool() const { return !ops.empty(); } 93 | 94 | int 95 | Nops() const { return ops.size(); } 96 | 97 | SiteTerm const& 98 | first() const { return ops.front(); } 99 | 100 | SiteTerm const& 101 | last() const { return ops.back(); } 102 | 103 | HTerm& 104 | operator*=(Real x); 105 | 106 | HTerm& 107 | operator*=(Cplx x); 108 | 109 | bool 110 | operator==(HTerm const& other) const; 111 | 112 | bool 113 | operator!=(HTerm const& other) const { return !operator==(other); } 114 | 115 | bool 116 | operator<(HTerm const& other) const; 117 | }; 118 | 119 | struct LessNoCoef 120 | { 121 | bool 122 | operator()(HTerm const& t1, HTerm const& t2) const; 123 | }; 124 | 125 | class AutoMPO 126 | { 127 | public: 128 | using storage = std::set; 129 | private: 130 | //abstract_sites sites_; 131 | storage terms_; 132 | 133 | enum State { New, Op }; 134 | 135 | class Accumulator 136 | { 137 | AutoMPO* pa; 138 | State state; 139 | Cplx coef; 140 | std::string op; 141 | public: 142 | HTerm term; 143 | 144 | Accumulator(AutoMPO* pa, 145 | Real x); 146 | 147 | Accumulator(AutoMPO* pa, 148 | Cplx x); 149 | 150 | Accumulator(AutoMPO* pa); 151 | 152 | Accumulator(AutoMPO* pa, 153 | const char* opname); 154 | 155 | Accumulator(AutoMPO* pa, 156 | std::string const& opname); 157 | 158 | ~Accumulator(); 159 | 160 | Accumulator& 161 | operator,(Real x); 162 | 163 | Accumulator& 164 | operator,(Cplx x); 165 | 166 | Accumulator& 167 | operator,(int i); 168 | 169 | Accumulator& 170 | operator,(const char* op); 171 | 172 | Accumulator& 173 | operator,(std::string const& op); 174 | }; 175 | 176 | public: 177 | 178 | AutoMPO() { } 179 | 180 | AutoMPO(abstract_sites const& sites) 181 | //: sites_(sites) 182 | { } 183 | 184 | //abstract_sites const& 185 | //sites() const { return sites_; } 186 | 187 | storage const& 188 | terms() const { return terms_; } 189 | 190 | int 191 | size() const { return terms_.size(); } 192 | 193 | //operator MPO() const { return toMPO(*this); } 194 | 195 | //operator IQMPO() const { return toMPO(*this); } 196 | 197 | template 198 | Accumulator 199 | operator+=(T x) { return Accumulator(this,x); } 200 | 201 | void 202 | add(HTerm & t); 203 | 204 | void 205 | reset() { terms_.clear(); } 206 | }; 207 | 208 | std::ostream& 209 | operator<<(std::ostream& s, SiteTerm const& t); 210 | 211 | std::ostream& 212 | operator<<(std::ostream& s, HTerm const& t); 213 | 214 | std::ostream& 215 | operator<<(std::ostream& s, AutoMPO const& a); 216 | 217 | 218 | #endif 219 | -------------------------------------------------------------------------------- /models/hams/Heisenberg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * Portions originally copyright 2018 The Simons Foundation, Inc., 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 19 | #ifndef SPIN_HALF_HEISENBERG_MODEL_HEADER 20 | #define SPIN_HALF_HEISENBERG_MODEL_HEADER 21 | 22 | #include "../sites/spinhalf.h" 23 | #include "../../mps/tt.h" 24 | #include "../../mps/qtt.h" 25 | #include "AutoMPO.h" 26 | 27 | 28 | /* 29 | A. Heisenberg model (with optional random fields), and MPO layout: 30 | 31 | H = \sum_i J/2(S+_i S-_{i+1} + S-_i S+_{i+1}) + J Sz_i Sz_{+1} + h_i S_z_i 32 | 33 | MPO layout of an Hamiltonian is not unique. There are many equivalent way of 34 | spelling out the matrices for each sites. We will discuss the one layout 35 | that is most appropriate for working with quantum numbers. 36 | 37 | e.g. 38 | 1D: On each site, except at the boundary, the matrix looks like 39 | I 0 0 0 0 40 | hSz I JSz JS- JS+ 41 | Sz 0 0 0 0 42 | S+ 0 0 0 0 43 | S- 0 0 0 0 44 | On the first site (leftmost site), the matrix is just the second row of it. 45 | On the last site (rightmost site), the matrix is just the first column of it. 46 | 47 | You may try to multiply matrices for two adjacent sites together, and convince 48 | yourself that this in the end gives you the correct Hamiltonian. 49 | 50 | There are a few things sepcial about this kind of layout in general: 51 | (1) The (0,0) element is always Identity 52 | (2) The (1,1) element is always Identity 53 | (3) The (1,0) element always contain single body on-site operators, like Zeeman fields or Hubbard U 54 | (4) On site i, elements in the 1st column following (2,0) are connected to operators 55 | on 2nd row of site i-1. 56 | (5) On site i, elements in the 2nd row following (1,2) are connected to operators 57 | on site on 1st column of i+1. 58 | 59 | 60 | 61 | B. Long range interaction 62 | Instead of nearest neighbor interaction, assume that we have a 1D Heisenberg chain 63 | with interaction length up to 3 sites away, so we need NN, NNN, NNNN interactions. 64 | 65 | NN NNN NNNN NN NNN NNNN NN NNN NNNN 66 | ----------------------------------------------------- 67 | I 0 0 0 0 0 0 0 0 0 0 68 | hSz I JSz JSz JSz JS- JS- JS- JS+ JS+ JS+ 69 | Sz 0 0 0 70 | 0 I 0 0 71 | 0 0 I 0 72 | S+ 0 0 0 73 | 0 I 0 0 74 | 0 0 I 0 75 | S- 0 0 0 76 | 0 I 0 0 77 | 0 0 I 0 78 | 79 | (Unfilled spots above are zero) 80 | (The 3-by-3 diagonal blocks make NNN and NNNN interactions possible.) 81 | 82 | Convince yourself that the added blocks passes through NNN and NNNN interactions. 83 | You may try to work out the MPOs for Heisenberg ladders. 84 | 85 | 86 | 87 | C. Quantum number of MPO: 88 | For matrix A on site i, the flow of quantum numbers by default looks like the following. 89 | 90 | top state (bra) 91 | | 92 | v 93 | vitual bond in ----> A ----> virtual bond out 94 | | 95 | v 96 | bottom state (ket) 97 | 98 | We know that a vertical bond, or a physical bond, can either be spin down or up, 99 | so it carrys quatum number -1 or +1. 100 | We will try to understand the virtual bonds' quantum numbers below. 101 | 102 | Before we label the MPO's quantum number sector, there are a few things that can 103 | help our understanding. 104 | (1) Total Sz for this model is conserved, and its quantum number is abelian (additive). 105 | (2) Conservation of S^2 (if present) is not considered. 106 | (2) A S+ is always paired with a S-, possibly connected by some Identities, if they 107 | correspond to long range interaction. 108 | (3) Non-zero quantum numbers flow between a paired S+ and S-, but not outside of them. 109 | (4) There is no quantum number flow associated with I or Sz. 110 | 111 | Now, for the 1D nearest neighbor (NN) Heisenberg chain with magnetic fields, 112 | we can label the virtual bonds' quantum numbers as 113 | 114 | out 0 0 0 -2 +2 115 | in | ----------------------- 116 | 0 | I 0 0 0 0 117 | 0 | hSz I JSz JS- JS+ 118 | 0 | Sz 0 0 0 0 119 | -2 | S+ 0 0 0 0 120 | +2 | S- 0 0 0 0 121 | 122 | It is easy to understand that the 3-by-3 block (usually called "Identity block") 123 | at the top left corner has no in/out virtual bond quantum numbers. 124 | For the S+ operator in the first column, let's understand why it has in-QN=-2 125 | and out-QN=0. 126 | (1) This S+ is connected to the S- to the left of this site. 127 | (2) To its right, there is nothing connected to it. So for this S+, we have 128 | 129 | <+| (bra) 130 | | (+1) 131 | v 132 | vitual bond in ----> S+ ----> 0 133 | | 134 | v (-1) 135 | |-> (ket) 136 | 137 | In order to have the sum of all in QNs equal to the sum of all out QNs, 138 | vitual bond in must carry a QN=-2. 139 | 140 | Similarly, we can show that the S- operator in the first column has QN=2. 141 | You may work out the QNs for the S+/- on the 2nd row as exercise. 142 | 143 | 144 | 145 | D. qtensor format 146 | This is a good place to introduce the qtensor class (quantum numbered tensor), 147 | since we need to store the above blocked Hamiltonian using it. 148 | 149 | qtensor class is based on tensor diagram like the following one 150 | 151 | top bond 152 | | 153 | v 154 | vitual bond 1 ----> A ----> virtual bond 2 155 | | 156 | v 157 | bottom bond 158 | 159 | Using it as an example, we see that it has 4 indices (or bonds), each bond may 160 | carry certain numbers of quantum number, like 0,-2,+2 for the NN Heisenberg 161 | chain with magnetic fields; and each quantum number has a certain size, 162 | like 3 or 1 for the the NN Heisenberg chain with magnetic fields. 163 | 164 | So the basic idea of qtensor is: 165 | (1) A class called "qtensor_index" will spell out the index, whose attributes are: 166 | arrow (Inward or Outward), name, type (Link or Site), level (prime level), and QNs. 167 | The QNs contains a certain number of pairs of (qn, qdim), where the first element 168 | is the quantum number and the second element is the associated size. 169 | (2) Given all the "qtensor_index"s, qtensor filters out all the legal combinations 170 | of quantum numbers (\sum in-QNs = \sum out-QNs). Each legal block is stored as 171 | a separate tensor of the same rank. Each block manages its data indiidually. 172 | 173 | For example, this tensor below has 4 indices, 174 | (1) v1: Inward, left_virtual, Link, level 0, QNs {(0,3), (-2,1), (+2,1)} 175 | (2) v2: Outward, right_virtual, Link, level 0, QNs {(0,3), (-2,1), (+2,1)} 176 | (3) p1: Inward, top_physical, Site, level 1, QNs {(-1,1), (+1,1)} 177 | (3) p2: Outward, bot_physical, Site, level 0, QNs {(-1,1), (+1,1)} 178 | 179 | It has 5 legal blocks: 180 | (1) (v1.qn=0, v2.qn=0, p1.qn=-1, p2.qn=-1), size = 3*3*1*1 = 9 181 | (2) (v1.qn=-2, v2.qn=0, p1.qn=+1, p2.qn=-1), size = 1*3*1*1 = 3 182 | (3) (v1.qn=+2, v2.qn=0, p1.qn=-1, p2.qn=+1), size = 1*3*1*1 = 3 183 | (4) (v1.qn=0, v2.qn=-2, p1.qn=-1, p2.qn=+1), size = 3*1*1*1 = 3 184 | (5) (v1.qn=0, v2.qn=+2, p1.qn=+1, p2.qn=-1), size = 3*1*1*1 = 3 185 | 186 | out 0 0 0 -2 +2 187 | in | ----------------------- 188 | 0 | I 0 0 0 0 189 | 0 | hSz I JSz JS- JS+ 190 | 0 | Sz 0 0 0 0 191 | -2 | S+ 0 0 0 0 192 | +2 | S- 0 0 0 0 193 | 194 | */ 195 | 196 | template 197 | class Heisenberg{ 198 | public: 199 | Heisenberg(abstract_sites* s, double tE=0, double* dh=nullptr) {_s=s; _tE=tE; _dh=dh;} 200 | ~Heisenberg(){} 201 | 202 | void addOperators(MPO& A, unsigned site, unsigned r, unsigned c, string op, double val); 203 | void addOperators(qMPO& A, unsigned site, unsigned r, unsigned c, string op, double val, QN_t Qi, QN_t Qo); 204 | 205 | void buildHam(MPO& H); 206 | void buildHam(AutoMPO& ampo, MPO& H); 207 | void buildHam(qMPO& H); 208 | void buildHam(AutoMPO& ampo, qMPO& H); 209 | 210 | private: 211 | double _tE; 212 | double* _dh; 213 | abstract_sites* _s; 214 | vector< vector< vector > > ops; 215 | vector< vector< vector > > val; 216 | }; 217 | 218 | 219 | #endif 220 | -------------------------------------------------------------------------------- /models/lattice/latticebond.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Originally copyright 2018 The Simons Foundation, Inc., 3 | * with modifications by Ryan Levy 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 19 | #ifndef __ITENSOR_LATTICEBOND_H__ 20 | #define __ITENSOR_LATTICEBOND_H__ 21 | 22 | #include 23 | 24 | struct LatticeBond; 25 | 26 | using LatticeGraph = std::vector; 27 | 28 | struct LatticeBond 29 | { 30 | int s1 = 0, 31 | s2 = 0; 32 | std::string type; 33 | Real x1 = NAN, 34 | y1 = NAN, 35 | x2 = NAN, 36 | y2 = NAN; 37 | 38 | LatticeBond() { } 39 | 40 | LatticeBond(int s1_, int s2_) 41 | : s1{s1_}, 42 | s2{s2_} 43 | { } 44 | 45 | LatticeBond(int s1_, int s2_, 46 | Real x1_, Real y1_, 47 | Real x2_, Real y2_) 48 | : s1{s1_}, 49 | s2{s2_}, 50 | x1{x1_}, 51 | y1{y1_}, 52 | x2{x2_}, 53 | y2{y2_} 54 | { } 55 | 56 | LatticeBond(int s1_, int s2_, std::string type_) 57 | : s1{s1_}, 58 | s2{s2_}, 59 | type{type_} 60 | { } 61 | 62 | LatticeBond(int s1_, int s2_, 63 | Real x1_, Real y1_, 64 | Real x2_, Real y2_, 65 | std::string type_) 66 | : s1{s1_}, 67 | s2{s2_}, 68 | type{type_}, 69 | x1{x1_}, 70 | y1{y1_}, 71 | x2{x2_}, 72 | y2{y2_} 73 | { } 74 | }; 75 | 76 | inline std::ostream& 77 | operator<<(std::ostream & s, LatticeBond const& b) 78 | { 79 | //s << format("(%*d,%*d",3,b.s1,3,b.s2); 80 | /*s << format("(%d,%d",b.s1,b.s2); 81 | if(b.type.size()!=0) s << "," << b.type; 82 | s << ")"; 83 | if(!std::isnan(b.x1) && !std::isnan(b.y1)) 84 | { 85 | s << format("[%s,%s",b.x1,b.y1); 86 | if(!std::isnan(b.x2) && !std::isnan(b.y2)) 87 | { 88 | s << format(";%s,%s]",b.x2,b.y2); 89 | } 90 | else 91 | { 92 | s << "]"; 93 | } 94 | }*/ 95 | return s; 96 | } 97 | 98 | inline std::ostream& 99 | operator<<(std::ostream& s, LatticeGraph const& G) 100 | { 101 | for(auto& b : G) 102 | { 103 | s << b << "\n"; 104 | } 105 | return s; 106 | } 107 | 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /models/lattice/square.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Originally copyright 2018 The Simons Foundation, Inc., 3 | * with modifications by Ryan Levy 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 19 | #ifndef __ITENSOR_LATTICE_SQUARE_H_ 20 | #define __ITENSOR_LATTICE_SQUARE_H_ 21 | 22 | #include "latticebond.h" 23 | 24 | 25 | LatticeGraph inline 26 | squareLattice(int Nx, 27 | int Ny, 28 | bool yperiodic=false) 29 | { 30 | // Periodicity on y is meaningless for one dimensional chain or a ladder 31 | yperiodic = yperiodic && (Ny > 2); 32 | auto N = Nx*Ny; 33 | auto Nbond = 2*N-Ny + (yperiodic ? 0 : -Nx); 34 | LatticeGraph latt; 35 | latt.reserve(Nbond); 36 | for(int n = 1; n <= N; ++n) 37 | { 38 | int x = (n-1)/Ny+1; 39 | int y = (n-1)%Ny+1; 40 | 41 | //X-direction bond 42 | if(x < Nx) latt.emplace_back(n,n+Ny,x,y,x+1,y); 43 | 44 | if(Ny > 1) 45 | { 46 | //Y-direction bond 47 | if(y < Ny) latt.emplace_back(n,n+1,x,y,x,y+1); 48 | //Periodic bond 49 | if(yperiodic && y == 1) latt.emplace_back(n,n+Ny-1,x,y,x,y+Ny); 50 | } 51 | } 52 | if(int(latt.size()) != Nbond) { 53 | perr<< "Square latt wrong number of bonds" < 2); 66 | auto N = Nx*Ny; 67 | LatticeGraph latt; 68 | for(int n = 1; n <= N; ++n) 69 | { 70 | int x = (n-1)/Ny+1; 71 | int y = (n-1)%Ny+1; 72 | 73 | //First-neighbor bonds 74 | if(x < Nx) 75 | { 76 | //X-direction bond 77 | latt.emplace_back(n,n+Ny,x,y,x+1,y,"1"); 78 | } 79 | if(Ny > 1) 80 | { 81 | //Y-direction bond 82 | if(y < Ny) latt.emplace_back(n,n+1,x,y,x,y+1,"1"); 83 | //Periodic Y bond 84 | if(yperiodic && y == 1) latt.emplace_back(n,n+Ny-1,x,y,x,y+Ny,"1"); 85 | } 86 | 87 | //Second-neighbor bonds 88 | if(x < Nx && Ny > 1) 89 | { 90 | //Next-Neighbor X +Y 91 | if(y < Ny) latt.emplace_back(n,n+Ny+1,x,y,x+1,y+1,"2"); 92 | //Next-Neighbor X -Y 93 | if(y > 1) latt.emplace_back(n,n+Ny-1,x,y,x+1,y-1,"2"); 94 | //Periodic Next-Neighbor bonds 95 | if(yperiodic && y == Ny) 96 | { 97 | //Periodic Next-Neighbor X +Y 98 | latt.emplace_back(n,n+1,x,Ny,x+1,1,"2"); 99 | } 100 | if(yperiodic && y == 1) 101 | { 102 | //Periodic Next-Neighbor X -Y 103 | latt.emplace_back(n,n+2*Ny-1,x,1,x+1,Ny,"2"); 104 | } 105 | } 106 | } 107 | return latt; 108 | } 109 | 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /models/lattice/triangular.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Originally copyright 2018 The Simons Foundation, Inc., 3 | * with modifications by Ryan Levy 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 19 | #ifndef __ITENSOR_LATTICE_TRIANGULAR_H_ 20 | #define __ITENSOR_LATTICE_TRIANGULAR_H_ 21 | 22 | #include "latticebond.h" 23 | 24 | 25 | LatticeGraph inline 26 | triangularLattice(int Nx, 27 | int Ny, 28 | bool yperiodic = true) 29 | { 30 | // Periodicity on y is meaningless for one dimensional chain or a ladder 31 | yperiodic = yperiodic && (Ny > 2); 32 | auto N = Nx*Ny; 33 | auto Nbond = 3*N-2*Ny + (yperiodic ? 0 : -2*Nx+1); 34 | LatticeGraph latt; 35 | latt.reserve(Nbond); 36 | 37 | for(int n = 1; n <= N; ++n) 38 | { 39 | int x = (n-1)/Ny+1; 40 | int y = (n-1)%Ny+1; 41 | 42 | //X-direction bonds 43 | if(x < Nx) latt.emplace_back(n,n+Ny); 44 | 45 | if(Ny > 1) //2d bonds 46 | { 47 | //vertical bond / Y-periodic diagonal bond 48 | if((n+1 <= N) && ((y < Ny) || yperiodic)) 49 | { 50 | latt.emplace_back(n,n+1); 51 | } 52 | 53 | //Periodic vertical bond 54 | if(yperiodic && y == 1) latt.emplace_back(n,n+Ny-1); 55 | 56 | //Diagonal bonds 57 | if(x < Nx && y < Ny) latt.emplace_back(n,n+Ny+1); 58 | } 59 | } 60 | 61 | if(int(latt.size()) != Nbond) { 62 | perr<<" Triangular lattice wrong number of bonds"<3 && op.substr( op.length() - 2 )=="*F"){ 115 | string op2 = op.substr(0,op.length() - 2); 116 | double tot = 0.; 117 | for (unsigned k=0;k electron::c_bra_op_ket(unsigned bra, string op, unsigned ket){ 128 | assert(bra<4 && ket<4); 129 | if(op=="Sy"){ 130 | if(ket==Dn && bra==Up) return std::complex(0, -0.5); 131 | if(ket==Up && bra==Dn) return std::complex(0, +0.5); 132 | return 0; 133 | }else{ 134 | return std::complex(d_bra_op_ket(bra,op,ket),0.); 135 | } 136 | } 137 | 138 | uint_vec electron::product_state(str_vec& st){ 139 | unsigned m = 0; 140 | uint_vec ps; 141 | for(auto s : st){ 142 | if(s=="Up"){ 143 | ps.push_back(1); 144 | }else if(s=="Dn"){ 145 | ps.push_back(0); 146 | }else if(s=="Emp"){ 147 | ps.push_back(2); 148 | }else if(s=="UpDn"){ 149 | ps.push_back(3); 150 | }else{ 151 | perr << "Input produst state string is incompatible with spinhalf sites!" << '\n'; 152 | abort(); 153 | } 154 | ++m; 155 | } 156 | assert(m == _N); 157 | return ps; 158 | } 159 | /* 160 | * Sz (Sz=0,Nf=0) 161 | * S+ (Sz=2,Nf=0) 162 | * S- (Sz=-2,Nf=0) 163 | * Id (Sz=0,Nf=0) 164 | * Nup (Sz=0,Nf=0) 165 | * Ndn (Sz=0,Nf=0) 166 | * Ntot (Sz=0,Nf=0) 167 | * Cup (Sz=-1,Nf=-1) 168 | * Cdagup (Sz=1,Nf=1) 169 | * Cdn (Sz=1,Nf=-1) 170 | * Cdagdn (Sz=-1,Nf=1) 171 | * Aup (Sz=-1,Nf=-1) 172 | * Adagup (Sz=1,Nf=1) 173 | * Adn (Sz=1,Nf=-1) 174 | * Adagdn (Sz=-1,Nf=1) 175 | * F (Sz=0,Nf=0) 176 | * Fup (Sz=0,Nf=0) 177 | * Fdn (Sz=0,Nf=0) 178 | * */ 179 | QN_t electron::div(string op){ 180 | if(op=="Sz") 181 | return {0,0}; 182 | if(op=="S+") 183 | return {2,0}; 184 | if(op=="S-") 185 | return {-2,0}; 186 | if(op=="Id") 187 | return 0; 188 | if(op=="Nup" || op=="Ndn" || op=="Ntot" || op=="Nupdn") 189 | return 0; 190 | if(op=="Cup") 191 | return {-1,-1}; 192 | if(op=="Cdagup") 193 | return {1,1}; 194 | if(op=="Cdn") 195 | return {1,-1}; 196 | if(op=="Cdagdn") 197 | return {-1,1}; 198 | 199 | perr<<"Bad string:"< c_bra_op_ket(unsigned bra, string op, unsigned ket); 37 | uint_vec product_state(str_vec& st); 38 | QN_t div(string op); 39 | 40 | const unsigned Dn; 41 | const unsigned Up; 42 | const unsigned Emp; 43 | const unsigned UpDn; 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /models/sites/sites.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef ABSTRACT_SITES_HEADER 19 | #define ABSTRACT_SITES_HEADER 20 | 21 | #include "../../util/types_and_headers.h" 22 | 23 | class abstract_sites{ 24 | public: 25 | 26 | abstract_sites(unsigned L, unsigned pD) : _N(L) , _phyDim(pD) {} 27 | ~abstract_sites(){} 28 | 29 | virtual double d_bra_op_ket(unsigned bra, string op, unsigned ket) = 0; 30 | virtual std::complex c_bra_op_ket(unsigned bra, string op, unsigned ket) = 0; 31 | virtual uint_vec product_state(str_vec& st) = 0; 32 | virtual QN_t div(string op)=0; 33 | 34 | unsigned N() {return _N;} 35 | unsigned phy_dim() {return _phyDim;} 36 | vector phy_qn() {return _phyQN;} 37 | 38 | protected: 39 | 40 | unsigned _N; 41 | unsigned _phyDim; 42 | vector _phyQN; 43 | }; 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /models/sites/spinhalf.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef SPIN_HALF_SITES_TYPE 19 | #define SPIN_HALF_SITES_TYPE 20 | 21 | #include "spinhalf.h" 22 | 23 | double spinhalf::d_bra_op_ket(unsigned bra, string op, unsigned ket){ 24 | assert(bra<2 && ket<2); 25 | if(op=="Id" || op=="I"){ 26 | if(ket==bra) return 1; 27 | return 0; 28 | }else if(op=="Sz"){ 29 | if(ket==Dn && bra==Dn) return -0.5; 30 | if(ket==Up && bra==Up) return +0.5; 31 | return 0; 32 | }else if(op=="Sx"){ 33 | if(ket==Dn && bra==Up) return +0.5; 34 | if(ket==Up && bra==Dn) return +0.5; 35 | return 0; 36 | }else if(op=="S+" || op=="Sp"){ 37 | if(ket==Dn && bra==Up) return +1; 38 | return 0; 39 | }else if(op=="S-" || op=="Sm"){ 40 | if(ket==Up && bra==Dn) return +1; 41 | return 0; 42 | }else{ 43 | perr << "(spinhalf class) Operator " << op << " is not supported!" << '\n'; 44 | return 0; 45 | } 46 | } 47 | 48 | std::complex spinhalf::c_bra_op_ket(unsigned bra, string op, unsigned ket){ 49 | assert(bra<2 && ket<2); 50 | if(op=="Id" || op=="I"){ 51 | if(ket==bra) return 1; 52 | return 0; 53 | }else if(op=="Sz"){ 54 | if(ket==Dn && bra==Dn) return -0.5; 55 | if(ket==Up && bra==Up) return +0.5; 56 | return 0; 57 | }else if(op=="Sx"){ 58 | if(ket==Dn && bra==Up) return +0.5; 59 | if(ket==Up && bra==Dn) return +0.5; 60 | return 0; 61 | }else if(op=="Sy"){ 62 | if(ket==Dn && bra==Up) return std::complex(0, -0.5); 63 | if(ket==Up && bra==Dn) return std::complex(0, +0.5); 64 | return 0; 65 | }else if(op=="S+" || op=="Sp"){ 66 | if(ket==Dn && bra==Up) return +1; 67 | return 0; 68 | }else if(op=="S-" || op=="Sm"){ 69 | if(ket==Up && bra==Dn) return +1; 70 | return 0; 71 | }else{ 72 | perr << "(spinhalf class) Operator " << op << " is not supported!" << '\n'; 73 | return 0; 74 | } 75 | } 76 | 77 | uint_vec spinhalf::product_state(str_vec& st){ 78 | unsigned m = 0; 79 | uint_vec ps; 80 | for(auto s : st){ 81 | if(s=="Up"){ 82 | ps.push_back(1); 83 | }else if(s=="Dn"){ 84 | ps.push_back(0); 85 | }else{ 86 | perr << "Input produst state string is incompatible with spinhalf sites!" << '\n'; 87 | abort(); 88 | } 89 | ++m; 90 | } 91 | assert(m == _N); 92 | return ps; 93 | } 94 | 95 | QN_t spinhalf::div(string op){ 96 | if(op=="Sz") 97 | return 0; 98 | if(op=="S+") 99 | return 2; 100 | if(op=="S-") 101 | return -2; 102 | if(op=="Id") 103 | return 0; 104 | assert(1==2); //Not found op string! 105 | return 0; 106 | } 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /models/sites/spinhalf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef SPIN_HALF_SITES_TYPE_HEADER 19 | #define SPIN_HALF_SITES_TYPE_HEADER 20 | 21 | #include "sites.h" 22 | 23 | class spinhalf : public abstract_sites 24 | { 25 | public: 26 | spinhalf() : abstract_sites(0,2),Dn(0),Up(1) {} 27 | spinhalf(unsigned L) : abstract_sites(L,2), Dn(0), Up(1) { 28 | abstract_sites::_phyQN.push_back(-1); 29 | abstract_sites::_phyQN.push_back(+1); 30 | /*abstract_sites::_phyQN.push_back({-1,0}); 31 | abstract_sites::_phyQN.push_back({+1,0});*/ 32 | } 33 | ~spinhalf(){} 34 | 35 | double d_bra_op_ket(unsigned bra, string op, unsigned ket); 36 | std::complex c_bra_op_ket(unsigned bra, string op, unsigned ket); 37 | uint_vec product_state(str_vec& st); 38 | QN_t div(string op); 39 | 40 | const unsigned Dn; 41 | const unsigned Up; 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /mps/mps_all.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef ALL_MPS_RELATED_HEADERS 19 | #define ALL_MPS_RELATED_HEADERS 20 | 21 | #include "tt.h" 22 | #include "qtt.h" 23 | #include "qstt.h" 24 | #include "observables.h" 25 | #include "mps_mpo_methods.h" 26 | namespace ezh5{ 27 | template<> Node& Node::operator = (QN_t_1 val){ 28 | (*this) = val.qn[0]; 29 | return *this; 30 | } 31 | template<> Node& Node::operator >> (QN_t_1& val){ 32 | int temp; 33 | (*this) >> temp; 34 | val.qn = {temp}; 35 | return *this; 36 | } 37 | template<> Node& Node::operator = (std::vector& vec){ 38 | vector temp;temp.reserve(vec.size()); for(auto& c: vec) temp.push_back(c.qn[0]); 39 | (*this) = temp; 40 | return *this; 41 | }; 42 | template<> Node& Node::operator >> (std::vector& vec){ 43 | vector temp; (*this) >> temp; 44 | for(auto c: temp) vec.push_back({c}); 45 | return *this; 46 | }; 47 | //---------------------------------------------------------------- 48 | template<> Node& Node::operator = (QN_t_2 val){ 49 | vector temp;temp.reserve(val.qn.size()); for(auto& c: val.qn) temp.push_back(c); 50 | (*this) = temp; 51 | return *this; 52 | } 53 | template<> Node& Node::operator >> (QN_t_2& val){ 54 | vector temp; (*this) >> temp; 55 | val.qn = valarray(temp.data(),temp.size()); 56 | return *this; 57 | } 58 | template<> Node& Node::operator = (std::vector& vec){ 59 | vector temp;temp.reserve(vec.size()); 60 | for(auto& v: vec) 61 | for(auto c: v.qn) 62 | temp.push_back(c); 63 | (*this) = temp; 64 | return *this; 65 | }; 66 | template<> Node& Node::operator >> (std::vector& vec){ 67 | vector temp; (*this) >> temp; 68 | assert(temp.size()%2 == 0); 69 | for(size_t i = 0; i 25 | void sum(vector< dTensorTrain >& x, dTensorTrain& res, int max_iter, double cutoff, int max_bd, double tol=1e-12, bool verbose=false); 26 | 27 | template 28 | void sum(vector< qTensorTrain >& x, qTensorTrain& res, int max_iter, double cutoff, int max_bd, double tol=1e-12, bool verbose=false); 29 | 30 | template 31 | void mult(MPO& A, MPO& B, MPO& res, int max_iter, double cutoff, int max_bd, double tol=1e-12, bool verbose=false); 32 | 33 | template 34 | void mult(qMPO& A, qMPO& B, qMPO& res, int max_iter, double cutoff, int max_bd, double tol=1e-12, bool verbose=false); 35 | 36 | template 37 | void mult(MPO& A, MPS& B, MPS& res, int max_iter, double cutoff, int max_bd, double tol=1e-12, bool verbose=false); 38 | 39 | template 40 | void mult(qMPO& A, qMPS& B, qMPS& res, int max_iter, double cutoff, int max_bd, double tol=1e-12, bool verbose=false); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /mps/observables.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef My_OBSERVABLES_H 19 | #define My_OBSERVABLES_H 20 | 21 | #include "tt.h" 22 | #include "qtt.h" 23 | #include "qstt.h" 24 | 25 | //------------------------------------- 26 | // Overlaps 27 | template 28 | T psiHphi(MPS& psi, MPO& H, MPS& phi); 29 | 30 | template 31 | T overlap(MPS& psi, MPO& H, MPS& phi){ return psiHphi(psi,H,phi); } 32 | 33 | template 34 | T psiHphi(qMPS& psi, qMPO& H, qMPS& phi); 35 | 36 | template 37 | T overlap(qMPS& psi, qMPO& H, qMPS& phi){ return psiHphi(psi,H,phi); } 38 | 39 | template 40 | T psiHphi(qsMPS& psi, qsMPO& H, qsMPS& phi); 41 | 42 | template 43 | T overlap(qsMPS& psi, qsMPO& H, qsMPS& phi){ return psiHphi(psi,H,phi); } 44 | 45 | //-------------------------------------------------------------------- 46 | template 47 | T psiHKphi(MPS& psi, MPO& H, MPO& K, MPS& phi); 48 | 49 | template 50 | T overlap(MPS& psi, MPO& H, MPO& K, MPS& phi){ return psiHKphi(psi,H,K,phi); } 51 | 52 | template 53 | T psiHKphi(qMPS& psi, qMPO& H, qMPO& K, qMPS& phi); 54 | 55 | template 56 | T overlap(qMPS& psi, qMPO& H, qMPO& K, qMPS& phi){ return psiHKphi(psi,H,K,phi); } 57 | 58 | template 59 | T psiHKphi(qsMPS& psi, qsMPO& H, qsMPO& K, qsMPS& phi); 60 | 61 | template 62 | T overlap(qsMPS& psi, qsMPO& H, qsMPO& K, qsMPS& phi){ return psiHKphi(psi,H,K,phi); } 63 | 64 | //-------------------------------------------------------------------- 65 | template 66 | T psiHKGphi(qMPS& psi, qMPO& H, qMPO& K, qMPO& G, qMPS& phi); 67 | 68 | template 69 | T overlap(qMPS& psi, qMPO& H, qMPO& K, qMPO& G, qMPS& phi){ return psiHKGphi(psi,H,K,G,phi); } 70 | 71 | template 72 | T psiHKGphi(qsMPS& psi, qsMPO& H, qsMPO& K, qsMPO& G,qsMPS& phi); 73 | 74 | template 75 | T overlap(qsMPS& psi, qsMPO& H, qsMPO& K, qsMPO& G,qsMPS& phi){ return psiHKGphi(psi,H,K,G,phi); } 76 | //-------------------------------------------------------------------- 77 | template 78 | T psiphi(MPS& psi, MPS& phi); 79 | 80 | template 81 | T overlap(MPS& psi, MPS& phi){ return psiphi(psi,phi); } 82 | 83 | template 84 | T psiphi(qMPS& psi, qMPS& phi); 85 | 86 | template 87 | T overlap(qMPS& psi, qMPS& phi){ return psiphi(psi,phi); } 88 | 89 | template 90 | T psiphi(qsMPS& psi, qsMPS& phi); 91 | 92 | template 93 | T overlap(qsMPS& psi, qsMPS& phi){ return psiphi(psi,phi); } 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /mps/qstt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef QUANTUM_NUMBERED_SPARSE_TENSORTRAIN_CLASS_H 19 | #define QUANTUM_NUMBERED_SPARSE_TENSORTRAIN_CLASS_H 20 | 21 | #include "../util/ezh5.h" 22 | #include "../linalg/lapack_wrapper.h" 23 | #include "../qstensor/qstensor_all.h" 24 | #include "qtt.h" 25 | #include "../models/sites/sites.h" 26 | 27 | 28 | /* 29 | This class is the base class of MPS and MPO. 30 | */ 31 | 32 | // N is the number of physical indices per site (1:MPS, 2:MPO) 33 | template 34 | class qsTensorTrain 35 | { 36 | public: 37 | //--------------------------------------------------------------------------- 38 | // ID used for naming the the tensors 39 | unsigned _id; // assigned randomly when an object is created 40 | 41 | //--------------------------------------------------------------------------- 42 | // Basic properties 43 | unsigned length; // length of the tensor train 44 | unsigned phy_dim; // dimension of each physical bond 45 | uint_vec bond_dims; // dimensions of virtual bonds 46 | int center; // canonicalization center 47 | QN_t totalQ; // total abelian quantum number 48 | vector phy_qn; // quantum numbers of physical bonds 49 | 50 | //--------------------------------------------------------------------------- 51 | // Data containers 52 | vector< qstensor > A; 53 | 54 | //--------------------------------------------------------------------------- 55 | // Flag -- whether the tensors are allocated 56 | bool tensors_allocated; 57 | 58 | //--------------------------------------------------------------------------- 59 | // Constructors 60 | qsTensorTrain(); 61 | qsTensorTrain(abstract_sites* s, QN_t Q = 0); 62 | qsTensorTrain(abstract_sites* s, str_vec product_string); 63 | qsTensorTrain(unsigned L, unsigned pD, vector& phyQN, QN_t Q); 64 | qsTensorTrain(unsigned L, unsigned pD, vector& phyQN, uint_vec product_state); 65 | qsTensorTrain(const qsTensorTrain& other); 66 | qsTensorTrain(qsTensorTrain&& other); 67 | qsTensorTrain(const qTensorTrain& other); 68 | qsTensorTrain(qTensorTrain&& other); 69 | // Destructor 70 | ~qsTensorTrain(){}; 71 | 72 | //--------------------------------------------------------------------------- 73 | // Set shapes 74 | void setLength(int L); 75 | void setPhysicalDim(int s); 76 | 77 | //--------------------------------------------------------------------------- 78 | // Tensor data management 79 | void allocateTensors(unsigned* product_state=nullptr); 80 | void freeTensors(); 81 | 82 | //--------------------------------------------------------------------------- 83 | // Set tensors values 84 | void setZero(); 85 | void setRandom(); 86 | 87 | //--------------------------------------------------------------------------- 88 | // Basic arithmetic operations 89 | qsTensorTrain& operator = (const qsTensorTrain& other); 90 | qsTensorTrain& operator = (qsTensorTrain&& other); 91 | qsTensorTrain& operator = (const qTensorTrain& other); //convert 92 | qsTensorTrain& operator = (qTensorTrain&& other); //convert 93 | qsTensorTrain& operator *=(const T c); 94 | qsTensorTrain& operator /=(const T c); 95 | qsTensorTrain operator * (const T c) const; 96 | qsTensorTrain operator / (const T c) const; 97 | 98 | //--------------------------------------------------------------------------- 99 | // Print qTensorTrain information 100 | void print(int level=0); 101 | 102 | //--------------------------------------------------------------------------- 103 | // txt or HDF5 storage 104 | void save(std::string fn, std::string wfn=""); 105 | void load(std::string fn, std::string dataPrefix=""); 106 | void save(ezh5::Node& fW); 107 | void load(ezh5::Node& fR); 108 | 109 | //--------------------------------------------------------------------------- 110 | // Canonicalization 111 | void rc(); 112 | void lc(); 113 | 114 | //--------------------------------------------------------------------------- 115 | // Adjust canonical center 116 | double position(int site); 117 | 118 | //--------------------------------------------------------------------------- 119 | // Norm 120 | void normalize(); 121 | double norm(); 122 | }; 123 | 124 | 125 | // Definition of MPS and MPO through qTensorTrain 126 | template 127 | using qsMPS = qsTensorTrain; 128 | 129 | template 130 | using qsMPO = qsTensorTrain; 131 | 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /mps/qtt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef QUANTUM_NUMBERED_TENSORTRAIN_CLASS_H 19 | #define QUANTUM_NUMBERED_TENSORTRAIN_CLASS_H 20 | 21 | #include "../util/ezh5.h" 22 | #include "../linalg/lapack_wrapper.h" 23 | #include "../qtensor/qtensor_index.h" 24 | #include "../qtensor/qtensor_index_op.h" 25 | #include "../qtensor/qtensor.h" 26 | #include "../qtensor/qtensor_op.h" 27 | #include "../qtensor/big_qtensor.h" 28 | #include "../models/sites/sites.h" 29 | 30 | 31 | /* 32 | This class is the base class of MPS and MPO. 33 | */ 34 | 35 | // N is the number of physical indices per site (1:MPS, 2:MPO) 36 | template 37 | class qTensorTrain 38 | { 39 | public: 40 | //--------------------------------------------------------------------------- 41 | // ID used for naming the the tensors 42 | unsigned _id; // assigned randomly when an object is created 43 | 44 | //--------------------------------------------------------------------------- 45 | // Basic properties 46 | unsigned length; // length of the tensor train 47 | unsigned phy_dim; // dimension of each physical bond 48 | uint_vec bond_dims; // dimensions of virtual bonds 49 | int center; // canonicalization center 50 | QN_t totalQ; // total abelian quantum number 51 | vector phy_qn; // quantum numbers of physical bonds 52 | 53 | //--------------------------------------------------------------------------- 54 | // Data containers 55 | vector< qtensor > A; 56 | 57 | //--------------------------------------------------------------------------- 58 | // Flag -- whether the tensors are allocated 59 | bool tensors_allocated; 60 | 61 | //--------------------------------------------------------------------------- 62 | // Constructors 63 | qTensorTrain(); 64 | qTensorTrain(abstract_sites* s, QN_t Q = 0); 65 | qTensorTrain(abstract_sites* s, str_vec product_string); 66 | qTensorTrain(unsigned L, unsigned pD, vector& phyQN, QN_t Q); 67 | qTensorTrain(unsigned L, unsigned pD, vector& phyQN, uint_vec product_state); 68 | qTensorTrain(const qTensorTrain& other); 69 | qTensorTrain(qTensorTrain&& other); 70 | // Destructor 71 | ~qTensorTrain(){}; 72 | 73 | //--------------------------------------------------------------------------- 74 | // Set shapes 75 | void setLength(int L); 76 | void setPhysicalDim(int s); 77 | 78 | //--------------------------------------------------------------------------- 79 | // Tensor data management 80 | void allocateTensors(unsigned* product_state=nullptr); 81 | void freeTensors(); 82 | 83 | //--------------------------------------------------------------------------- 84 | // Set tensors values 85 | void setZero(); 86 | void setRandom(); 87 | 88 | //--------------------------------------------------------------------------- 89 | // Basic arithmetic operations 90 | qTensorTrain& operator = (const qTensorTrain& other); 91 | qTensorTrain& operator = (qTensorTrain&& other); 92 | qTensorTrain& operator *=(const T c); 93 | qTensorTrain& operator /=(const T c); 94 | qTensorTrain operator * (const T c) const; 95 | qTensorTrain operator / (const T c) const; 96 | 97 | //--------------------------------------------------------------------------- 98 | // Print qTensorTrain information 99 | void print(int level=0); 100 | 101 | //--------------------------------------------------------------------------- 102 | // txt or HDF5 storage 103 | void save(std::string fn, std::string wfn=""); 104 | void load(std::string fn, std::string dataPrefix=""); 105 | void save(ezh5::Node& fW); 106 | void load(ezh5::Node& fR); 107 | 108 | //--------------------------------------------------------------------------- 109 | // Canonicalization 110 | void rc(); 111 | void lc(); 112 | 113 | //--------------------------------------------------------------------------- 114 | // Adjust canonical center 115 | double position(int site); 116 | 117 | //--------------------------------------------------------------------------- 118 | // Norm 119 | void normalize(); 120 | double norm(); 121 | }; 122 | 123 | 124 | // Definition of MPS and MPO through qTensorTrain 125 | template 126 | using qMPS = qTensorTrain; 127 | 128 | template 129 | using qMPO = qTensorTrain; 130 | 131 | 132 | #endif 133 | -------------------------------------------------------------------------------- /mps/tt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef DENSE_TENSORTRAIN_CLASS_H 19 | #define DENSE_TENSORTRAIN_CLASS_H 20 | 21 | #include "../util/ezh5.h" 22 | #include "../linalg/lapack_wrapper.h" 23 | #include "../dtensor/dtensor_index.h" 24 | #include "../dtensor/dtensor_index_op.h" 25 | #include "../dtensor/dtensor.h" 26 | //#include "../dtensor/dtensor_view.h" 27 | #include "../dtensor/dtensor_op.h" 28 | #include "../dtensor/big_dtensor.h" 29 | #include "../models/sites/sites.h" 30 | 31 | /* 32 | This class is the base class of MPS and MPO. 33 | */ 34 | 35 | // N is the number of physical indices per site (1:MPS, 2:MPO) 36 | template 37 | class dTensorTrain 38 | { 39 | public: 40 | //--------------------------------------------------------------------------- 41 | // ID used for naming the the tensors 42 | unsigned _id; // assigned randomly when an object is created 43 | 44 | //--------------------------------------------------------------------------- 45 | // Basic properties 46 | unsigned length; // length of the tensor train 47 | unsigned phy_dim; // dimension of each physical bond 48 | int center; // canonicalization center 49 | uint_vec bond_dims; // dimensions of virtual bonds 50 | 51 | //--------------------------------------------------------------------------- 52 | // Data containers 53 | vector< dtensor > A; 54 | 55 | //--------------------------------------------------------------------------- 56 | // Flag -- whether the tensors are allocated 57 | bool tensors_allocated; 58 | 59 | //--------------------------------------------------------------------------- 60 | // Constructors 61 | dTensorTrain(); 62 | dTensorTrain(abstract_sites* s, unsigned bd = 1); 63 | dTensorTrain(abstract_sites* s, uint_vec& bd); 64 | dTensorTrain(abstract_sites* s, str_vec product_string); 65 | dTensorTrain(unsigned l, unsigned pd, unsigned bd = 1); 66 | dTensorTrain(const dTensorTrain& other); 67 | dTensorTrain(dTensorTrain&& other); 68 | // Destructor 69 | ~dTensorTrain(){}; 70 | 71 | //--------------------------------------------------------------------------- 72 | // Set shapes 73 | void setLength(int L); 74 | void setPhysicalDim(int s); 75 | void setBondDim(int bd); 76 | void setBondDims(const uint_vec& bds); 77 | 78 | //--------------------------------------------------------------------------- 79 | // Tensor data management 80 | void allocateTensors(unsigned* product_state=nullptr); 81 | void freeTensors(); 82 | 83 | //--------------------------------------------------------------------------- 84 | // Set tensors values 85 | void setZero(); 86 | void setRandom(); 87 | 88 | //--------------------------------------------------------------------------- 89 | // Basic arithmetic operations 90 | dTensorTrain& operator = (const dTensorTrain& other); 91 | dTensorTrain& operator = (dTensorTrain&& other); 92 | dTensorTrain& operator *=(const T c); 93 | dTensorTrain& operator /=(const T c); 94 | dTensorTrain operator * (const T c) const; 95 | dTensorTrain operator / (const T c) const; 96 | 97 | //--------------------------------------------------------------------------- 98 | // Print dTensorTrain information 99 | void print(int level=0); 100 | 101 | //--------------------------------------------------------------------------- 102 | // HDF5 storage 103 | void save(std::string fn, std::string wfn=""); 104 | void load(std::string fn); 105 | void save(ezh5::Node& fW); 106 | void load(ezh5::Node& fR); 107 | 108 | //--------------------------------------------------------------------------- 109 | // Canonicalization 110 | void rc(); 111 | void lc(); 112 | 113 | //--------------------------------------------------------------------------- 114 | // Adjust canonical center 115 | double position(int site); 116 | 117 | //--------------------------------------------------------------------------- 118 | // Norm 119 | void normalize(); 120 | double norm(); 121 | }; 122 | 123 | 124 | // Definition of MPS and MPO through dTensorTrain 125 | template 126 | using MPS = dTensorTrain; 127 | 128 | template 129 | using MPO = dTensorTrain; 130 | 131 | 132 | #endif 133 | -------------------------------------------------------------------------------- /qstensor/big_qstensor.cpp: -------------------------------------------------------------------------------- 1 | #ifndef BIG_QUANTUM_NUMBERED_SPARSE_TENSOR_CLASS 2 | #define BIG_QUANTUM_NUMBERED_SPARSE_TENSOR_CLASS 3 | 4 | #include "big_qstensor.h" 5 | 6 | template 7 | qstensor big_qstensor::product(qstensor& v){ 8 | // contract pattern: 9 | // L-v-mid-R 10 | qstensor res; 11 | if(L!=nullptr) res = std::move((*L)*v); 12 | if(res.rank>0) 13 | res = std::move(res*(mid)); 14 | else 15 | res = std::move(v*(mid)); 16 | if(R!=nullptr) res = std::move(res*(*R)); 17 | 18 | /*qstensor res = std::move(A*v); 19 | if(R!=nullptr) res = std::move(res*(*R));*/ 20 | 21 | res.prime(-1); 22 | return res; 23 | } 24 | template qstensor big_qstensor::product(qstensor& v); 25 | template qstensor< std::complex > big_qstensor< std::complex >::product(qstensor< std::complex >& v); 26 | 27 | 28 | template 29 | T big_qstensor::expec(qstensor& v){ 30 | // contract pattern: 31 | /*// L-v-mid-R 32 | qstensor res; 33 | if(L!=nullptr) res = std::move((*L)*v); 34 | if(res.rank>0) 35 | res = std::move(res*mid); 36 | else 37 | res = std::move(v*(mid)); 38 | if(R!=nullptr) res = std::move(res*(*R)); 39 | 40 | assert(1==2);*/ 41 | //qstensor res = std::move(A*v); 42 | //if(R!=nullptr) res = std::move(res*(*R)); 43 | qstensor res = std::move(product(v)); 44 | 45 | return res.contract(v); 46 | } 47 | template double big_qstensor::expec(qstensor& v); 48 | template std::complex big_qstensor< std::complex >::expec(qstensor< std::complex >& v); 49 | 50 | template 51 | qstensor big_qstensor::diagonal(){ 52 | /*qstensor res; 53 | if(L!=nullptr) res = (*L).diagonal(); 54 | for(auto m : mid){ 55 | qstensor dm = m->diagonal(); 56 | res = std::move(res*(dm)); 57 | } 58 | if(R!=nullptr){ 59 | qstensor dR = R->diagonal(); 60 | res = std::move(res*dR); 61 | }*/ 62 | 63 | qstensor res; 64 | if(R==nullptr){ 65 | res = std::move((*L)*mid); 66 | res = std::move(res.diagonal()); 67 | }else{ 68 | //fake operators without storage so we can get final index structure 69 | qstensor midtemp(mid.idx_set); idxToSparse(mid.idx_set, midtemp._T); midtemp._initted=true; 70 | qstensor Ltemp(L->idx_set); idxToSparse(L->idx_set,Ltemp._T); Ltemp._initted=true; 71 | qstensor Rtemp(R->idx_set); idxToSparse(R->idx_set,Rtemp._T); Rtemp._initted=true; 72 | //res = std::move(A*(*R)); 73 | //res = std::move(res.diagonal()); 74 | res = std::move(Ltemp*midtemp); 75 | res = std::move(res*Rtemp); 76 | res = std::move(res.diagonal(All)); 77 | 78 | unordered_map charMap; 79 | /*vector L_diag = {L->idx_set[1],L->idx_set[2]}; 80 | vector R_diag = {R->idx_set[1],R->idx_set[2]}; 81 | CTF::Tensor LT(2,L->_T.lens+1); LT.sparsify(); 82 | CTF::Tensor RT(2,R->_T.lens+1); RT.sparsify(); 83 | vector mid_diag = {mid.idx_set[0],mid.idx_set[1], 84 | mid.idx_set[3],mid.idx_set[5]}; 85 | vector mid_sizes = {mid._T.lens[0],mid._T.lens[1], 86 | mid._T.lens[3],mid._T.lens[5]}; 87 | CTF::Tensor midT(4,mid_sizes.data());midT.sparsify(); 88 | 89 | //TODO: only have LT or RT in memory at once? 90 | 91 | auto indMid_diag = indicesToCharNP(mid_diag,charMap); 92 | auto indL_diag = indicesToCharNP(L_diag,charMap); 93 | auto indR_diag = indicesToCharNP(R_diag,charMap); 94 | LT[indL_diag.c_str()] = L->_T[indL.c_str()]; 95 | RT[indR_diag.c_str()] = R->_T[indR.c_str()]; 96 | midT[indMid_diag.c_str()] = mid._T[indMid.c_str()]; 97 | //perr<idx_set,charMap); 102 | auto indR = indicesToCharNP(R->idx_set,charMap); 103 | auto indRes = indicesToCharNP(res.idx_set,charMap); 104 | //perr<_T[indL.c_str()]*mid._T[indMid.c_str()]*R->_T[indR.c_str()]; 107 | } 108 | 109 | // qstensor res = std::move(A.diagonal()); 110 | 111 | return res; 112 | } 113 | template qstensor big_qstensor::diagonal(); 114 | template qstensor< std::complex > big_qstensor< std::complex >::diagonal(); 115 | 116 | template 117 | size_t big_qstensor::size() const{ 118 | if(size_ == 0){ 119 | size_ = 1; 120 | if(L!=nullptr){ 121 | for(unsigned l=0; l< L->rank; l++){ 122 | if(L->idx_set[l].level() > 0) 123 | size_ *= L->idx_set[l].size(); 124 | } 125 | } 126 | if(R!=nullptr){ 127 | for(unsigned l=0; l< R->rank; l++){ 128 | if(R->idx_set[l].level() > 0) 129 | size_ *= R->idx_set[l].size(); 130 | } 131 | } 132 | } 133 | for(unsigned l=0;l::size() const; 140 | template size_t big_qstensor< std::complex >::size() const; 141 | 142 | #endif 143 | -------------------------------------------------------------------------------- /qstensor/big_qstensor.h: -------------------------------------------------------------------------------- 1 | #ifndef BIG_QUANTUM_NUMBERED_SPARSE_TENSOR_CLASS_HEADER 2 | #define BIG_QUANTUM_NUMBERED_SPARSE_TENSOR_CLASS_HEADER 3 | 4 | #include "qstensor.h" 5 | 6 | /* 7 | Big qstensor class: 8 | 1. Purpose: 9 | Assume we need to multiply a tensor structure (composed of several tensors, 10 | say, A*B*C*D) by some other tensors (E_i, i=1,2,3,...) for a lot of times, 11 | like in any iterative solver, where A*B*C*D are identified as a "matrix". 12 | Often it happens that contracting A*B*C*D into a single tensor is very costly, 13 | probably due to its large tensor rank. And often we would be better off 14 | doing A*B*E_i*C*D, because contracting E_i in the middle makes the tensor rank 15 | small throughout the process. 16 | 17 | So, in some situation, we do not want to contract A,B,C,D first. But in order 18 | to make the the solver code more coherent, it is helpful to hold them in a 19 | single object that we can identify as a "matrix". Then we can use it to perform 20 | "matrix-vector" multiplication in the old style. 21 | big_qstensor class is designed exactly to fullfill this purpose. 22 | 23 | "matrix", when contracted, must produce indices in pairs of prime levels 24 | of 0 and 1. 25 | */ 26 | 27 | template 28 | class big_qstensor{ 29 | public: 30 | big_qstensor(){ 31 | L=nullptr; 32 | R=nullptr; 33 | size_=0; 34 | } 35 | ~big_qstensor(){} 36 | 37 | void setLeft(qstensor* Left) {L=Left; } 38 | void setRight(qstensor* Right) {R=Right;} 39 | void addMid(qstensor* m) { mid=std::move(mid*(*m)); } 40 | 41 | qstensor product(qstensor& v); 42 | qstensor diagonal(); 43 | T expec(qstensor& v); 44 | size_t size() const; 45 | 46 | private: 47 | // Left/Right environment 48 | qstensor* L; 49 | qstensor* R; 50 | qstensor mid; 51 | // (1) One site 52 | //vector< qstensor* > mid; 53 | mutable size_t size_; 54 | }; 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /qstensor/qstensor.h: -------------------------------------------------------------------------------- 1 | #ifndef QUANTUM_NUMBERED_SPARSE_TENSOR_CLASS_HEADER 2 | #define QUANTUM_NUMBERED_SPARSE_TENSOR_CLASS_HEADER 3 | 4 | #include "../util/types_and_headers.h" 5 | #include "../util/ezh5.h" 6 | #include "../linalg/lapack_wrapper.h" 7 | #include "../qtensor/qtensor_index.h" 8 | #include "../qtensor/qtensor_index_op.h" 9 | #include "../qtensor/qtensor.h" 10 | #include 11 | 12 | /* 13 | Design of the templated qstensor class: 14 | 15 | (1) qstensor's underlying storage and algorithms are provided 16 | by CTF. 17 | CTF is a library and framework for performing tensor operations, 18 | especially tensor contraction, using efficient native algorithms. 19 | https://github.com/cyclops-community/ctf/ 20 | 21 | (2) When performing qstensor contraction, Einstein summation rule is assumed. 22 | Repeated indices will be summed over. 23 | 24 | (3) All qn blocks are stored in a giant CTF tensor. They default to being dense but are really sparse 25 | */ 26 | 27 | 28 | 29 | template 30 | class qstensor{ 31 | public: 32 | //--------------------------------------------------------------------------- 33 | // Constructors -- sets up the qtensor_index 34 | qstensor(); // default constructor 35 | qstensor(arr_list arrows); // given idx_sizes, random names, default to type Link 36 | qstensor(arr_vec& arrows); // given idx_sizes, random names, default to type Link 37 | qstensor(arr_list arrows, str_list names); // given idx_sizes and names, default to type Link 38 | qstensor(arr_vec& arrows, str_vec& names); // given idx_sizes and names, default to type Link 39 | qstensor(arr_list arrows, str_list names, typ_list types); // given idx_sizes, names, and types 40 | qstensor(arr_vec& arrows, str_vec& names, typ_vec& types); // given idx_sizes, names, and types 41 | qstensor(arr_list arrows, str_list names, typ_list types, uint_list levels); // given idx_sizes, names, types, levels 42 | qstensor(arr_vec& arrows, str_vec& names, typ_vec& types, uint_vec& levels); // given idx_sizes, names, types, levels 43 | qstensor(vector& idx_vec); 44 | qstensor(vector&& idx_vec); 45 | qstensor(initializer_list idx_list); 46 | 47 | qstensor(const qstensor& other); // copy constructor 48 | qstensor(qstensor&& other); // move constructor 49 | 50 | qstensor(const qtensor& other); // copy convert constructor 51 | qstensor(qtensor&& other); // move convert constructor 52 | //--------------------------------------------------------------------------- 53 | // Destructor 54 | ~qstensor(){} 55 | //--------------------------------------------------------------------------- 56 | // set up quantum number information {(qn, qdim)} for a selected qtensor_index 57 | void addQNtoIndex(unsigned idx, quantum_number qn); 58 | //--------------------------------------------------------------------------- 59 | // Initialize legal tensor block 60 | void initBlock(); 61 | void clearBlock(); 62 | 63 | //--------------------------------------------------------------------------- 64 | // Reset 65 | void reset(vector& qidx_vec); 66 | 67 | //--------------------------------------------------------------------------- 68 | // Storage 69 | unsigned rank; 70 | vector idx_set; 71 | vector> block; //TODO: remove! 72 | vector > _block; 73 | CTF::Tensor _T; 74 | vector< qn_vec > block_index_qn; 75 | vector< int_vec > block_index_qd; 76 | vector< uint_vec > block_index_qi; 77 | unordered_map< string, unsigned > block_id_by_qn_str; 78 | bool _initted; 79 | //--------------------------------------------------------------------------- 80 | // Index help 81 | string _indices; 82 | string getIndices(); 83 | string getIndices(unordered_map &charMap); 84 | //--------------------------------------------------------------------------- 85 | // Initializer 86 | void setRandom(); 87 | void setZero(); 88 | void setOne(); 89 | 90 | //--------------------------------------------------------------------------- 91 | // Permutate 92 | void permute(uint_vec& perm); 93 | void permute(uint_list perm); 94 | 95 | //--------------------------------------------------------------------------- 96 | // Overloaded operator 97 | qstensor& operator = (const qstensor& other); // copy assignment 98 | qstensor& operator = (qstensor&& other); // move assignment 99 | qstensor& operator = (const qtensor& other); // convert copy assignment 100 | qstensor& operator = (qtensor&& other); // convert move assignment 101 | qstensor operator * (qstensor& A); // repeated indices are summed over 102 | qstensor& operator += (qstensor& A); // 103 | qstensor& operator -= (qstensor& A); // 104 | qstensor operator + (qstensor& A); // 105 | qstensor operator - (qstensor& A); // 106 | qstensor& operator *= (const T c); // scaling 107 | qstensor& operator /= (const T c); // scaling 108 | qstensor operator * (const T c); // scaling 109 | qstensor operator / (const T c); // scaling 110 | 111 | //--------------------------------------------------------------------------- 112 | // Full contraction (ends in a scalar) 113 | T contract(qstensor& A); 114 | 115 | //--------------------------------------------------------------------------- 116 | // Get diagonal subtensor 117 | // only possible when tensor indices come in "pairs", 118 | // meaning same name string but different prime level 119 | qstensor diagonal(); 120 | qstensor diagonal(index_type type); 121 | 122 | //--------------------------------------------------------------------------- 123 | // special arithmetic operations with another tensor in the same format/pattern 124 | void add(qstensor& A, T c = T(1)); 125 | T inner_product(qstensor& A); 126 | 127 | //--------------------------------------------------------------------------- 128 | // Prime level manipulation 129 | void prime(int inc=1); 130 | void primeLink(int inc=1); 131 | void primeSite(int inc=1); 132 | void mapPrime(unsigned from, unsigned to); 133 | void mapPrime(unsigned from, unsigned to, index_type type); 134 | void dag(); 135 | void conj(); 136 | 137 | //--------------------------------------------------------------------------- 138 | // Save/Load 139 | void save(string fn); 140 | void load(string fn); 141 | void save(ezh5::Node& fW); 142 | void load(ezh5::Node& fR); 143 | 144 | //--------------------------------------------------------------------------- 145 | // Get norm 146 | double norm(); 147 | double normalize(); 148 | 149 | //--------------------------------------------------------------------------- 150 | // Print 151 | void print(unsigned print_level=0); 152 | 153 | }; 154 | //convert blocks into sparse tensor 155 | template class TensorType > 156 | void blockToSparse(const TensorType &A, CTF::Tensor &M); 157 | 158 | template 159 | void idxToSparse(vector &idx_set, CTF::Tensor &M); 160 | 161 | template 162 | void getOffsets(qstensor &A, vector >& blockOffsets); 163 | 164 | /*template 165 | double calcEntropy(qstensor& S, double cutoff=1e-24){ 166 | assert(S.rank==1); assert(S._initted==true); 167 | CTF::Scalar vNEE = 0.0; 168 | for(auto block : S._block) 169 | vNEE[""] += CTF::Function([cutoff](T sg){ if(real(sg)>cutoff) return -norm(sg)*std::log(norm(sg)); else return 0.0; })(block["i"]); 170 | return vNEE; 171 | }*/ 172 | 173 | #endif 174 | -------------------------------------------------------------------------------- /qstensor/qstensor_all.h: -------------------------------------------------------------------------------- 1 | #ifndef ALL_QSTENSOR_RELATED_HEADERS 2 | #define ALL_QSTENSOR_RELATED_HEADERS 3 | 4 | //#include "qstensor_index.h" 5 | //#include "qstensor_index_op.h" 6 | #include "qstensor.h" 7 | #include "qstensor_op.h" 8 | #include "big_qstensor.h" 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /qstensor/qstensor_op.h: -------------------------------------------------------------------------------- 1 | #ifndef QUANTUM_NUMBERED_SPARSE_TENSOR_OPERATIONS_HEADER 2 | #define QUANTUM_NUMBERED_SPARSE_TENSOR_OPERATIONS_HEADER 3 | 4 | #include "../util/types_and_headers.h" 5 | #include "../linalg/lapack_wrapper.h" 6 | #include "../qtensor/qtensor_index.h" 7 | #include "../qtensor/qtensor_index_op.h" 8 | #include "qstensor.h" 9 | 10 | #define MoveFromLeft 0 11 | #define MoveFromRight 1 12 | 13 | template 14 | void qr(qstensor& A, 15 | vector& left, vector& right, 16 | qstensor& Q, qstensor& R); 17 | 18 | /*template 19 | void svd(qstensor& A, 20 | vector& left, vector& right, 21 | qstensor& U, qstensor& V, vector& S, 22 | int direction); 23 | 24 | template 25 | void svd(qstensor& A, 26 | vector& left, vector& right, 27 | qstensor& U, qstensor& V, vector& S, 28 | int direction, double cutoff);*/ 29 | 30 | template 31 | void svd(qstensor& A, 32 | vector& left, vector& right, 33 | qstensor& U, qstensor& V, qtensor& S, 34 | int direction, double cutoff=0, unsigned K=0); 35 | 36 | /*template 37 | void svd_bond(qstensor& A_left, qstensor& A_right, 38 | qtensor_index& mid, vector& S, 39 | int direction);*/ 40 | 41 | template 42 | void svd_bond(qstensor& A_left, qstensor& A_right, 43 | qtensor_index& mid, qtensor& S, 44 | int direction, double cutoff=0, long unsigned K=0); 45 | 46 | template 47 | void svd_bond(qstensor& combined, qstensor& A_left, qstensor& A_right, 48 | qtensor_index& mid, qtensor& S, 49 | int direction, double cutoff=0, long unsigned K=0); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /qtensor/big_qtensor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef BIG_QUANTUM_NUMBERED_TENSOR_CLASS 19 | #define BIG_QUANTUM_NUMBERED_TENSOR_CLASS 20 | 21 | #include "big_qtensor.h" 22 | 23 | template 24 | qtensor big_qtensor::product(qtensor& v){ 25 | // contract pattern: 26 | // L-v-mid-R 27 | qtensor res; 28 | if(L!=nullptr) res = std::move((*L)*v); 29 | if(res.rank>0) 30 | res = std::move(res*(mid)); 31 | else 32 | res = std::move(v*(mid)); 33 | if(R!=nullptr) res = std::move(res*(*R)); 34 | 35 | /*qtensor res = std::move(A*v); 36 | if(R!=nullptr) res = std::move(res*(*R));*/ 37 | 38 | res.prime(-1); 39 | return res; 40 | } 41 | template qtensor big_qtensor::product(qtensor& v); 42 | template qtensor< std::complex > big_qtensor< std::complex >::product(qtensor< std::complex >& v); 43 | 44 | 45 | template 46 | T big_qtensor::expec(qtensor& v){ 47 | // contract pattern: 48 | // L-v-mid-R 49 | /*qtensor res; 50 | if(L!=nullptr) res = std::move((*L)*v); 51 | if(res.rank>0) 52 | res = std::move(res*(mid)); 53 | else 54 | res = std::move(v*(mid)); 55 | 56 | if(R!=nullptr) res = std::move(res*(*R));*/ 57 | 58 | /*qtensor res = std::move(A*v); 59 | if(R!=nullptr) res = std::move(res*(*R));*/ 60 | 61 | //res.prime(-1); 62 | qtensor res = std::move(product(v)); 63 | return res.contract(v); 64 | } 65 | template double big_qtensor::expec(qtensor& v); 66 | template std::complex big_qtensor< std::complex >::expec(qtensor< std::complex >& v); 67 | 68 | 69 | template 70 | qtensor big_qtensor::diagonal(){ 71 | qtensor res; 72 | if(L!=nullptr) res = (*L); 73 | res = std::move(res*(mid)); 74 | 75 | if(R!=nullptr) res = std::move(res*(*R)); 76 | res = std::move(res.diagonal()); 77 | 78 | /*qtensor res; 79 | if(R==nullptr){ 80 | res = std::move(A.diagonal()); 81 | }else{ 82 | res = std::move(A*(*R)); 83 | res = std::move(res.diagonal()); 84 | //qtensor Rd = R->diagonal(); 85 | //res = std::move(A.diagonal()); 86 | //res = std::move(res*Rd); 87 | }*/ 88 | 89 | // qtensor res = std::move(A.diagonal()); 90 | 91 | return res; 92 | } 93 | template qtensor big_qtensor::diagonal(); 94 | template qtensor< std::complex > big_qtensor< std::complex >::diagonal(); 95 | 96 | template 97 | size_t big_qtensor::size() const{ 98 | if(size_ == 0){ 99 | size_ = 1; 100 | if(L!=nullptr){ 101 | for(unsigned l=0; l< L->rank; l++){ 102 | if(L->idx_set[l].level() > 0) 103 | size_ *= L->idx_set[l].size(); 104 | } 105 | } 106 | if(R!=nullptr){ 107 | for(unsigned l=0; l< R->rank; l++){ 108 | if(R->idx_set[l].level() > 0) 109 | size_ *= R->idx_set[l].size(); 110 | } 111 | } 112 | } 113 | for(unsigned l=0;l::size() const; 121 | template size_t big_qtensor< std::complex >::size() const; 122 | #endif 123 | -------------------------------------------------------------------------------- /qtensor/big_qtensor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef BIG_QUANTUM_NUMBERED_TENSOR_CLASS_HEADER 19 | #define BIG_QUANTUM_NUMBERED_TENSOR_CLASS_HEADER 20 | 21 | #include "qtensor.h" 22 | 23 | /* 24 | Big qtensor class: 25 | 1. Purpose: 26 | Assume we need to multiply a tensor structure (composed of several tensors, 27 | say, A*B*C*D) by some other tensors (E_i, i=1,2,3,...) for a lot of times, 28 | like in any iterative solver, where A*B*C*D are identified as a "matrix". 29 | Often it happens that contracting A*B*C*D into a single tensor is very costly, 30 | probably due to its large tensor rank. And often we would be better off 31 | doing A*B*E_i*C*D, because contracting E_i in the middle makes the tensor rank 32 | small throughout the process. 33 | 34 | So, in some situation, we do not want to contract A,B,C,D first. But in order 35 | to make the the solver code more coherent, it is helpful to hold them in a 36 | single object that we can identify as a "matrix". Then we can use it to perform 37 | "matrix-vector" multiplication in the old style. 38 | big_qtensor class is designed exactly to fullfill this purpose. 39 | 40 | "matrix", when contracted, must produce indices in pairs of prime levels 41 | of 0 and 1. 42 | */ 43 | 44 | template 45 | class big_qtensor{ 46 | public: 47 | big_qtensor(){ 48 | L=nullptr; 49 | R=nullptr; 50 | size_=0; 51 | } 52 | ~big_qtensor(){} 53 | 54 | void setLeft(qtensor* Left) {L=Left;} 55 | void setRight(qtensor* Right) {R=Right;} 56 | void addMid(qtensor* m) {mid=std::move(mid*(*m));} 57 | 58 | qtensor product(qtensor& v); 59 | qtensor diagonal(); 60 | T expec(qtensor& v); 61 | size_t size() const; 62 | 63 | private: 64 | // Left/Right environment 65 | qtensor* L; 66 | qtensor* R; 67 | qtensor mid; 68 | // (1) One site 69 | //vector< qtensor* > mid; 70 | mutable size_t size_; 71 | }; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /qtensor/qtensor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef QUANTUM_NUMBERED_TENSOR_CLASS_HEADER 19 | #define QUANTUM_NUMBERED_TENSOR_CLASS_HEADER 20 | 21 | #include "../util/types_and_headers.h" 22 | #include "../util/ezh5.h" 23 | #include "../linalg/lapack_wrapper.h" 24 | #include "qtensor_index.h" 25 | #include "qtensor_index_op.h" 26 | #include 27 | 28 | /* 29 | Design of the templated qtensor class: 30 | 31 | (1) qtensor's underlying storage and algorithms are provided 32 | by CTF. 33 | CTF is a library and framework for performing tensor operations, 34 | especially tensor contraction, using efficient native algorithms. 35 | https://github.com/cyclops-community/ctf/ 36 | 37 | (2) When performing qtensor contraction, Einstein summation rule is assumed. 38 | Repeated indices will be summed over. 39 | */ 40 | 41 | 42 | string indToStr(vector &indices,unordered_map &charMap); 43 | string indicesToChar(vector &indices, unordered_map &charMap); 44 | string indToStrNP(vector &indices,unordered_map &charMap); 45 | string indicesToCharNP(vector &indices, unordered_map &charMap); 46 | 47 | template 48 | class qtensor{ 49 | public: 50 | //--------------------------------------------------------------------------- 51 | // Constructors -- sets up the qtensor_index 52 | qtensor(); // default constructor 53 | qtensor(arr_list arrows); // given idx_sizes, random names, default to type Link 54 | qtensor(arr_vec& arrows); // given idx_sizes, random names, default to type Link 55 | qtensor(arr_list arrows, str_list names); // given idx_sizes and names, default to type Link 56 | qtensor(arr_vec& arrows, str_vec& names); // given idx_sizes and names, default to type Link 57 | qtensor(arr_list arrows, str_list names, typ_list types); // given idx_sizes, names, and types 58 | qtensor(arr_vec& arrows, str_vec& names, typ_vec& types); // given idx_sizes, names, and types 59 | qtensor(arr_list arrows, str_list names, typ_list types, uint_list levels); // given idx_sizes, names, types, levels 60 | qtensor(arr_vec& arrows, str_vec& names, typ_vec& types, uint_vec& levels); // given idx_sizes, names, types, levels 61 | qtensor(vector& idx_vec); 62 | qtensor(vector&& idx_vec); 63 | qtensor(initializer_list idx_list); 64 | 65 | qtensor(const qtensor& other); // copy constructor 66 | qtensor(qtensor&& other); // move constructor 67 | //--------------------------------------------------------------------------- 68 | // Destructor 69 | ~qtensor(){} 70 | //--------------------------------------------------------------------------- 71 | // set up quantum number information {(qn, qdim)} for a selected qtensor_index 72 | void addQNtoIndex(unsigned idx, quantum_number qn); 73 | //--------------------------------------------------------------------------- 74 | // Initialize legal tensor block 75 | void initBlock(); 76 | void clearBlock(); 77 | 78 | //--------------------------------------------------------------------------- 79 | // Reset 80 | void reset(vector& qidx_vec); 81 | 82 | //--------------------------------------------------------------------------- 83 | // Storage 84 | unsigned rank; 85 | vector idx_set; 86 | vector> block; //TODO: remove! 87 | vector > _block; 88 | vector< qn_vec > block_index_qn; 89 | vector< int_vec > block_index_qd; 90 | vector< uint_vec > block_index_qi; 91 | unordered_map< string, unsigned > block_id_by_qn_str; 92 | bool _initted; 93 | //--------------------------------------------------------------------------- 94 | // Index help 95 | string _indices; 96 | string getIndices(); 97 | string getIndices(unordered_map &charMap); 98 | //--------------------------------------------------------------------------- 99 | // Initializer 100 | void setRandom(); 101 | void setZero(); 102 | void setOne(); 103 | 104 | //--------------------------------------------------------------------------- 105 | // Permutate 106 | void permute(uint_vec& perm); 107 | void permute(uint_list perm); 108 | 109 | //--------------------------------------------------------------------------- 110 | // Overloaded operator 111 | qtensor& operator = (const qtensor& other); // copy assignment 112 | qtensor& operator = (qtensor&& other); // move assignment 113 | qtensor operator * (qtensor& A); // repeated indices are summed over 114 | qtensor& operator += (qtensor& A); // 115 | qtensor& operator -= (qtensor& A); // 116 | qtensor operator + (qtensor& A); // 117 | qtensor operator - (qtensor& A); // 118 | qtensor& operator *= (const T c); // scaling 119 | qtensor& operator /= (const T c); // scaling 120 | qtensor operator * (const T c); // scaling 121 | qtensor operator / (const T c); // scaling 122 | 123 | //--------------------------------------------------------------------------- 124 | // Full contraction (ends in a scalar) 125 | T contract(qtensor& A); 126 | 127 | //--------------------------------------------------------------------------- 128 | // Get diagonal subtensor 129 | // only possible when tensor indices come in "pairs", 130 | // meaning same name string but different prime level 131 | qtensor diagonal(); 132 | 133 | //--------------------------------------------------------------------------- 134 | // special arithmetic operations with another tensor in the same format/pattern 135 | void add(qtensor& A, T c = T(1)); 136 | T inner_product(qtensor& A); 137 | 138 | //--------------------------------------------------------------------------- 139 | // Prime level manipulation 140 | void prime(int inc=1); 141 | void primeLink(int inc=1); 142 | void primeSite(int inc=1); 143 | void mapPrime(unsigned from, unsigned to); 144 | void mapPrime(unsigned from, unsigned to, index_type type); 145 | void dag(); 146 | void conj(); 147 | 148 | //--------------------------------------------------------------------------- 149 | // Save/Load 150 | void save(string fn); 151 | void load(string fn); 152 | void save(ezh5::Node& fW); 153 | void load(ezh5::Node& fR); 154 | 155 | //--------------------------------------------------------------------------- 156 | // Get norm 157 | double norm(); 158 | double normalize(); 159 | 160 | //--------------------------------------------------------------------------- 161 | // Print 162 | void print(unsigned print_level=0); 163 | 164 | }; 165 | 166 | template 167 | double calcEntropy(qtensor& S, double cutoff=1e-24){ 168 | assert(S.rank==1); assert(S._initted==true); 169 | CTF::Scalar vNEE = 0.0; 170 | for(auto block : S._block) 171 | vNEE[""] += CTF::Function([cutoff](T sg){ if(real(sg)>cutoff) return -norm(sg)*std::log(norm(sg)); else return 0.0; })(block["i"]); 172 | return vNEE; 173 | } 174 | 175 | #endif 176 | -------------------------------------------------------------------------------- /qtensor/qtensor_all.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef ALL_QTENSOR_RELATED_HEADERS 19 | #define ALL_QTENSOR_RELATED_HEADERS 20 | 21 | #include "qtensor_index.h" 22 | #include "qtensor_index_op.h" 23 | #include "qtensor.h" 24 | #include "qtensor_op.h" 25 | #include "big_qtensor.h" 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /qtensor/qtensor_index.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef INDEX_CLASS_FOR_QUANTUM_NUMBERED_TENSOR 19 | #define INDEX_CLASS_FOR_QUANTUM_NUMBERED_TENSOR 20 | 21 | #include "qtensor_index.h" 22 | 23 | qtensor_index::qtensor_index(){ 24 | _arrow = Inward; 25 | _level = 0; 26 | _name = "qi"+to_string(int(1e8*thread_safe_random_double()+1e6*thread_safe_random_double())); 27 | _type = Link; 28 | setTag(); 29 | _sorted=false; 30 | } 31 | 32 | qtensor_index::qtensor_index(arrow_type arrow){ 33 | _arrow = arrow; 34 | _level = 0; 35 | _name = "qi"+to_string(int(1e8*thread_safe_random_double()+1e5*thread_safe_random_double())); 36 | _type = Link; 37 | setTag(); 38 | _sorted=false; 39 | } 40 | 41 | qtensor_index::qtensor_index(arrow_type arrow, string name){ 42 | _arrow = arrow; 43 | _level = 0; 44 | _name = name; 45 | _type = Link; 46 | setTag(); 47 | _sorted=false; 48 | } 49 | 50 | qtensor_index::qtensor_index(arrow_type arrow, string name, index_type type){ 51 | _arrow = arrow; 52 | _level = 0; 53 | _name = name; 54 | _type = type; 55 | setTag(); 56 | _sorted=false; 57 | } 58 | 59 | qtensor_index::qtensor_index(arrow_type arrow, string name, index_type type, unsigned level){ 60 | _arrow = arrow; 61 | _level = level; 62 | _name = name; 63 | _type = type; 64 | setTag(); 65 | _sorted=false; 66 | } 67 | 68 | qtensor_index::qtensor_index(const qtensor_index& other){ 69 | _arrow = other._arrow; 70 | _level = other._level; 71 | _name = other._name; 72 | _type = other._type; 73 | _qn = other._qn; 74 | _tag = other._tag; 75 | _sorted = other._sorted; 76 | } 77 | 78 | qtensor_index::qtensor_index(qtensor_index&& other){ 79 | _arrow = other._arrow; 80 | _level = other._level; 81 | _name = other._name; 82 | _type = other._type; 83 | _qn = std::move(other._qn); 84 | _tag = other._tag; 85 | _sorted = other._sorted; 86 | } 87 | 88 | qtensor_index qtensor_index::operator = (const qtensor_index& other){ 89 | if(this!=&other){ 90 | _arrow = other._arrow; 91 | _level = other._level; 92 | _name = other._name; 93 | _type = other._type; 94 | _qn = other._qn; 95 | _tag = other._tag; 96 | _sorted = other._sorted; 97 | } 98 | return *this; 99 | } 100 | 101 | bool qtensor_index::operator == (const qtensor_index& A) const{ 102 | return (_tag==A._tag && _arrow==A._arrow && _level==A._level); 103 | } 104 | 105 | bool qtensor_index::operator != (const qtensor_index& A) const{ 106 | return (_tag!=A._tag || _arrow!=A._arrow || _level!=A._level); 107 | } 108 | 109 | bool qtensor_index::operator < (const qtensor_index& A) const{ 110 | return (_tag qn, uint_vec qdim) { 37 | for (size_t i = 0; i < qn.size(); i++) { 38 | _qn.push_back(std::make_pair(qn[i], qdim[i])); 39 | } 40 | _sorted=false; 41 | setTag(); 42 | } 43 | 44 | inline void rename(string name) {_name=name; setTag();} 45 | inline void retype(index_type type) {_type=type; setTag();} 46 | inline void resize(unsigned i, unsigned size) {_qn.at(i).second=size; setTag();} 47 | inline void sortQN(){if(!_sorted && _qn.size()>1) std::sort(_qn.begin(), _qn.end(), qnCompare); _sorted=true;} 48 | inline void setTag(){ 49 | sortQN(); 50 | _tag = _name+" "+to_string(_type)+" "; 51 | for (size_t i = 0; i < _qn.size(); i++) { 52 | _tag += ("qn"+to_string(_qn[i].first)+"qdim"+to_string(_qn[i].second)+" "); 53 | } 54 | }; 55 | 56 | qtensor_index operator = (const qtensor_index& other); 57 | bool operator == (const qtensor_index& A) const; 58 | bool operator != (const qtensor_index& A) const; 59 | bool operator < (const qtensor_index& A) const; 60 | 61 | inline arrow_type arrow() const {return _arrow;} 62 | inline unsigned size() const {return _qn.size();} 63 | inline unsigned level() const {return _level;} 64 | inline string name() const {return _name;} 65 | inline index_type type() const {return _type;} 66 | inline string tag() const {return _arrow+" "+to_string(_level)+" "+_tag;} 67 | inline string tagNoArrow() const {return to_string(_level)+" "+_tag;} 68 | inline QN_t qn(unsigned i) const {return _qn.at(i).first;} 69 | inline unsigned qdim(unsigned i) const {return _qn.at(i).second;} 70 | 71 | inline void dag() { 72 | if(_arrow==Inward) 73 | _arrow=Outward; 74 | else 75 | _arrow=Inward; 76 | } 77 | 78 | inline bool similar(const qtensor_index& A){ 79 | if(_arrow != A._arrow && 80 | _tag == A._tag && 81 | ((_level== A._level+1)||(_level+1== A._level)) 82 | ){ 83 | return true; 84 | }else{ 85 | return false; 86 | } 87 | } 88 | 89 | inline bool similar(qtensor_index& A){ 90 | if(_arrow != A._arrow && 91 | _tag == A._tag && 92 | ((_level== A._level+1)||(_level+1== A._level)) 93 | ){ 94 | return true; 95 | }else{ 96 | return false; 97 | } 98 | } 99 | 100 | inline void prime(int inc=1) {_level+=inc;} 101 | inline void primeLink(int inc=1) {if(_type==Link) _level+=inc;} 102 | inline void primeSite(int inc=1) {if(_type==Site) _level+=inc;} 103 | inline void mapPrime(unsigned from, unsigned to) {if(_level==from) _level=to;} 104 | inline void mapPrime(unsigned from, unsigned to, index_type type) {if(_level==from&&_type==type) _level=to;} 105 | inline void noPrime(index_type type=All){if(type==All || _type==type) _level=0;} 106 | 107 | private: 108 | bool _sorted; 109 | arrow_type _arrow; 110 | string _name; 111 | index_type _type; 112 | unsigned _level; 113 | vector< quantum_number > _qn; 114 | string _tag; // make it hashable 115 | }; 116 | 117 | qtensor_index noPrime(qtensor_index& index); 118 | #endif 119 | -------------------------------------------------------------------------------- /qtensor/qtensor_index_op.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef INDEX_OP_CLASS_FOR_QUANTUM_NUMBERED_TENSOR 19 | #define INDEX_OP_CLASS_FOR_QUANTUM_NUMBERED_TENSOR 20 | 21 | #include "qtensor_index_op.h" 22 | 23 | void find_index_permutation(vector& from, vector& to, vector& perm){ 24 | assert(from.size()==to.size()); 25 | if(perm.size()>0) perm.clear(); 26 | // brute force O(n^2) 27 | int n = to.size(); 28 | for (int i = 0; i < n; i++) { 29 | for (int j = 0; j < n; j++) { 30 | if(to[i] == from[j]){ 31 | perm.push_back(j); 32 | break; 33 | } 34 | } 35 | } 36 | assert(int(perm.size())==n); 37 | } 38 | 39 | void index_sets_union(const vector& Ac, const vector& Bc, vector& res){ 40 | res.resize(Ac.size()+Bc.size()); 41 | vector::iterator it; 42 | vector A(Ac.begin(), Ac.end()); 43 | vector B(Bc.begin(), Bc.end()); 44 | std::sort(A.begin(), A.end()); 45 | std::sort(B.begin(), B.end()); 46 | // make sure indices are unique 47 | it = std::unique (A.begin(), A.end()); 48 | A.resize(std::distance(A.begin(),it)); 49 | it = std::unique (B.begin(), B.end()); 50 | B.resize(std::distance(B.begin(),it)); 51 | it = std::set_union(A.begin(), A.end(), B.begin(), B.end(), res.begin()); 52 | res.resize(it-res.begin()); 53 | } 54 | 55 | void index_sets_difference(const vector& Ac, const vector& Bc, vector& res){ 56 | vector::iterator it; 57 | vector A(Ac.begin(), Ac.end()); 58 | vector B(Bc.begin(), Bc.end()); 59 | // make sure indices are unique 60 | it = std::unique (A.begin(), A.end()); 61 | A.resize(std::distance(A.begin(),it)); 62 | it = std::unique (B.begin(), B.end()); 63 | B.resize(std::distance(B.begin(),it)); 64 | res.clear(); 65 | for (size_t i = 0; i < A.size(); i++) { 66 | bool duplicated = false; 67 | for (size_t j = 0; j < B.size(); j++) { 68 | if(A[i]==B[j]){ 69 | duplicated = true; 70 | break; 71 | } 72 | } 73 | if(!duplicated){ 74 | res.push_back(A[i]); 75 | } 76 | } 77 | for (size_t i = 0; i < B.size(); i++) { 78 | bool duplicated = false; 79 | for (size_t j = 0; j < A.size(); j++) { 80 | if(B[i]==A[j]){ 81 | duplicated = true; 82 | break; 83 | } 84 | } 85 | if(!duplicated){ 86 | res.push_back(B[i]); 87 | } 88 | } 89 | } 90 | 91 | void index_sets_intersection(const vector& Ac, const vector& Bc, vector& res){ 92 | res.resize(Ac.size()+Bc.size()); 93 | vector::iterator it; 94 | vector A(Ac.begin(), Ac.end()); 95 | vector B(Bc.begin(), Bc.end()); 96 | std::sort(A.begin(), A.end()); 97 | std::sort(B.begin(), B.end()); 98 | // make sure indices are unique 99 | it = std::unique (A.begin(), A.end()); 100 | A.resize(std::distance(A.begin(),it)); 101 | it = std::unique (B.begin(), B.end()); 102 | B.resize(std::distance(B.begin(),it)); 103 | it = std::set_intersection(A.begin(), A.end(), B.begin(), B.end(), res.begin()); 104 | res.resize(it-res.begin()); 105 | } 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /qtensor/qtensor_index_op.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef INDEX_OP_CLASS_FOR_QUANTUM_NUMBERED_TENSOR_HEADER 19 | #define INDEX_OP_CLASS_FOR_QUANTUM_NUMBERED_TENSOR_HEADER 20 | 21 | #include "qtensor_index.h" 22 | 23 | void find_index_permutation(vector& from, vector& to, vector& perm); 24 | 25 | void index_sets_union(const vector& Ac, const vector& Bc, vector& res); 26 | 27 | void index_sets_difference(const vector& Ac, const vector& Bc, vector& res); 28 | 29 | void index_sets_intersection(const vector& Ac, const vector& Bc, vector& res); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /qtensor/qtensor_op.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef QUANTUM_NUMBERED_TENSOR_OPERATIONS_HEADER 19 | #define QUANTUM_NUMBERED_TENSOR_OPERATIONS_HEADER 20 | 21 | #include "../util/types_and_headers.h" 22 | #include "../linalg/lapack_wrapper.h" 23 | #include "qtensor_index.h" 24 | #include "qtensor_index_op.h" 25 | #include "qtensor.h" 26 | 27 | #define MoveFromLeft 0 28 | #define MoveFromRight 1 29 | 30 | template 31 | void qr(qtensor& A, 32 | vector& left, vector& right, 33 | qtensor& Q, qtensor& R); 34 | 35 | /*template 36 | void svd(qtensor& A, 37 | vector& left, vector& right, 38 | qtensor& U, qtensor& V, vector& S, 39 | int direction); 40 | 41 | template 42 | void svd(qtensor& A, 43 | vector& left, vector& right, 44 | qtensor& U, qtensor& V, vector& S, 45 | int direction, double cutoff);*/ 46 | 47 | template 48 | void svd(qtensor& A, 49 | vector& left, vector& right, 50 | qtensor& U, qtensor& V, qtensor& S, 51 | int direction, double cutoff=0, unsigned K=0); 52 | 53 | /*template 54 | void svd_bond(qtensor& A_left, qtensor& A_right, 55 | qtensor_index& mid, vector& S, 56 | int direction);*/ 57 | 58 | template 59 | void svd_bond(qtensor& A_left, qtensor& A_right, 60 | qtensor_index& mid, qtensor& S, 61 | int direction, double cutoff=0, long unsigned K=0); 62 | 63 | template 64 | void svd_bond(qtensor& combined, qtensor& A_left, qtensor& A_right, 65 | qtensor_index& mid, qtensor& S, 66 | int direction, double cutoff=0, long unsigned K=0); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /toFix/dtensor/dtensor_view.h: -------------------------------------------------------------------------------- 1 | #ifndef DENSE_TENSOR_VIEW_CLASS_HEADER 2 | #define DENSE_TENSOR_VIEW_CLASS_HEADER 3 | 4 | #include "../util/types_and_headers.h" 5 | #include "../util/ezh5.h" 6 | #include "dtensor_index.h" 7 | #include "dtensor_index_op.h" 8 | #include "dtensor.h" 9 | 10 | template class dtensor; 11 | 12 | /* 13 | dtensor_view class is the same as dtensor class, 14 | except that it does not own the data container. 15 | */ 16 | 17 | template 18 | class dtensor_view{ 19 | public: 20 | //--------------------------------------------------------------------------- 21 | // Constructors 22 | dtensor_view(uint_list idx_sizes, str_list names, typ_list types, uint_list levels, T* data_array); // given idx_sizes, names, types, levels, data 23 | dtensor_view(uint_vec& idx_sizes, str_vec& names, typ_vec& types, uint_vec& levels, T* data_array); // given idx_sizes, names, types, levels, data 24 | dtensor_view(vector& idx_vec, T* data_array); 25 | dtensor_view(const dtensor& other); // copy constructor 26 | dtensor_view(const dtensor_view& other); // copy constructor 27 | dtensor_view(dtensor_view&& other); // move constructor 28 | //--------------------------------------------------------------------------- 29 | // Destructor 30 | ~dtensor_view(){} 31 | //--------------------------------------------------------------------------- 32 | // Update data pointer 33 | void update(T* data_array); 34 | 35 | //--------------------------------------------------------------------------- 36 | // Storage 37 | unsigned size; // total size (number of elements) of the tensor 38 | unsigned rank; // number of indices 39 | vector idx_set; // full set of tensor indices (dtensor_index.h) 40 | //tblis::tensor_view _T; // tblis::tensor_view, provide tensor functionality (does not own data) 41 | bool _initted; // initilization flag 42 | 43 | //--------------------------------------------------------------------------- 44 | // Initializer 45 | void setRandom(); 46 | void setZero(); 47 | 48 | //--------------------------------------------------------------------------- 49 | // Permutate 50 | void permute(uint_vec& perm); 51 | void permute(uint_list perm); 52 | 53 | //--------------------------------------------------------------------------- 54 | // Overloaded operator 55 | dtensor_view& operator = (const dtensor_view& other); // copy assignment 56 | dtensor_view& operator = (dtensor_view&& other); // move assignment 57 | dtensor operator * (dtensor_view& A); // repeated indices are summed over 58 | dtensor operator * (dtensor& A); // repeated indices are summed over 59 | dtensor_view& operator += (dtensor_view& A); // 60 | dtensor_view& operator += (dtensor& A); // 61 | dtensor_view& operator -= (dtensor_view& A); // 62 | dtensor_view& operator -= (dtensor& A); // 63 | dtensor operator + (dtensor_view& A); // 64 | dtensor operator + (dtensor& A); // 65 | dtensor operator - (dtensor_view& A); // 66 | dtensor operator - (dtensor& A); // 67 | dtensor_view& operator *= (const T c); // scaling 68 | dtensor_view& operator /= (const T c); // scaling 69 | dtensor operator * (const T c); // scaling 70 | dtensor operator / (const T c); // scaling 71 | 72 | //--------------------------------------------------------------------------- 73 | // Full contraction (ends in a scalar) 74 | T contract(dtensor_view& A); 75 | T contract(dtensor& A); 76 | 77 | //--------------------------------------------------------------------------- 78 | // Get diagonal subtensor 79 | // only possible when tensor indices come in "pairs", 80 | // meaning same name string but different prime level 81 | dtensor diagonal(); 82 | dtensor diagonal(index_type type); 83 | 84 | //--------------------------------------------------------------------------- 85 | // Prime level manipulation 86 | void prime(int inc=1); 87 | void primeLink(int inc=1); 88 | void primeSite(int inc=1); 89 | void mapPrime(unsigned from, unsigned to); 90 | void mapPrime(unsigned from, unsigned to, index_type type); 91 | 92 | void dag(){}; 93 | void conj(); 94 | 95 | //--------------------------------------------------------------------------- 96 | // Save/Load 97 | void save(std::string fn); 98 | // void load(std::string fn); 99 | 100 | //--------------------------------------------------------------------------- 101 | // Get norm 102 | double norm(); 103 | double normalize(); 104 | 105 | //--------------------------------------------------------------------------- 106 | // Print 107 | void print(unsigned print_level=0); 108 | 109 | }; 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /toFix/linalg/tensor_cg.cpp: -------------------------------------------------------------------------------- 1 | #ifndef DENSE_TENSOR_BASED_CG_SOLVER 2 | #define DENSE_TENSOR_BASED_CG_SOLVER 3 | 4 | #include "tensor_cg.h" 5 | 6 | template 7 | void elemWiseDivide(dtensor& A, dtensor& B){ 8 | assert(1==2); 9 | /*assert(A._initted && B._initted); 10 | assert(A.size == B.size); 11 | for (size_t i = 0; i < A.size; i++) { 12 | if( B._T.data()[i]!=T(0) && B._T.data()[i]>1e-16 ) 13 | A._T.data()[i] = A._T.data()[i]/B._T.data()[i]; 14 | }*/ 15 | } 16 | template void elemWiseDivide(dtensor& A, dtensor& B); 17 | template void elemWiseDivide(dtensor< std::complex >& A, dtensor< std::complex >& B); 18 | 19 | 20 | template 21 | void elemWiseDivide(qtensor& A, qtensor& B){ 22 | assert(A._initted && B._initted); 23 | assert(A.rank == B.rank); 24 | for (auto i = A.block_id_by_qn_str.begin(); i != A.block_id_by_qn_str.end(); ++i){ 25 | string qn_str = i->first; 26 | unsigned A_id = i->second; 27 | if(B.block_id_by_qn_str.find(qn_str)!=B.block_id_by_qn_str.end()){ 28 | unsigned B_id = B.block_id_by_qn_str.at(qn_str); 29 | assert(A.block[A_id].size() == B.block[B_id].size()); 30 | for (size_t j = 0; j < A.block[A_id].size(); j++) { 31 | if( B.block[B_id][j]!=T(0) ) 32 | A.block[A_id][j] = A.block[A_id][j]/B.block[B_id][j]; 33 | } 34 | } 35 | } 36 | } 37 | template void elemWiseDivide(qtensor& A, qtensor& B); 38 | template void elemWiseDivide(qtensor< std::complex >& A, qtensor< std::complex >& B); 39 | 40 | 41 | template class BigTensorType, template class TensorType1, template class TensorType2> 42 | int tensor_CG(BigTensorType& A, TensorType1& x, TensorType2& b, int max_iter, double tol, bool preconditioning){ 43 | TensorType1 D, t1, t2; 44 | if(preconditioning){ 45 | D = std::move(A.diagonal()); 46 | // uint_vec perm; 47 | // find_index_permutation(D.idx_set, b.idx_set, perm); 48 | // D.permute(perm); 49 | } 50 | T resid, alpha, beta, rho, rho_1, normb; 51 | normb = b.norm(); 52 | TensorType1 r, p, z, q; 53 | t1 = std::move(A.product(x)); 54 | r = std::move(b - t1); 55 | if (normb == 0.0) 56 | normb = 1; 57 | if ((resid = r.norm() / normb) <= tol) { 58 | return 0; 59 | } 60 | for (int i = 1; i <= max_iter; i++){ 61 | z = r; 62 | if(preconditioning) elemWiseDivide(z,D); 63 | if(preconditioning){ 64 | r.dag(); r.conj(); 65 | rho = r.contract(z); 66 | r.dag(); r.conj(); 67 | }else{ 68 | rho = r.norm(); 69 | rho *= rho; 70 | } 71 | if(i==1) 72 | p = z; 73 | else{ 74 | beta = rho / rho_1; 75 | t1 = std::move(p * beta); p = std::move(z + t1); 76 | } 77 | q = std::move(A.product(p)); p.conj(); 78 | alpha = rho / p.contract(q); q.dag(); p.conj(); 79 | t1 = std::move(p * alpha); x += t1; 80 | t1 = std::move(q * alpha); r -= t1; 81 | if ((resid = r.norm() / normb) <= tol) { 82 | return 0; 83 | } 84 | rho_1 = rho; 85 | // std::cout << "resid = " << resid << " " << i << " " << alpha << " " << beta << '\n'; 86 | } 87 | return 1; 88 | } 89 | template int tensor_CG(big_dtensor& A, dtensor& x, dtensor& b, int max_iter, double tol, bool preconditioning); 90 | template int tensor_CG(big_dtensor< std::complex >& A, dtensor< std::complex >& x, dtensor< std::complex >& b, int max_iter, double tol, bool preconditioning); 91 | template int tensor_CG(big_dtensor& A, dtensor& x, dtensor_view& b, int max_iter, double tol, bool preconditioning); 92 | template int tensor_CG(big_dtensor< std::complex >& A, dtensor< std::complex >& x, dtensor_view< std::complex >& b, int max_iter, double tol, bool preconditioning); 93 | 94 | template int tensor_CG(big_qtensor& A, qtensor& x, qtensor& b, int max_iter, double tol, bool preconditioning); 95 | template int tensor_CG(big_qtensor< std::complex >& A, qtensor< std::complex >& x, qtensor< std::complex >& b, int max_iter, double tol, bool preconditioning); 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /toFix/linalg/tensor_cg.h: -------------------------------------------------------------------------------- 1 | #ifndef DENSE_TENSOR_BASED_CG_SOLVER_HEADER 2 | #define DENSE_TENSOR_BASED_CG_SOLVER_HEADER 3 | 4 | #include "../dtensor/dtensor_index.h" 5 | #include "../dtensor/dtensor_index_op.h" 6 | #include "../dtensor/dtensor.h" 7 | #include "../dtensor/dtensor_view.h" 8 | #include "../dtensor/big_dtensor.h" 9 | 10 | #include "../qtensor/qtensor_index.h" 11 | #include "../qtensor/qtensor_index_op.h" 12 | #include "../qtensor/qtensor.h" 13 | #include "../qtensor/big_qtensor.h" 14 | 15 | template 16 | void elemWiseDivide(dtensor& A, dtensor& B); 17 | 18 | template 19 | void elemWiseDivide(qtensor& A, qtensor& B); 20 | 21 | // CG, optional Jacobi Preconditioner 22 | template class BigTensorType, template class TensorType1, template class TensorType2> 23 | int tensor_CG(BigTensorType& A, TensorType1& x, TensorType2& b, int max_iter, double tol, bool preconditioning=false); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /util/QN.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef QN_TYPE_HEADER 19 | #define QN_TYPE_HEADER 20 | #include 21 | 22 | // describes a system with 1 abelian quantum number 23 | class QN_t_1 { 24 | 25 | //using qtype = int; 26 | using qtype = std::valarray; 27 | public: 28 | QN_t_1(): qn(0) {}; 29 | QN_t_1(qtype qn_in): qn(qn_in) {}; 30 | QN_t_1(int qn_in):qn({qn_in}) {}; 31 | QN_t_1(std::initializer_list qn_list): qn(qn_list){}; 32 | 33 | inline QN_t_1 operator * (const QN_t_1& A) const{ return {qn*A.qn}; } 34 | inline QN_t_1 operator + (const QN_t_1& A) const{ return {qn+A.qn}; } 35 | //inline QN_t_1 operator + (const QN_t_1 A) const{ return {qn+A.qn}; } 36 | inline QN_t_1 operator - (const QN_t_1& A) const{ return {qn-A.qn};}; 37 | inline QN_t_1 operator - (){ return {-qn};}; 38 | QN_t_1& operator += (const QN_t_1& A){ qn+=A.qn; return *this; } 39 | QN_t_1& operator -= (const QN_t_1& A){ qn-=A.qn; return *this; } 40 | inline bool operator == (const QN_t_1& rhs)const{ 41 | assert(rhs.qn.size()==qn.size()); 42 | return (qn == rhs.qn).sum()==qn.size(); 43 | } 44 | inline bool operator != (const QN_t_1& rhs)const{ return !(*this == rhs); } 45 | inline bool operator < (const QN_t_1& rhs)const{ 46 | //return qn < rhs.qn; 47 | return qn[0] < rhs.qn[0]; 48 | } 49 | 50 | /*qtype operator ()() const{ 51 | * return qn; 52 | * } */ 53 | 54 | friend std::ostream& operator<<(std::ostream &os, const QN_t_1 &A){ 55 | os << "("; 56 | for(auto c: A.qn) 57 | os<< c <<","; 58 | os<< ")"; 59 | return os; 60 | } 61 | 62 | //Note: illegal to inject to_string customization into std namespace because it isn't 63 | friend std::string to_string(const QN_t_1& A){ 64 | std::string s; 65 | for(auto c: A.qn) s+=std::to_string(c)+"|"; 66 | return s; 67 | } 68 | 69 | qtype qn; 70 | }; 71 | namespace std { 72 | template <> struct hash{ 73 | size_t operator()(const QN_t_1& A) const noexcept{ 74 | return hash{}(to_string(A)); 75 | } 76 | }; 77 | } 78 | // describes a system with 2 abelian quantum number 79 | class QN_t_2 { 80 | 81 | //using qtype = int; 82 | using qtype = std::valarray; 83 | public: 84 | QN_t_2(): qn({0,0}) {}; 85 | QN_t_2(int qn_in):qn({qn_in,0}) {assert(qn_in==0);}; 86 | QN_t_2(qtype qn_in): qn(qn_in) {}; 87 | QN_t_2(std::initializer_list qn_list): qn(qn_list){}; 88 | 89 | inline QN_t_2 operator * (const QN_t_2& A) const{ return {qn*A.qn}; } 90 | inline QN_t_2 operator + (const QN_t_2& A) const{ return {qn+A.qn}; } 91 | inline QN_t_2 operator - (const QN_t_2& A) const{ return {qn-A.qn};}; 92 | inline QN_t_2 operator - (){ return {-qn};}; 93 | QN_t_2& operator += (const QN_t_2& A){ qn+=A.qn; return *this; } 94 | QN_t_2& operator -= (const QN_t_2& A){ qn-=A.qn; return *this; } 95 | inline bool operator == (const QN_t_2& rhs)const{ 96 | assert(rhs.qn.size()==qn.size()); 97 | return (qn[0] == rhs.qn[0]) && (qn[1]==rhs.qn[1]); 98 | } 99 | inline bool operator != (const QN_t_2& rhs)const{ return !(*this == rhs); } 100 | inline bool operator < (const QN_t_2& rhs)const{ 101 | //return qn < rhs.qn; 102 | //return qn[0] < rhs.qn[0]; 103 | return std::make_pair(qn[0],qn[1]) < std::make_pair(rhs.qn[0],rhs.qn[1]); 104 | } 105 | 106 | /*qtype operator ()() const{ 107 | * return qn; 108 | * } */ 109 | 110 | friend std::ostream& operator<<(std::ostream &os, const QN_t_2 &A){ 111 | std::string s = ""; 112 | for(auto c: A.qn) 113 | s+= to_string(c)+","; 114 | s.back()=')'; 115 | os<<"("< struct hash{ 130 | size_t operator()(const QN_t_2& A) const noexcept{ 131 | return hash{}(to_string(A)); 132 | } 133 | }; 134 | } 135 | #endif 136 | -------------------------------------------------------------------------------- /util/ezh5.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef EZH5_H 19 | #define EZH5_H 20 | 21 | #include 22 | #include "hdf5.h" 23 | #include 24 | #include 25 | 26 | namespace ezh5{ 27 | /////////////////////////// 28 | class ID{ 29 | public: 30 | hid_t id; 31 | ID(): id(-1) {} 32 | ID(hid_t id_in) : id(id_in) {} 33 | ~ID(){} 34 | }; 35 | /////////////////////////// 36 | class Node :public ID 37 | { 38 | public: 39 | hid_t pid; 40 | std::string path; 41 | bool verbose_; 42 | 43 | Node(){verbose_ = false;} 44 | Node(hid_t pid_in, const std::string& path_in, bool verbose=false): ID(-1), pid(pid_in), path(path_in){ 45 | verbose_ = verbose; 46 | if(verbose_) std::cout<<"creating "< Node& operator = (T val); 56 | template Node& operator >> (T& val); 57 | //////// 58 | template Node& operator = (std::vector& vec); 59 | template Node& operator >> (std::vector& vec); 60 | //////// 61 | template Node& operator = (Eigen::Matrix& m); 62 | template Node& operator >> (Eigen::Matrix& m); 63 | //////// 64 | ~Node(){ 65 | if(verbose_) std::cout<<"closing "<id>0) 67 | { 68 | H5Gclose(this->id); 69 | this->id = -1; 70 | } 71 | } 72 | }; 73 | /////////////////////////// 74 | class File : public Node 75 | { 76 | public: 77 | File(const std::string& path, unsigned flags, bool verbose = false); 78 | 79 | ~File() 80 | { 81 | H5Fclose(this->id); 82 | this->id = -1; 83 | } 84 | }; 85 | /////////////////////////// 86 | } 87 | 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /util/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef BASIC_TIMER 19 | #define BASIC_TIMER 20 | 21 | #include "types_and_headers.h" 22 | 23 | /*// Timer 24 | struct timeval _tval; 25 | double get_clock() { 26 | struct timeval _tval; int ok; 27 | ok = gettimeofday(&_tval, 0); 28 | if (ok<0) { std::printf("gettimeofday error");} 29 | return (_tval.tv_sec * 1.0 + _tval.tv_usec * 1.0E-6); 30 | }*/ 31 | #pragma once 32 | #include 33 | class Timer 34 | { 35 | public: 36 | struct timeval start, end; 37 | struct timezone tz; 38 | double timeSpent; 39 | string name; 40 | 41 | Timer(string tempName) : name(tempName) 42 | { 43 | timeSpent=0.; 44 | 45 | } 46 | 47 | 48 | void Start() 49 | { 50 | gettimeofday(&start, &tz); 51 | } 52 | 53 | void Stop() 54 | { 55 | gettimeofday(&end, &tz); 56 | timeSpent += (double)(end.tv_sec-start.tv_sec) + 57 | 1.0e-6*(double)(end.tv_usec-start.tv_usec); 58 | } 59 | 60 | void Clear() 61 | { 62 | timeSpent=0.0; 63 | } 64 | 65 | double Time() 66 | { 67 | return timeSpent; 68 | 69 | } 70 | 71 | }; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /util/types_and_headers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Ryan Levy, Xiongjie Yu, and Bryan K. Clark 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef BASIC_DATA_TYPES_AND_HEADER 19 | #define BASIC_DATA_TYPES_AND_HEADER 20 | 21 | //------------------------------------------------------------------------------ 22 | // Standard headers 23 | //------------------------------------------------------------------------------ 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include "omp.h" 42 | //------------------------------------------------------------------------------ 43 | using std::vector; 44 | using std::pair; 45 | using std::string; 46 | using std::to_string; 47 | using std::set; 48 | using std::map; 49 | using std::unordered_set; 50 | using std::unordered_map; 51 | using std::initializer_list; 52 | using std::complex; 53 | //------------------------------------------------------------------------------ 54 | 55 | //------------------------------------------------------------------------------ 56 | // External library 1 -- TBLIS -- necessary 57 | //------------------------------------------------------------------------------ 58 | // By Devin Matthews, et al. 59 | // https://github.com/devinamatthews/tblis 60 | // Intro: 61 | // TBLIS is a library and framework for performing tensor operations, 62 | // especially tensor contraction, using efficient native algorithms. 63 | // In other words, TBLIS does not need tensor transposition to perform tensor 64 | // contraction. 65 | // In comparison, a popular but not optimal tensor contraction strategy consists 66 | // of 3 steps: transposition, d/s/zgemm, transposition. 67 | // However, TBLIS does not support sparse tensor (at least for now). 68 | //#include "tblis.h" 69 | //typedef vector len_vec; 70 | //typedef vector lab_vec; 71 | //------------------------------------------------------------------------------ 72 | 73 | 74 | //------------------------------------------------------------------------------ 75 | // External library 2 -- Eigen -- needed, but only for conducting easier tests 76 | //------------------------------------------------------------------------------ 77 | // http://eigen.tuxfamily.org 78 | #include 79 | //------------------------------------------------------------------------------ 80 | 81 | 82 | //------------------------------------------------------------------------------ 83 | // External library 3 -- HDF5 -- required when saving/loading data 84 | //------------------------------------------------------------------------------ 85 | // Check https://support.hdfgroup.org/HDF5/ for instructions on 86 | // how to install HDF5 87 | #include "hdf5.h" 88 | //------------------------------------------------------------------------------ 89 | // For easier user interface of HDF5 functions, a wrapper called "EZH5" is used. 90 | // By M. Chen 91 | // https://github.com/mileschen360/ezh5 92 | //------------------------------------------------------------------------------ 93 | 94 | 95 | //------------------------------------------------------------------------------ 96 | // External library 4 -- HPTT -- optional 97 | //------------------------------------------------------------------------------ 98 | // By Paul Springer 99 | // https://github.com/springer13/hptt 100 | // Intro: 101 | // HPTT is a high-performance C++ library for out-of-place tensor transpositions. 102 | // Notice: 103 | // Tensor transposition is used to reshape tensors before sending them to QR/SVD. 104 | // If enabled, tensor transposition calls will be sent to HPTT driver. 105 | // If not enabled, tensor transposition will be sent to a not optimal function. 106 | #ifdef USE_HPTT 107 | //#include 108 | #endif 109 | //------------------------------------------------------------------------------ 110 | 111 | 112 | //------------------------------------------------------------------------------ 113 | // Single Abelian quantum number 114 | // first: qn; second: dimension 115 | //------------------------------------------------------------------------------ 116 | #include "QN.h" 117 | //typedef int QN_t; 118 | //typedef QN_t_1 QN_t; 119 | typedef QN_t_2 QN_t; 120 | typedef pair quantum_number; 121 | //------------------------------------------------------------------------------ 122 | // For sorting quantum numbers by qn 123 | inline bool qnCompare(const quantum_number& qn1, const quantum_number& qn2) { 124 | return qn1.first < qn2.first; 125 | } 126 | // For sorting singular values of different quantum blocks 127 | inline bool pairCompare(const pair& p1, const pair& p2) { 128 | return p1.first > p2.first; 129 | } 130 | //------------------------------------------------------------------------------ 131 | 132 | 133 | //------------------------------------------------------------------------------ 134 | // Enum 135 | //------------------------------------------------------------------------------ 136 | // Index type 137 | //------------------------------------------------------------------------------ 138 | enum index_type {Link, Site,All}; 139 | //------------------------------------------------------------------------------ 140 | // Arrow type, for qtensor 141 | //------------------------------------------------------------------------------ 142 | enum arrow_type {Inward, Outward}; 143 | //------------------------------------------------------------------------------ 144 | 145 | 146 | //------------------------------------------------------------------------------ 147 | // For svd, and sweeping procedures 148 | //------------------------------------------------------------------------------ 149 | #define MoveFromLeft 0 150 | #define MoveFromRight 1 151 | //------------------------------------------------------------------------------ 152 | 153 | 154 | //------------------------------------------------------------------------------ 155 | // Deal with complex conjugation in class template 156 | inline double cconj(double val) {return val;} 157 | inline std::complex cconj(std::complex val) {return std::conj(val);} 158 | //------------------------------------------------------------------------------ 159 | 160 | 161 | //------------------------------------------------------------------------------ 162 | // Thread safe random numbers 163 | //------------------------------------------------------------------------------ 164 | inline double thread_safe_random_double() { 165 | // static thread_local std::mt19937 generator(std::random_device{}()); 166 | static thread_local std::mt19937 generator; 167 | std::uniform_real_distribution distribution(0, 1); 168 | return distribution(generator); 169 | } 170 | //------------------------------------------------------------------------------ 171 | 172 | 173 | //------------------------------------------------------------------------------ 174 | // Deal with complex random numbers in class template 175 | //------------------------------------------------------------------------------ 176 | inline void random_array(double* val, unsigned size){ 177 | for (size_t i = 0; i < size; i++) { 178 | val[i] = 2*(thread_safe_random_double() - 0.5); 179 | } 180 | } 181 | inline void random_array(std::complex* val, unsigned size){ 182 | for (size_t i = 0; i < size; i++) { 183 | val[i] = std::complex (2*(thread_safe_random_double() - 0.5), 2*(thread_safe_random_double() - 0.5)); 184 | } 185 | } 186 | //------------------------------------------------------------------------------ 187 | 188 | 189 | //------------------------------------------------------------------------------ 190 | // short hand 191 | //------------------------------------------------------------------------------ 192 | typedef initializer_list uint_list; 193 | typedef initializer_list int_list; 194 | typedef initializer_list str_list; 195 | typedef initializer_list arr_list; 196 | typedef initializer_list typ_list; 197 | typedef vector uint_vec; 198 | typedef vector int_vec; 199 | typedef vector str_vec; 200 | typedef vector arr_vec; 201 | typedef vector typ_vec; 202 | typedef vector qn_vec; 203 | //------------------------------------------------------------------------------ 204 | 205 | //------------------------------------------------------------------------------ 206 | // MPI utilities 207 | //------------------------------------------------------------------------------ 208 | extern std::ostream perr; 209 | extern std::ostream pout; 210 | //------------------------------------------------------------------------------ 211 | #endif 212 | --------------------------------------------------------------------------------