From 51829d392e1cac3d57946a6b0ee6d836f3bf6cc3 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Thu, 29 Mar 2018 10:16:52 -0400 Subject: [PATCH 01/41] Update CMakeLists.txt: MinGW include DLL --- CMakeLists.txt | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e394c9..28006b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ # cmake .. -G "MSYS Makefiles" -DPYTHON_EXECUTABLE=C:/Users/user/Anaconda3/python.exe # + cmake_minimum_required(VERSION 3.5) project(pitensor) @@ -161,25 +162,24 @@ elseif(MSYS AND MINGW) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_RELEASE}") - if (NOT DEFINED OPENBLAS_ROOT) + if (NOT DEFINED MINGW_ROOT) + set(MINGW_ROOT "$ENV{MINGW_PREFIX}") if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8) - set(OPENBLAS_ROOT "/mingw64") add_definitions(-DMS_WIN64) elseif(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 4) - set(OPENBLAS_ROOT "/mingw32") else() message(FATAL_ERROR "Unsupported pointer size") endif() endif() - target_include_directories(pitensor PUBLIC "${OPENBLAS_ROOT}/include/OpenBLAS") + target_include_directories(pitensor PUBLIC "${MINGW_ROOT}/include/OpenBLAS") find_library(OPENBLAS_LIBRARY NAMES openblas - HINTS "${OPENBLAS_ROOT}/lib" + HINTS "${MINGW_ROOT}/lib" ) set(ITENSOR_PLATFORM openblas) set(ITENSOR_BLAS_LAPACK_LIBFLAGS "${OPENBLAS_LIBRARY}") - set(ITENSOR_BLAS_LAPACK_INCLUDEFLAGS "-I${OPENBLAS_ROOT}/include/OpenBLAS") + set(ITENSOR_BLAS_LAPACK_INCLUDEFLAGS "-I${MINGW_ROOT}/include/OpenBLAS") target_link_libraries(pitensor PRIVATE @@ -188,13 +188,28 @@ elseif(MSYS AND MINGW) ) target_link_libraries(pitensor PRIVATE - # TODO(kyungminlee): dynamically link libraries and include DLL files in setup.py - general "-static -static-libgcc -static-libstdc++" # statically link all libraries (without needing DLLs) - general "-Wl,-Bstatic" general "${OPENBLAS_LIBRARY}" general gfortran general quadmath ) + + file(GLOB libopenblas_dll "${MINGW_ROOT}/bin/libopenblas*.dll") + file(GLOB libwinpthread_dll "${MINGW_ROOT}/bin/libwinpthread*.dll") + file(GLOB libgfortran_dll "${MINGW_ROOT}/bin/libgfortran*.dll") + file(GLOB libquadmath_dll "${MINGW_ROOT}/bin/libquadmath*.dll") + file(GLOB libstdcpp_dll "${MINGW_ROOT}/bin/libstdc++*.dll") + file(GLOB libgcc_dll "${MINGW_ROOT}/bin/libgcc*.dll") + + add_custom_target(DllBinaries + COMMAND ${CMAKE_COMMAND} -E copy "${libopenblas_dll}" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" + COMMAND ${CMAKE_COMMAND} -E copy "${libwinpthread_dll}" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" + COMMAND ${CMAKE_COMMAND} -E copy "${libgfortran_dll}" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" + COMMAND ${CMAKE_COMMAND} -E copy "${libquadmath_dll}" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" + COMMAND ${CMAKE_COMMAND} -E copy "${libstdcpp_dll}" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" + COMMAND ${CMAKE_COMMAND} -E copy "${libgcc_dll}" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" + ) + + add_dependencies(pitensor DllBinaries) elseif(UNIX) set(CMAKE_AR "gcc-ar") set(CMAKE_RANLIB "gcc-ranlib") @@ -273,7 +288,7 @@ ExternalProject_Add(ITensor_external CONFIGURE_COMMAND "${CMAKE_COMMAND}" -E copy "${PITENSOR_DEPENDENCY_DIR}/options.mk" "${PITENSOR_DEPENDENCY_DIR}/ITensor/options.mk" - BUILD_COMMAND "make" + BUILD_COMMAND "${CMAKE_MAKE_PROGRAM}" INSTALL_COMMAND "" WORKING_DIRECTORY "${PITENSOR_DEPENDENCY_DIR}/ITensor" ) From 8252083376c33164b939397f9265d0061bfbe5a6 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Thu, 29 Mar 2018 22:03:23 -0400 Subject: [PATCH 02/41] Updates --- src/itensor/mps/autompo.h.cc | 1 + src/itensor/mps/sites/spinone.h.cc | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/itensor/mps/autompo.h.cc b/src/itensor/mps/autompo.h.cc index b053809..dec2b18 100644 --- a/src/itensor/mps/autompo.h.cc +++ b/src/itensor/mps/autompo.h.cc @@ -108,4 +108,5 @@ void pitensor::mps::autompo(pybind11::module& module) _init(module); initSiteTerm(module); initHTerm(module); + initAutoMPO(module); } diff --git a/src/itensor/mps/sites/spinone.h.cc b/src/itensor/mps/sites/spinone.h.cc index 264b220..05b4290 100644 --- a/src/itensor/mps/sites/spinone.h.cc +++ b/src/itensor/mps/sites/spinone.h.cc @@ -6,6 +6,26 @@ namespace py = pybind11; using namespace itensor; +static inline +auto +initSpinOne(pybind11::module& module) +{ + using Type = SpinOne; + py::class_ type(module, "SpinOne"); + + type.def(py::init<>()); + type.def(py::init(), + py::arg("N"), + py::arg("args")=Args::global()); + type.def(py::init const &>()); + + // TODO: how should I treat istream? + type + .def("read", &Type::read) + ; + return type; +} + static inline auto initSpinOneSite(pybind11::module& module) @@ -29,6 +49,5 @@ initSpinOneSite(pybind11::module& module) void pitensor::mps::sites::spinone(pybind11::module& module) { - py::class_ typeSpinOne(module, "SpinOne"); auto typeSpinOneSite = initSpinOneSite(module); } From f5ba7bd4f724cd4418c7b29f222dfb32432710cc Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Thu, 29 Mar 2018 23:12:17 -0400 Subject: [PATCH 03/41] An example added. --- example/example.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 example/example.py diff --git a/example/example.py b/example/example.py new file mode 100644 index 0000000..4b5850d --- /dev/null +++ b/example/example.py @@ -0,0 +1,26 @@ +import pitensor + +def main(): + N = 100; + sites = pitensor.SpinHalf(N); + psi = pitensor.MPS(sites) + ampo = pitensor.AutoMPO(sites) + for j in range(1, N): + hz = pitensor.HTerm(1.0, [pitensor.SiteTerm("Sz", j), pitensor.SiteTerm("Sz", j+1)]) + hp = pitensor.HTerm(0.5, [pitensor.SiteTerm("S+", j), pitensor.SiteTerm("S-", j+1)]) + hm = pitensor.HTerm(0.5, [pitensor.SiteTerm("S-", j), pitensor.SiteTerm("S+", j+1)]) + + ampo.add(hz) + ampo.add(hp) + ampo.add(hm) + + H = pitensor.toMPO(ampo) + + sweeps = pitensor.Sweeps(5); + sweeps.maxm = [10, 40, 100, 200, 200] + sweeps.cutoff = 1E-8 + + energy = pitensor.dmrg(psi, H, sweeps, pitensor.Args(Quiet=True)) + +if __name__=='__main__': + main() From d1772a8679dd2a10e4e9677bb85ff1b58a63326d Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Thu, 29 Mar 2018 23:13:27 -0400 Subject: [PATCH 04/41] Fixed SpinOne.h.cc --- src/itensor/mps/sites/spinone.h.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/itensor/mps/sites/spinone.h.cc b/src/itensor/mps/sites/spinone.h.cc index 05b4290..acb48a2 100644 --- a/src/itensor/mps/sites/spinone.h.cc +++ b/src/itensor/mps/sites/spinone.h.cc @@ -49,5 +49,6 @@ initSpinOneSite(pybind11::module& module) void pitensor::mps::sites::spinone(pybind11::module& module) { + auto typeSpinOne = initSpinOne(module); auto typeSpinOneSite = initSpinOneSite(module); } From 8c038393ce03d6da217fdf4bc3167224bee92b4f Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Thu, 29 Mar 2018 23:13:54 -0400 Subject: [PATCH 05/41] Update sweeps.h.cc --- src/itensor/mps/sweeps.h.cc | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/itensor/mps/sweeps.h.cc b/src/itensor/mps/sweeps.h.cc index 2eca5b2..08a8892 100644 --- a/src/itensor/mps/sweeps.h.cc +++ b/src/itensor/mps/sweeps.h.cc @@ -69,7 +69,36 @@ initSweeps(pybind11::module& module) (int (Sweeps::*)(int, int)) &Sweeps::setmaxm) // TODO: bound check .def("__repr__", [](Sweeps const & obj) { std::stringstream ss; ss << obj; return ss.str(); }) - // TODO cutoff + .def_property("cutoff", + [](Sweeps const & self) -> std::vector { + std::vector res; + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + res.push_back(self.cutoff(i)); + } + return res; + }, + [](Sweeps & self, py::object obj) { // Overloading (list vs single Real) + if (py::isinstance(obj)) { + if (py::list(obj).size() != self.nsweep()) { + throw std::length_error("Length of the list does not match the number of sweeps"); + } + + int i = 0; + for (auto const & item : py::list(obj)) { + Real r = item.cast(); // this does type check + self.setcutoff(i, r); + ++i; + } + } else if (py::isinstance(obj)) { + Real v = obj.cast(); + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + self.setcutoff(i, v); + } + } else { + throw std::domain_error("Unsupported type"); + } + } + ) // TODO noise // TODO niter // TODO write From ae3459b2b5c55bbdd6c2651a744702f993f01f08 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Thu, 29 Mar 2018 23:14:32 -0400 Subject: [PATCH 06/41] Update dmrg.h.cc: DMRGWorker added, but not used. --- src/itensor/mps/dmrg.h.cc | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/itensor/mps/dmrg.h.cc b/src/itensor/mps/dmrg.h.cc index 3b7123a..ab36f41 100644 --- a/src/itensor/mps/dmrg.h.cc +++ b/src/itensor/mps/dmrg.h.cc @@ -106,9 +106,38 @@ _init(pybind11::module& module) py::arg("obs"), py::arg("args")=Global::args()) ; +} - // TODO DMRGWorker +template +static inline +void +_initDMRGWorker(pybind11::module& module) +{ + module + /* + .def("DMRGWorker", + (Real (*)(MPSt &, + LocalOpT &, + Sweeps const &, + Args const &)) &DMRGWorker, + py::arg("psi"), + py::arg("PH"), + py::arg("sweeps"), + py::arg("args")=Global::args()) + .def("DMRGWorker", + (Real (*)(MPSt &, + LocalOpT &, + Sweeps const &, + DMRGObserver &, + Args const &)) &DMRGWorker, + py::arg("psi"), + py::arg("PH"), + py::arg("sweeps"), + py::arg("obs"), + py::arg("args")=Global::args()) + */ + ; } @@ -116,4 +145,11 @@ void pitensor::mps::dmrg(pybind11::module& module) { _init(module); _init(module); + // TODO: find all combinations? all relevant classes? +#if 0 + _initDMRGWorker>(module); + _initDMRGWorker>(module); + _initDMRGWorker>(module); + _initDMRGWorker>(module); +#endif } From e2d6070677b85b2bb779844bb5e2b64a3b3236fa Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Thu, 29 Mar 2018 23:28:29 -0400 Subject: [PATCH 07/41] Update sweeps.h.cc --- src/itensor/mps/sweeps.h.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/itensor/mps/sweeps.h.cc b/src/itensor/mps/sweeps.h.cc index 08a8892..db8c30c 100644 --- a/src/itensor/mps/sweeps.h.cc +++ b/src/itensor/mps/sweeps.h.cc @@ -82,7 +82,6 @@ initSweeps(pybind11::module& module) if (py::list(obj).size() != self.nsweep()) { throw std::length_error("Length of the list does not match the number of sweeps"); } - int i = 0; for (auto const & item : py::list(obj)) { Real r = item.cast(); // this does type check @@ -99,8 +98,9 @@ initSweeps(pybind11::module& module) } } ) - // TODO noise - // TODO niter + // TODO noise (peculiar behavior with single argument) + // TODO niter (peculiar behavior with single argument) + // TODO read // TODO write ; } @@ -108,4 +108,7 @@ initSweeps(pybind11::module& module) void pitensor::mps::sweeps(pybind11::module& module) { initSweeps(module); + // TODO RampM + // TODO ExpM + // TODO sweepnext and sweepnext1 } From d97fffe53b3ff44f797fc487723ed6ee72995c9b Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Thu, 29 Mar 2018 23:29:30 -0400 Subject: [PATCH 08/41] Update example.py --- example/example.py | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/example/example.py b/example/example.py index 4b5850d..37b344b 100644 --- a/example/example.py +++ b/example/example.py @@ -1,26 +1,32 @@ +import numpy as np import pitensor def main(): - N = 100; - sites = pitensor.SpinHalf(N); - psi = pitensor.MPS(sites) - ampo = pitensor.AutoMPO(sites) - for j in range(1, N): - hz = pitensor.HTerm(1.0, [pitensor.SiteTerm("Sz", j), pitensor.SiteTerm("Sz", j+1)]) - hp = pitensor.HTerm(0.5, [pitensor.SiteTerm("S+", j), pitensor.SiteTerm("S-", j+1)]) - hm = pitensor.HTerm(0.5, [pitensor.SiteTerm("S-", j), pitensor.SiteTerm("S+", j+1)]) + result = [] + for N in range(10, 200, 10): + sites = pitensor.SpinHalf(N); + psi = pitensor.MPS(sites) + ampo = pitensor.AutoMPO(sites) + for j in range(1, N): + hz = pitensor.HTerm(1.0, [pitensor.SiteTerm("Sz", j), pitensor.SiteTerm("Sz", j+1)]) + hp = pitensor.HTerm(0.5, [pitensor.SiteTerm("S+", j), pitensor.SiteTerm("S-", j+1)]) + hm = pitensor.HTerm(0.5, [pitensor.SiteTerm("S-", j), pitensor.SiteTerm("S+", j+1)]) - ampo.add(hz) - ampo.add(hp) - ampo.add(hm) + ampo.add(hz) + ampo.add(hp) + ampo.add(hm) - H = pitensor.toMPO(ampo) + H = pitensor.toMPO(ampo) - sweeps = pitensor.Sweeps(5); - sweeps.maxm = [10, 40, 100, 200, 200] - sweeps.cutoff = 1E-8 + sweeps = pitensor.Sweeps(5); + sweeps.maxm = [10, 40, 100, 200, 200] + sweeps.cutoff = 1E-8 - energy = pitensor.dmrg(psi, H, sweeps, pitensor.Args(Quiet=True)) + energy = pitensor.dmrg(psi, H, sweeps, pitensor.Args(Quiet=True)) + result.append((N, energy/N)) + print("Ground state energy per site = {:.18f}".format(energy / N)) + result = np.array(result) + np.savetxt('GroundStateEnergy.txt', result) if __name__=='__main__': main() From 5c259eab2602fa28e48a85d696f8dcf22b1fa46c Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:11:19 -0400 Subject: [PATCH 09/41] Update CMakeLists.txt: show host system and also build shared library --- CMakeLists.txt | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 28006b6..173b230 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,6 +138,7 @@ set(PITENSOR_DEPENDENCY_DIR "${CMAKE_BINARY_DIR}/deps") target_include_directories(pitensor PUBLIC "${PITENSOR_DEPENDENCY_DIR}/ITensor") if(APPLE) + message(STATUS "Building for macOS") # https://stackoverflow.com/questions/26185978/macos-wchar-h-file-not-found set(ITENSOR_PLATFORM macos) set(ITENSOR_BLAS_LAPACK_LIBFLAGS "-framework Accelerate") @@ -151,7 +152,8 @@ if(APPLE) debug "${ITENSOR_LIB_DEBUG}" general "${ACCELERATE_LIBRARY}" ) -elseif(MSYS AND MINGW) +elseif(MINGW) + message(STATUS "Building for MinGW") set(CMAKE_AR "gcc-ar") set(CMAKE_RANLIB "gcc-ranlib") @@ -211,6 +213,7 @@ elseif(MSYS AND MINGW) add_dependencies(pitensor DllBinaries) elseif(UNIX) + message(STATUS "Building for Linux") set(CMAKE_AR "gcc-ar") set(CMAKE_RANLIB "gcc-ranlib") @@ -222,8 +225,16 @@ elseif(UNIX) set(ITENSOR_PLATFORM lapack) set(ITENSOR_BLAS_LAPACK_LIBFLAGS "${LAPACK_LIBRARY} ${BLAS_LIBRARY} -lpthread") set(ITENSOR_BLAS_LAPACK_INCLUDEFLAGS "-I${BLAS_LAPACK_ROOT}/include") - set(ITENSOR_LIB_OPTIMIZED "${PITENSOR_DEPENDENCY_DIR}/ITensor/lib/libitensor.a") - set(ITENSOR_LIB_DEBUG "${PITENSOR_DEPENDENCY_DIR}/ITensor/lib/libitensor-g.a") + + #find_library(ITENSOR_LIB_OPTIMIZED NAMES itensor HINTS "${PITENSOR_DEPENDENCY_DIR}/ITensor/lib") + #find_library(ITENSOR_LIB_DEBUG NAMES itensor-g HINTS "${PITENSOR_DEPENDENCY_DIR}/ITensor/lib") + + #set(ITENSOR_LIB_OPTIMIZED "${PITENSOR_DEPENDENCY_DIR}/ITensor/lib/libitensor.a") + #set(ITENSOR_LIB_DEBUG "${PITENSOR_DEPENDENCY_DIR}/ITensor/lib/libitensor-g.a") + + set(ITENSOR_LIB_OPTIMIZED "${PITENSOR_DEPENDENCY_DIR}/ITensor/lib/libitensor.so") + set(ITENSOR_LIB_DEBUG "${PITENSOR_DEPENDENCY_DIR}/ITensor/lib/libitensor-g.so") + target_link_libraries(pitensor PRIVATE optimized "${ITENSOR_LIB_OPTIMIZED}" @@ -253,7 +264,7 @@ BLAS_LAPACK_LIBFLAGS=${ITENSOR_BLAS_LAPACK_LIBFLAGS} BLAS_LAPACK_INCLUDEFLAGS=${ITENSOR_BLAS_LAPACK_INCLUDEFLAGS} OPTIMIZATIONS=-DNDEBUG -Wall ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} DEBUGFLAGS=-DDEBUG -Wall -pedantic ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG} -ITENSOR_MAKE_DYLIB=0 +ITENSOR_MAKE_DYLIB=1 PREFIX=$(THIS_DIR) ITENSOR_LIBDIR=$(PREFIX)/lib ITENSOR_INCLUDEDIR=$(PREFIX) @@ -271,6 +282,15 @@ CCFLAGS=-I. $(ITENSOR_INCLUDEFLAGS) $(OPTIMIZATIONS) -Wno-unused-variable CCGFLAGS=-I. $(ITENSOR_INCLUDEFLAGS) $(DEBUGFLAGS) LIBFLAGS=-L$(ITENSOR_LIBDIR) $(ITENSOR_LIBFLAGS) LIBGFLAGS=-L$(ITENSOR_LIBDIR) $(ITENSOR_LIBGFLAGS) + +UNAME_S := $(shell uname -s) +ifeq ($(UNAME_S),Darwin) + DYLIB_EXT ?= dylib + DYLIB_FLAGS ?= -dynamiclib +else + DYLIB_EXT ?= so + DYLIB_FLAGS ?= -shared +endif ") include(ExternalProject) From f1260184451bee932688d4ed6cd743f47be6d7a4 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:11:42 -0400 Subject: [PATCH 10/41] Update src/pitensor.h: some c++ includes --- src/pitensor.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pitensor.h b/src/pitensor.h index 955b3b0..f5e396d 100644 --- a/src/pitensor.h +++ b/src/pitensor.h @@ -2,6 +2,10 @@ #define PITENSOR_LIBRARY_H #include +#include +#include +#include +#include #include #include From 846bfd7946444cec0e9692621482fb8e3217c734 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:22:03 -0400 Subject: [PATCH 11/41] __repr__ and Minor formatting fixes - `__repr__` now uses std::scientific (to print all data) and --- src/itensor/decomp.h.cc | 12 ++++++------ src/itensor/index.h.cc | 26 ++++++++------------------ src/itensor/iqindex.h.cc | 33 +++++++++++++++------------------ src/itensor/mps/autompo.h.cc | 28 +++++++++++++++------------- src/itensor/mps/mpo.h.cc | 12 ++++++++---- src/itensor/mps/mps.h.cc | 2 +- src/itensor/mps/siteset.h | 4 ++++ src/itensor/qn.h.cc | 3 +-- src/itensor/real.h.cc | 11 +++++++---- src/itensor/spectrum.h.cc | 3 +-- 10 files changed, 66 insertions(+), 68 deletions(-) diff --git a/src/itensor/decomp.h.cc b/src/itensor/decomp.h.cc index 917d731..4987a1b 100644 --- a/src/itensor/decomp.h.cc +++ b/src/itensor/decomp.h.cc @@ -69,14 +69,14 @@ initDecomp(pybind11::module& module) py::arg("U"), py::arg("D"), py::arg("V"), - py::arg("args") = Global::args()) + py::arg("args")=Global::args()) .def("factor", (Spectrum (*)(Tensor const &, Tensor &, Tensor &, Args const &)) &safeFactor, "Factor Decomposition", py::arg("T"), py::arg("A"), py::arg("B"), - py::arg("args") = Args::global()) + py::arg("args")=Args::global()) .def("denmatDecomp", (Spectrum (*)(Tensor const &, Tensor &, Tensor &, Direction, Args const &)) &safeDenmatDecomp, "Density matrix decomposition", @@ -84,7 +84,7 @@ initDecomp(pybind11::module& module) py::arg("A"), py::arg("B"), py::arg("dir"), - py::arg("args") = Args::global()) + py::arg("args")=Args::global()) // TODO: denmatDecomp with BigMatrixT .def("diagHermitian", (Spectrum (*)(Tensor const &, Tensor &, Tensor &, Args)) &safeDiagHermitian, @@ -92,19 +92,19 @@ initDecomp(pybind11::module& module) py::arg("M"), py::arg("U"), py::arg("D"), - py::arg("args") = Args::global()) + py::arg("args")=Args::global()) .def("expHermitian", (Tensor (*)(Tensor const &, Cplx)) &expHermitian, "Hermitian Exponential", py::arg("T"), - py::arg("t") = 1.) + py::arg("t")=1.) .def("eigen", (void (*)(Tensor const &, Tensor &, Tensor & D, Args const &)) &eigen, "Eigenvalues and eigenvectors", py::arg("T"), py::arg("V"), py::arg("D"), - py::arg("args") = Args::global()) + py::arg("args")=Args::global()) ; } diff --git a/src/itensor/index.h.cc b/src/itensor/index.h.cc index ad9798f..8968aa3 100644 --- a/src/itensor/index.h.cc +++ b/src/itensor/index.h.cc @@ -39,22 +39,22 @@ initIndex(pybind11::module& module) .def("prime", py::overload_cast(&Index::prime), "Increase primelevel", - py::arg("inc") = 1) + py::arg("inc")=1) .def("prime", py::overload_cast(&Index::prime), "Increase primelevel", py::arg("type"), - py::arg("inc") = 1) + py::arg("inc")=1) .def("noprime", &Index::noprime, "Set primelevel to zero (optionally only if type matches)", - py::arg("type") = All) + py::arg("type")=All) .def("mapprime", &Index::mapprime, "Switch primelevel from plevold to plevnew", py::arg("plevold"), py::arg("plevnew"), - py::arg("type") = All) + py::arg("type")=All) .def("noprimeEquals", &Index::noprimeEquals, "Check if other Index is a copy of this, ignoring primeLevel") @@ -76,13 +76,9 @@ initIndex(pybind11::module& module) .def(py::self > py::self) .def(py::self == IndexVal()) .def("__repr__", - [](Index const & obj) -> std::string { - std::stringstream ss; - ss << obj; - return ss.str(); - }) + [](Index const & obj) -> std::string { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) + ; - ; module .def("dag", (Index (*)(Index)) &dag) @@ -162,14 +158,8 @@ initIndexVal(pybind11::module& module) .def(py::self == py::self) .def(py::self != py::self) .def(py::self == Index()) - .def("__repr__", - [](IndexVal const & obj) -> std::string { - std::stringstream ss; - ss << obj; - return ss.str(); - }) - - ; + .def("__repr__", [](IndexVal const & obj) -> std::string { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) + ; return type; } diff --git a/src/itensor/iqindex.h.cc b/src/itensor/iqindex.h.cc index c98a876..7741df7 100644 --- a/src/itensor/iqindex.h.cc +++ b/src/itensor/iqindex.h.cc @@ -7,7 +7,6 @@ using namespace itensor; void static inline initIQIndex(pybind11::module& module) { - py::class_ type(module, "IQIndex"); type.def(py::init<>(), "Constructor"); @@ -108,7 +107,9 @@ initIQIndex(pybind11::module& module) py::arg("i5"), py::arg("q5"), py::arg("i6"), py::arg("q6"), py::arg("i7"), py::arg("q7"), - py::arg("dir") = Out); + py::arg("dir")=Out) + ; + type .def("nblock", &IQIndex::nblock) @@ -132,7 +133,6 @@ initIQIndexVal(pybind11::module& module) type .def_readwrite("index", &IQIndexVal::index) .def_readwrite("val", &IQIndexVal::val) - ; type @@ -176,10 +176,7 @@ initIQIndexVal(pybind11::module& module) .def(py::self != IQIndex()) //.def(IQIndex() == py::self) //.def(IQIndex() != py::self) - .def("__repr__", - [](IQIndex const & obj) -> std::string { - std::stringstream ss; ss << obj; return ss.str(); - }) + .def("__repr__", [](IQIndex const & obj) -> std::string { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) ; @@ -191,17 +188,17 @@ initIQIndexVal(pybind11::module& module) (IndexQN (*)(IndexQN)) &dag) .def("dag", (IQIndexVal (*)(IQIndexVal)) &dag) - .def("hasindex", (bool (*)(IQIndex const &, Index const &)) &hasindex) - .def("findindex", (long (*)(IQIndex const &, Index const &)) &findindex) - .def("offset", (long (*)(IQIndex const &, Index const&)) &offset) - .def("qn", (QN (*)(IQIndex const &, Index const &)) &qn) - .def("findByQN", (Index (*)(IQIndex const &, QN const &))&findByQN) - .def("sim", - (IQIndex (*)(IQIndex const &, int)) &sim, - py::arg("I"), - py::arg("plev")=0) - .def("showm", - (std::string (*)(IQIndex const &)) &showm) + .def("hasindex", (bool (*)(IQIndex const &, Index const &)) &hasindex) + .def("findindex", (long (*)(IQIndex const &, Index const &)) &findindex) + .def("offset", (long (*)(IQIndex const &, Index const&)) &offset) + .def("qn", (QN (*)(IQIndex const &, Index const &)) &qn) + .def("findByQN", (Index (*)(IQIndex const &, QN const &))&findByQN) + .def("sim", + (IQIndex (*)(IQIndex const &, int)) &sim, + py::arg("I"), + py::arg("plev")=0) + .def("showm", + (std::string (*)(IQIndex const &)) &showm) .def("prime", diff --git a/src/itensor/mps/autompo.h.cc b/src/itensor/mps/autompo.h.cc index dec2b18..677c1f0 100644 --- a/src/itensor/mps/autompo.h.cc +++ b/src/itensor/mps/autompo.h.cc @@ -13,15 +13,15 @@ _init(pybind11::module& module) using mps_type = MPSt; module - .def("toMPO", - (mpo_type (*)(AutoMPO const&, Args const &)) &toMPO, - py::arg("a"), - py::arg("args")=Args::global()) - .def("toExpH", - (mpo_type (*)(AutoMPO const &, Cplx, Args const & args)) &toExpH, - py::arg("a"), - py::arg("tau"), - py::arg("args")=Args::global()) + .def("toMPO", + (mpo_type (*)(AutoMPO const&, Args const &)) &toMPO, + py::arg("a"), + py::arg("args")=Args::global()) + .def("toExpH", + (mpo_type (*)(AutoMPO const &, Cplx, Args const & args)) &toExpH, + py::arg("a"), + py::arg("tau"), + py::arg("args")=Args::global()) ; } @@ -42,10 +42,12 @@ auto initSiteTerm(pybind11::module& module) ; type - .def("__repr__", [](SiteTerm const & obj) { std::stringstream ss; ss << obj; return ss.str(); }) + .def("__repr__", [](SiteTerm const & obj) { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) ; - module.def("isFermionic", (bool (*)(SiteTerm const &)) &isFermionic); + module + .def("isFermionic", (bool (*)(SiteTerm const &)) &isFermionic) + ; return type; } @@ -77,7 +79,7 @@ auto initHTerm(pybind11::module& module) .def(py::self == py::self) .def(py::self != py::self) .def(py::self < py::self) - .def("__repr__", [](TheType const & obj) { std::stringstream ss; ss << obj; return ss.str(); }) + .def("__repr__", [](TheType const & obj) { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) ; } @@ -97,7 +99,7 @@ auto initAutoMPO(pybind11::module& module) // TODO Accumulator .def("add", &AutoMPO::add) .def("reset", &AutoMPO::reset) - .def("__repr__", [](AutoMPO const & obj) { std::stringstream ss; ss << obj; return ss.str(); }) + .def("__repr__", [](AutoMPO const & obj) { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) ; return type; } diff --git a/src/itensor/mps/mpo.h.cc b/src/itensor/mps/mpo.h.cc index 6add33d..ecaa1c4 100644 --- a/src/itensor/mps/mpo.h.cc +++ b/src/itensor/mps/mpo.h.cc @@ -15,10 +15,14 @@ initMPOt(pybind11::module& module, const char* typeName) .def(py::init<>()) .def(py::init(), py::arg("sites"), - py::arg("refNorm") = DefaultLogRefScale) // TODO: variable name mismatch with ITensor + py::arg("refNorm")=DefaultLogRefScale) // TODO: variable name mismatch with ITensor ; + type .def("__bool__", [](mpo_type const & self) { return static_cast(self); }) + ; + + type .def("logRefNorm", &mpo_type::logRefNorm) .def("plusEq", &mpo_type::plusEq) .def("toMPO", &mpo_type::toMPO) @@ -86,9 +90,9 @@ initMPOt(pybind11::module& module, const char* typeName) #endif .def("overlapC", (Complex (*)(mps_type const &, - mpo_type const &, - mpo_type const &, - mps_type const &)) &overlapC) + mpo_type const &, + mpo_type const &, + mps_type const &)) &overlapC) .def("nmultMPO", (void (*)(mpo_type const &, mpo_type const &, diff --git a/src/itensor/mps/mps.h.cc b/src/itensor/mps/mps.h.cc index 8ccb7f5..d7f89e3 100644 --- a/src/itensor/mps/mps.h.cc +++ b/src/itensor/mps/mps.h.cc @@ -34,7 +34,7 @@ initMPSt(pybind11::module& module, const char* typeName) .def("plusEq", (mps_type& (mps_type::*)(mps_type const&, Args const&)) &mps_type::plusEq, py::arg("R"), - py::arg("args") = Args::global()) + py::arg("args")=Args::global()) .def("mapprime", (void (mps_type::*)(int, int, IndexType)) &mps_type::mapprime, py::arg("oldp"), diff --git a/src/itensor/mps/siteset.h b/src/itensor/mps/siteset.h index 2aed736..4da6597 100644 --- a/src/itensor/mps/siteset.h +++ b/src/itensor/mps/siteset.h @@ -18,6 +18,10 @@ initBasicSiteSet(pybind11::module & module, const char* typeName) py::arg("N"), py::arg("args")=Args::global()); type.def(py::init const &>()); + type + .def("__repr__", [](Type const & obj) { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) + ; + // TODO read write return type; } \ No newline at end of file diff --git a/src/itensor/qn.h.cc b/src/itensor/qn.h.cc index 91fba61..29c6190 100644 --- a/src/itensor/qn.h.cc +++ b/src/itensor/qn.h.cc @@ -24,8 +24,7 @@ void pitensor::qn(pybind11::module& module) { .def("val", &QNVal::val) .def("set", &QNVal::set) .def(-py::self) //TODO: Design flaw - - ; + ; } { diff --git a/src/itensor/real.h.cc b/src/itensor/real.h.cc index d6829bb..95f8fcb 100644 --- a/src/itensor/real.h.cc +++ b/src/itensor/real.h.cc @@ -13,9 +13,12 @@ void pitensor::real(pybind11::module& module) py::class_ type(module, "LogNum"); type - .def(py::init<>()) - .def(py::init()) - .def(py::init()) + .def(py::init<>()) + .def(py::init()) + .def(py::init(), py::arg("lognum"), py::arg("sign")) + ; + + type .def("logNum", &LogNum::logNum) .def("sign", &LogNum::sign) .def("isZero", &LogNum::isZero) @@ -53,6 +56,6 @@ void pitensor::real(pybind11::module& module) (LogNum (*)(LogNum)) &sqrt ) ; type - .def("__repr__", [](LogNum const & self) { std::stringstream ss; ss< std::string { std::stringstream ss; ss << obj; return ss.str(); }) + .def("__repr__", [](Spectrum const & obj) -> std::string { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) ; } From 45883d7b876a98bacbb7c05a013c541a9259bd29 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:22:39 -0400 Subject: [PATCH 12/41] Update eigensolver.h.cc: include mpo.h and localmpo.h --- src/itensor/eigensolver.h.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/itensor/eigensolver.h.cc b/src/itensor/eigensolver.h.cc index b2bd6e9..83e2850 100644 --- a/src/itensor/eigensolver.h.cc +++ b/src/itensor/eigensolver.h.cc @@ -1,5 +1,8 @@ #include "../pitensor.h" #include "itensor/eigensolver.h" +#include "itensor/mps/mpo.h" +#include "itensor/mps/localmpo.h" + namespace py = pybind11; using namespace itensor; From 7ba167a0b734e16cb750cd3155a17d31395e5214 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:22:59 -0400 Subject: [PATCH 13/41] Update eigensolver.h.cc: rename init to _init --- src/itensor/eigensolver.h.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/itensor/eigensolver.h.cc b/src/itensor/eigensolver.h.cc index 83e2850..c4cdcc9 100644 --- a/src/itensor/eigensolver.h.cc +++ b/src/itensor/eigensolver.h.cc @@ -9,7 +9,7 @@ using namespace itensor; template static inline auto -init(pybind11::module& module) +_init(pybind11::module& module) { module .def("davidson", @@ -20,5 +20,8 @@ init(pybind11::module& module) void pitensor::eigensolver(pybind11::module& module) { - + _init, ITensor>(module); + _init, IQTensor>(module); + // TODO: cross-combination? + // TODO: BigMatrixT type? } From 375972f543637f856122a9a773a2f7b5e6802c7a Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:23:18 -0400 Subject: [PATCH 14/41] Update index.h.cc --- src/itensor/index.h.cc | 73 +++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/src/itensor/index.h.cc b/src/itensor/index.h.cc index 8968aa3..4d1b22d 100644 --- a/src/itensor/index.h.cc +++ b/src/itensor/index.h.cc @@ -14,28 +14,9 @@ initIndex(pybind11::module& module) .def(py::init(), "Constructor", py::arg("name"), - py::arg("m") = 1, - py::arg("it") = Link, - py::arg("primelev") = 0) - .def_property_readonly("m", &Index::m) - .def("primeLevel", - py::overload_cast<>(&Index::primeLevel, py::const_)) - .def("primeLevel", - py::overload_cast(&Index::primeLevel)) - .def_property_readonly("type",&Index::type) - .def_property_readonly("name", &Index::name) - .def_property_readonly("rawname", &Index::rawname) - .def_property_readonly("id", &Index::id) - .def("__bool__", - [](const Index& index) { return static_cast(index); } ) - .def("__int__", - [](const Index& index) { return static_cast(index); } ) - .def("__index__", - [](const Index& index) { return static_cast(index); } ) - .def("dir", - py::overload_cast<>(&Index::dir, py::const_)) - .def("dir", - py::overload_cast(&Index::dir, py::const_)) + py::arg("m")=1, + py::arg("it")=Link, + py::arg("primelev")=0) .def("prime", py::overload_cast(&Index::prime), "Increase primelevel", @@ -58,23 +39,49 @@ initIndex(pybind11::module& module) .def("noprimeEquals", &Index::noprimeEquals, "Check if other Index is a copy of this, ignoring primeLevel") + .def("dag", &Index::dag) + // TODO read write + //.def("write", &Index::write) + //.def("read", &Index::read) + ; + + type + .def_property_readonly("size", &Index::size) + .def_property_readonly("m", &Index::m) + .def_property_readonly("type",&Index::type) + .def_property_readonly("name", &Index::name) + .def_property_readonly("rawname", &Index::rawname) + .def_property_readonly("id", &Index::id) + .def("dir", py::overload_cast<>(&Index::dir, py::const_)) + .def_property("primeLevel", + py::overload_cast<>(&Index::primeLevel, py::const_), + py::overload_cast(&Index::primeLevel)) + + //.def("dir", // TODO: why is this here? + // py::overload_cast(&Index::dir, py::const_)) + ; + + type + .def(py::self == py::self) + .def(py::self != py::self) + .def(py::self < py::self) + .def(py::self > py::self) + .def(py::self == IndexVal()) + ; + + type + .def("__bool__", + [](const Index& index) { return static_cast(index); } ) .def("__call__", [](Index const & obj, long val) -> IndexVal { return obj(val); }, "Return an IndexVal with specific value") .def("__getitem__", [](Index const & obj, int plev) -> Index { return obj[plev]; }, "Return copy of this Index with primelevel plev") - .def("dag", - &Index::dag) - .def_property_readonly("size", - &Index::size) - .def("write", &Index::write) - .def("read", &Index::read) - .def(py::self == py::self) - .def(py::self != py::self) - .def(py::self < py::self) - .def(py::self > py::self) - .def(py::self == IndexVal()) + .def("__int__", + [](const Index& index) { return static_cast(index); } ) + .def("__index__", + [](const Index& index) { return static_cast(index); } ) .def("__repr__", [](Index const & obj) -> std::string { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) ; From 816f578ad17484ecf2002e32c63835d24ba53cc8 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:23:33 -0400 Subject: [PATCH 15/41] Update indexname.h.cc --- src/itensor/indexname.h.cc | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/itensor/indexname.h.cc b/src/itensor/indexname.h.cc index cfeed81..c56271f 100644 --- a/src/itensor/indexname.h.cc +++ b/src/itensor/indexname.h.cc @@ -3,6 +3,38 @@ namespace py = pybind11; using namespace itensor; +static inline +auto +initIndexName(pybind11::module& module) +{ + using Type = IndexName; + py::class_ type(module, "IndexName"); + + type + .def(py::init<>()) + .def(py::init()) + ; + + type + .def_property_readonly_static("size", &IndexName::size) + .def_property_readonly("name", + [](Type const & self) -> std::string { + return std::string(self.c_str()); + }) + ; + + type + .def("__getitem__", + [](IndexName const & obj, size_t i) -> char { return obj[i]; }) + .def("__setitem__", + [](IndexName& obj, size_t i, char c) -> void { obj[i] = c; }) + .def("__repr__", [](IndexName const & obj) -> std::string { std::stringstream ss; ss << std::scientific << static_cast(obj); return ss.str(); }) + ; + + // TODO read write + + return type; +} void pitensor::indexname(pybind11::module& module) { #if 0 From 7efba67a81d7b752b54e50f086ab2fffa343ba83 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:23:50 -0400 Subject: [PATCH 16/41] Update indexset.h.cc --- src/itensor/indexset.h.cc | 935 +++++++++++--------------------------- 1 file changed, 270 insertions(+), 665 deletions(-) diff --git a/src/itensor/indexset.h.cc b/src/itensor/indexset.h.cc index 528e2f2..d97c00e 100644 --- a/src/itensor/indexset.h.cc +++ b/src/itensor/indexset.h.cc @@ -3,690 +3,295 @@ namespace py = pybind11; using namespace itensor; +template +bool matchAny(CmpType&& cmp, ItemType const & i, Iterator first, Iterator last) +{ + using IteratorItemType = decltype(*first); + return std::any_of(first, last, [&cmp, &i](IteratorItemType const & j) -> bool { return cmp(i,j); }); +} - -template -void initIndexSetT(pybind11::module& module, const char* name) +template +struct InitializerIndexSetT { + using index_type = IndexT; using index_set_type = IndexSetT; using size_type = typename index_set_type::size_type; - /* - using extent_type = index_set_type::extent_type; - using range_type = index_set_type::range_type; - using parent = index_set_type::parent; - using storage_type = index_set_type::storage_type; - using value_type = index_set_type::value_type; - using iterator = index_set_type::iterator; - using const_iterator = index_set_type::const_iterator; - using indexval_type = index_set_type::indexval_type; - */ + using extent_type = typename index_set_type::extent_type; + using range_type = typename index_set_type::range_type; + using parent = typename index_set_type::parent; + using storage_type = typename index_set_type::storage_type; + using value_type = typename index_set_type::value_type; + using iterator = typename index_set_type::iterator; + using const_iterator = typename index_set_type::const_iterator; + using indexval_type = typename index_set_type::indexval_type; using label_type = std::string; //TODO: LabelT ??? - py::class_ type(module, name); - type - .def(py::init<>()) - .def(py::init()) - .def(py::init()) - .def(py::init()) - .def(py::init()) - .def(py::init()) - .def(py::init()) - .def(py::init()) - .def(py::init()) - .def(py::init()) + py::module & module; + const char * name; + py::class_ type; + + InitializerIndexSetT(pybind11::module & theModule, const char * theName) + : module(theModule), name(theName), type(module, name) + { + initConstructor(); + initMethod(); + initPrime(); + initFunction(); + } + + void initConstructor() + { + type + .def(py::init([](py::args args) { + bool all_index_type = true; + for (auto const & item : args) { + all_index_type = all_index_type && py::isinstance(item); + } + if(!all_index_type) { throw std::domain_error("Arguments should all be of index_type"); } + std::vector cpp_args; + cpp_args.reserve(py::len(args)); + for (auto const & item : args) { + cpp_args.push_back(item.cast()); + } + return new index_set_type(cpp_args); + })) + ; + + } + + void initMethod() + { + type + .def("__bool__", [](index_set_type const &obj) { return static_cast(obj); }) + .def("extent", &index_set_type::extent) + .def("stride", &index_set_type::stride) + .def_property_readonly("r", &index_set_type::r) + .def("__getitem__", + [](index_set_type const &obj, size_type i) { return obj[i]; }) + .def("__setitem__", + [](index_set_type &obj, size_t i, index_type const &idx) { obj[i] = idx; }) + .def("__call__", + [](index_set_type const &obj, size_type i) { return obj.index(i); }) + .def("range", &index_set_type::range) + .def("dag", &index_set_type::dag) + .def("swap", &index_set_type::swap) + .def("front", &index_set_type::front) + .def("back", &index_set_type::back) + .def("__iter__", [](index_set_type &obj) { + return py::make_iterator(obj.begin(), obj.end()); + }) + .def("__repr__", [](index_set_type const & obj) { + std::stringstream ss; ss << std::scientific << obj; return ss.str(); + }); + } + + // TODO: check prime + void initPrime() + { + // TODO: Check + + module + .def("prime", [](index_set_type& is, + py::args args, + py::kwargs kwargs) -> void { + int inc = kwargs.contains(py::cast("inc")) ? kwargs[py::cast("inc")].cast() : 1; + if (py::len(args)==0) { + //std::cout << __PRETTY_FUNCTION__ << " (ALL TYPES):" << std::endl; + return prime(is, inc); // TODO: ITensor Bug? prime with variadic (possibly empty) arguments + } + + //std::cout << "IndexType = " << typeid(IndexType).name() << std::endl; + //std::cout << "index_type = " << typeid(index_type).name() << std::endl; + + bool all_IndexType = true, all_IndexT = true; + + for (auto const &item : args) { + //std::cout << "TYPE: " << item.get_type() << std::endl; + //std::cout << py::isinstance(item) << std::endl; + //std::cout << py::isinstance(item) << std::endl; + all_IndexType = all_IndexType && (py::isinstance(item)); + all_IndexT = all_IndexT && (py::isinstance(item)); + } + + if(all_IndexType) { + if (py::len(args) > 1) { + throw std::domain_error("Priming multiple types not defined in ITensor"); + } + std::vector types; types.reserve(py::len(args)); + for(auto const & item : args) { types.push_back(item.cast()); } + + // prime if i matches any of the types + for(auto & i : is) { + if (matchAny([](const index_type & x, IndexType y) -> bool { return x.type() == y; }, + i, types.begin(), types.end())) { + //std::cout << __PRETTY_FUNCTION__<< "(IndexType) : " << i << " matches." << std::endl; + i.prime(inc); + } + } // for i : is + } // if all_IndexType + else if (all_IndexT) { + std::vector types; types.reserve(py::len(args)); + for(auto const & item : args) { types.push_back(item.cast()); } + for(auto & i : is) { + if (matchAny(detail::IndexCmp(), i, types.begin(), types.end())) { + //std::cout << __PRETTY_FUNCTION__<< " (index_type): " << i << " matches." << std::endl; + i.prime(inc); + } + } + } // else if (all_IndexT) + else { + throw std::domain_error("Unsupported argument types"); + } + // TODO: return or not return? + }) ; - type - .def("__bool__", [](index_set_type const &obj) { return static_cast(obj); }) - .def("extent", &index_set_type::extent) - .def("stride", &index_set_type::stride) - .def_property_readonly("r", &index_set_type::r) - .def("__getitem__", - [](index_set_type const &obj, size_type i) { return obj[i]; }) - .def("__setitem__", - [](index_set_type &obj, size_t i, index_type const &idx) { obj[i] = idx; }) - .def("__call__", - [](index_set_type const &obj, size_type i) { return obj.index(i); }) - .def("range", &index_set_type::range) - .def("dag", &index_set_type::dag) - .def("swap", &index_set_type::swap) - .def("front", &index_set_type::front) - .def("back", &index_set_type::back) - .def("__iter__", [](index_set_type &obj) { - return py::make_iterator(obj.begin(), obj.end()); - }) - .def("__repr__", [](index_set_type const & obj) { - std::stringstream ss; ss << obj; return ss.str(); - }); + // TODO: Check. very error prone module - // TODO: read - // TODO: write - // TODO: rangeBegin - // TODO: rangeEnd - .def("prime", - (void (*)(index_set_type &, int)) &prime, - py::arg("indexset"), - py::arg("inc") = 1) - // TODO prime variadic - .def("primeExcept", - (void (*)(index_set_type &, - index_type const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - int const &)) &primeExcept) - - .def("primeExcept", - (void (*)(index_set_type &, - IndexType, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - IndexType, - IndexType const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - IndexType, - IndexType const &, - IndexType const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - IndexType, - IndexType const &, - IndexType const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - IndexType, - IndexType const &, - IndexType const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - IndexType, - IndexType const &, - IndexType const &, - IndexType const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - IndexType, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - IndexType, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - IndexType, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - IndexType, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - IndexType, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - int const &)) &primeExcept) - .def("primeExcept", - (void (*)(index_set_type &, - IndexType, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - int const &)) &primeExcept) - - .def("noprime", - (void (*)(index_set_type &, - IndexType)) &noprime, - "", - py::arg("indexset"), - py::arg("type") = All) - .def("noprime", - (void (*)(index_set_type &, - IndexType, - IndexType)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - IndexType, - IndexType, - IndexType const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - IndexType, - IndexType, - IndexType const &, - IndexType const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - IndexType, - IndexType, - IndexType const &, - IndexType const &, - IndexType const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - IndexType, - IndexType, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - IndexType, - IndexType, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - IndexType, - IndexType, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - IndexType, - IndexType, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - IndexType, - IndexType, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &, - IndexType const &)) &noprime) - - .def("noprime", - (void (*)(index_set_type &, - index_type const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - index_type const &, - index_type const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &, - index_type const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &)) &noprime) - .def("noprime", - (void (*)(index_set_type &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &, - index_type const &)) &noprime) - - .def("mapprime", - (void (*)(index_set_type &, - int, int, IndexType)) &mapprime, - "", - py::arg("indexset"), - py::arg("plevold"), - py::arg("plevnew"), - py::arg("type") = All) - //TODO: Why order different? - .def("mapprime", - (void (*)(index_set_type &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const &, - IndexType const &, int const &, int const & - )) &mapprime) - - .def("mapprime", - (void (*)(index_set_type &, - index_type const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const & - )) &mapprime) - .def("mapprime", - (void (*)(index_set_type &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const &, - index_type const &, int const &, int const & - )) &mapprime) - - .def("sim", - (void (*)(index_set_type &, index_type const &)) &sim) - .def("sim", - (void (*)(index_set_type &, IndexType)) &sim) - - .def("findindex", - (long (*)(index_set_type const &, index_type const &)) &findindex) - .def("findtype", - (index_type const & (*)(index_set_type const &, IndexType)) &findtype) - // TODO: fix warning (dangling reference) - .def("finddir", - (index_type const & (*)(index_set_type const &, Arrow)) &finddir) - .def("dir", - (Arrow (*)(index_set_type const &, index_type const &)) &dir) - - .def("hasindex", - (bool (*)(index_set_type const &, index_type const &)) &hasindex) - .def("hastype", - (bool (*)(index_set_type const &, IndexType)) &hastype) - - .def("minM", - (long (*)(index_set_type const &)) &minM) - .def("maxM", - (long (*)(index_set_type const &)) &maxM) - .def("contractIS", - (void (*)(index_set_type const &, index_set_type const &, index_set_type &, bool)) &contractIS, - "", - py::arg("Lis"), - py::arg("Ris"), - py::arg("Nis"), - py::arg("sortResult") = false) - .def("contractIS", - (void (*)(index_set_type const &, label_type const &, - index_set_type const &, label_type const &, - index_set_type &, label_type &, bool)) &contractIS, - "", - py::arg("Lis"), py::arg("Lind"), - py::arg("Ris"), py::arg("Rind"), - py::arg("Nis"), py::arg("Nind"), - py::arg("sortResult") = false) - .def("ncprod", - (void (*)(index_set_type const &, label_type const &, - index_set_type const &, label_type const &, - index_set_type &, label_type &)) &ncprod, - "", - py::arg("Lis"), py::arg("Lind"), - py::arg("Ris"), py::arg("Rind"), - py::arg("Nis"), py::arg("Nind")) + .def("primeExcept", [](index_set_type& is, + py::object obj, + py::args args, + py::kwargs kwargs) { + int inc = kwargs.contains(py::cast("inc")) ? kwargs[py::cast("inc")].cast() : 1; + + bool all_IndexType = py::isinstance(obj); + bool all_IndexT = py::isinstance(obj); + for (auto const &item : args) { + all_IndexType = all_IndexType && (py::isinstance(item)); + all_IndexT = all_IndexT && (py::isinstance(item)); + } + + if(all_IndexType) { + std::vector types; types.reserve(py::len(args)+1); + types.push_back(obj.cast()); + for (auto const & item : args) { types.push_back(item.cast()); } + // prime if i matches any of the types + for(auto & i : is) { + if (!matchAny([](const index_type & x, IndexType y) -> bool { return x.type() == y; }, + i, types.begin(), types.end())) { + i.prime(inc); + } + } // for i : is + + + } // if all_IndexType + else if (all_IndexT) { + std::vector types; types.reserve(py::len(args)+1); + types.push_back(obj.cast()); + for (auto const & item : args) { types.push_back(item.cast()); } + for(auto & i : is) { + if (!matchAny(detail::IndexCmp(), i, types.begin(), types.end())) { + i.prime(inc); + } + } + } // else if (all_IndexT) + else { + throw std::domain_error("Unsupported argument types"); + } + }) + ; + module + .def("noprime", [](index_set_type& is, + py::args args) -> void { + if (len(args)==0) { return noprime(is); } + bool all_IndexType = true, all_IndexT = true; + for (auto const &item : args) { + all_IndexType = all_IndexType && (py::isinstance(item)); + all_IndexT = all_IndexT && (py::isinstance(item)); + } + if(all_IndexType) { + std::vector types; types.reserve(py::len(args)); + for (auto const & item : args) { types.push_back(item.cast()); } + // prime if i matches any of the types + for(auto & i : is) { + if (matchAny([](const index_type & x, IndexType y) -> bool { return x.type() == y; }, + i, types.begin(), types.end())) { + i.noprime(); + } + } // for i : is + } // if all_IndexType + else if (all_IndexT) { + std::vector types; types.reserve(py::len(args)); + for (auto const & item : args) { types.push_back(item.cast()); } + for(auto & i : is) { + if (matchAny(detail::IndexCmp(), i, types.begin(), types.end())) { + i.noprime(); + } + } + } // else if (all_IndexT) + else { + throw std::domain_error("Unsupported argument types"); + } + }) + ; + + + } // initPrime + + void initFunction() + { + module + .def("sim", + (void (*)(index_set_type &, index_type const &)) &sim) + .def("sim", + (void (*)(index_set_type &, IndexType)) &sim) + .def("findindex", + (long (*)(index_set_type const &, index_type const &)) &findindex) + .def("findtype", + (index_type const & (*)(index_set_type const &, IndexType)) &findtype) + // TODO: fix warning (dangling reference) + .def("finddir", + (index_type const & (*)(index_set_type const &, Arrow)) &finddir) + .def("dir", + (Arrow (*)(index_set_type const &, index_type const &)) &dir) + + .def("hasindex", + (bool (*)(index_set_type const &, index_type const &)) &hasindex) + .def("hastype", + (bool (*)(index_set_type const &, IndexType)) &hastype) + + .def("minM", + (long (*)(index_set_type const &)) &minM) + .def("maxM", + (long (*)(index_set_type const &)) &maxM) + .def("contractIS", + (void (*)(index_set_type const &, index_set_type const &, index_set_type &, bool)) &contractIS, + "", + py::arg("Lis"), + py::arg("Ris"), + py::arg("Nis"), + py::arg("sortResult") = false) + .def("contractIS", + (void (*)(index_set_type const &, label_type const &, + index_set_type const &, label_type const &, + index_set_type &, label_type &, bool)) &contractIS, + "", + py::arg("Lis"), py::arg("Lind"), + py::arg("Ris"), py::arg("Rind"), + py::arg("Nis"), py::arg("Nind"), + py::arg("sortResult") = false) + .def("ncprod", + (void (*)(index_set_type const &, label_type const &, + index_set_type const &, label_type const &, + index_set_type &, label_type &)) &ncprod, + "", + py::arg("Lis"), py::arg("Lind"), + py::arg("Ris"), py::arg("Rind"), + py::arg("Nis"), py::arg("Nind")) ; -} + } +}; // struct InitializerIndexSetT void pitensor::indexset(pybind11::module& module) { - initIndexSetT(module, "IndexSet"); - initIndexSetT(module, "IQIndexSet"); + { InitializerIndexSetT _(module, "IndexSet"); } + { InitializerIndexSetT _(module, "IQIndexSet"); } } From cf47527ba1b410efb6ca62bdb5e69234c834970e Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:24:06 -0400 Subject: [PATCH 17/41] Update indextype.h.cc --- src/itensor/indextype.h.cc | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/itensor/indextype.h.cc b/src/itensor/indextype.h.cc index e1531d8..d0db684 100644 --- a/src/itensor/indextype.h.cc +++ b/src/itensor/indextype.h.cc @@ -5,23 +5,29 @@ using namespace itensor; void pitensor::indextype(pybind11::module& module) { + using Type = IndexType; py::class_ type(module, "IndexType"); type - .def(py::init()) - .def_property_readonly_static("size", &IndexType::size) - .def("c_str", &IndexType::c_str) - .def("__repr__", - [](IndexType const & obj) -> std::string { - std::stringstream ss; ss << static_cast(obj); return ss.str(); - }) - .def("__getitem__", - [](IndexType const & obj, size_t i) -> char { return obj[i]; }) - .def("__setitem__", - [](IndexType& obj, size_t i, char c) -> void { obj[i] = c; }) + .def(py::init()) + .def_property_readonly_static("size", &IndexType::size) + .def_property_readonly("name", + [](IndexType const & self) -> std::string { + return std::string(self.c_str()); + }) + //.def("c_str", &IndexType::c_str) + ; + + type + .def("__repr__", [](Type const & obj) -> std::string { std::stringstream ss; ss << std::scientific << static_cast(obj); return ss.str(); }) + .def("__getitem__", [](IndexType const & obj, size_t i) -> char { return obj[i]; }) + .def("__setitem__", [](IndexType& obj, size_t i, char c) -> void { obj[i] = c; }) + ; + + module + // TODO read write ; - module.attr("All") = All; module.attr("All") = All; module.attr("NullInd") = NullInd; module.attr("Link") = Link; From f4fe75478399ec984bb22bfd75884cede080af91 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:24:22 -0400 Subject: [PATCH 18/41] Update itensor_interface.h.cc --- src/itensor/itensor_interface.h.cc | 1342 +++++++++++++++++++++------- 1 file changed, 1001 insertions(+), 341 deletions(-) diff --git a/src/itensor/itensor_interface.h.cc b/src/itensor/itensor_interface.h.cc index 3f75376..a90f7f7 100644 --- a/src/itensor/itensor_interface.h.cc +++ b/src/itensor/itensor_interface.h.cc @@ -15,366 +15,1021 @@ template void static inline initRandomTensor(pybind11::module& module); - -template -static inline -py::class_< ITensorT > -initITensorT(pybind11::module& module, const char* name) -{ - +template +struct InitializerITensorT { + using index_type = IndexT; using itensor_type = ITensorT; using indexval_type = typename itensor_type::indexval_type; using storage_ptr = typename itensor_type::storage_ptr; using const_storage_ptr = typename itensor_type::const_storage_ptr; using scale_type = typename itensor_type::scale_type; - py::class_ type(module, name); - - pitensor::recursiveConstructor< - py::class_, - index_type const&, - index_type const&, - index_type const&, - index_type const&, - index_type const&, - index_type const&, - index_type const&, - index_type const&, - index_type const&, - index_type const& - >(type); - - type - // TODO: using list - .def(py::init()); - - type - .def_property_readonly("r", &itensor_type::r) - .def("__bool__", [](itensor_type const& obj) { return static_cast(obj);}) - - .def("real", - (Real (itensor_type::*)(indexval_type const &) const) &itensor_type::real) - .def("real", - (Real (itensor_type::*)(indexval_type const &, - indexval_type const &) const) &itensor_type::real) - .def("real", - (Real (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::real) - .def("real", - (Real (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::real) - .def("real", - (Real (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::real) - .def("real", - (Real (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::real) - .def("real", - (Real (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::real) - .def("real", - (Real (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::real) - .def("real", - (Real (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::real) - .def("real", - (Real (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::real) - - .def("cplx", - (Cplx (itensor_type::*)(indexval_type const &) const) &itensor_type::cplx) - .def("cplx", - (Cplx (itensor_type::*)(indexval_type const &, - indexval_type const &) const) &itensor_type::cplx) - .def("cplx", - (Cplx (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::cplx) - .def("cplx", - (Cplx (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::cplx) - .def("cplx", - (Cplx (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::cplx) - .def("cplx", - (Cplx (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::cplx) - .def("cplx", - (Cplx (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::cplx) - .def("cplx", - (Cplx (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::cplx) - .def("cplx", - (Cplx (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::cplx) - .def("cplx", - (Cplx (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &) const) &itensor_type::cplx) - .def("set", - (void (itensor_type::*)(Cplx)) &itensor_type::set) - .def("set", - (void (itensor_type::*)(indexval_type const &, Cplx const &)) &itensor_type::set) - .def("set", - (void (itensor_type::*)(indexval_type const &, - indexval_type const &, Cplx const &)) &itensor_type::set) - .def("set", - (void (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, Cplx const &)) &itensor_type::set) - .def("set", - (void (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, Cplx const &)) &itensor_type::set) - .def("set", - (void (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, Cplx const &)) &itensor_type::set) - .def("set", - (void (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, Cplx const &)) &itensor_type::set) - .def("set", - (void (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, Cplx const &)) &itensor_type::set) - .def("set", - (void (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, Cplx const &)) &itensor_type::set) - .def("set", - (void (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, Cplx const &)) &itensor_type::set) - .def("set", - (void (itensor_type::*)(indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, - indexval_type const &, Cplx const &)) &itensor_type::set) - .def("fill", &itensor_type::fill) - .def("generate", [](itensor_type& self, py::function &func) { - auto f = [&func]() -> Cplx { - py::object ret = func(); - return ret.cast(); - }; - self.generate(f); - }) - .def("apply", [](itensor_type& self, py::function &func) { - // TODO: take Cplx? or Real? - auto f = [&func](Cplx x) -> Cplx { - py::object ret = func(x); - return ret.cast(); - }; - self.apply(f); - }) - .def("visit", [](itensor_type& self, py::function &func) { - auto f = [&func](Cplx x) { - func(x); - }; - self.visit(f); + py::module & module; + const char * name; + py::class_ type; + + InitializerITensorT(pybind11::module & theModule, const char *theName) + : module (theModule), name(theName), type(module, name) { + initConstructor(); + initOperator(); + initRealCplx(); + } + + void initConstructor() { + pitensor::recursiveConstructor< + py::class_, + index_type const &, + index_type const &, + index_type const &, + index_type const &, + index_type const &, + index_type const &, + index_type const &, + index_type const &, + index_type const &, + index_type const & + >(type); // includes default constructor + + type + .def(py::init const &>()) + // don't need std::array or initializer list + .def(py::init()) + ; + } + + void initOperator() + { + type + .def_property_readonly("r", &itensor_type::r) + .def_property_readonly("inds", &itensor_type::inds) + .def("__bool__", [](itensor_type const &obj) { return static_cast(obj); }) + .def("__repr__", [](itensor_type const &obj) { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) + ; + + type + .def(py::self *= py::self) + .def(py::self /= py::self) + .def(py::self += py::self) + .def(py::self -= py::self) + .def(py::self *= Real()) + .def(py::self /= Real()) + .def(py::self *= Cplx()) + .def(py::self /= Cplx()) + .def("__neg__", [](itensor_type &self) { return -self; }) // TODO BEHAVIOR.... + ; + + } + + void initRealCplx() + { + type + .def("real", + (Real(itensor_type::*)(indexval_type const &) const) &itensor_type::real) + .def("real", + (Real(itensor_type::*)(indexval_type const &, + indexval_type const &) const) &itensor_type::real) + .def("real", + (Real(itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &) const) &itensor_type::real) + .def("real", + (Real(itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &) const) &itensor_type::real) + .def("real", + (Real(itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &) const) &itensor_type::real) + .def("real", + (Real(itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &) const) &itensor_type::real) + .def("real", + (Real(itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &) const) &itensor_type::real) + .def("real", + (Real(itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &) const) &itensor_type::real) + .def("real", + (Real(itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &) const) &itensor_type::real) + .def("real", + (Real(itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &) const) &itensor_type::real) + ; + + type + .def("cplx", + (Cplx(itensor_type::*)(indexval_type const &) const) &itensor_type::cplx) + .def("cplx", + (Cplx(itensor_type::*)(indexval_type const &, + indexval_type const &) const) &itensor_type::cplx) + .def("cplx", + (Cplx(itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &) const) &itensor_type::cplx) + .def("cplx", + (Cplx(itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &) const) &itensor_type::cplx) + .def("cplx", + (Cplx(itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &) const) &itensor_type::cplx) + .def("cplx", + (Cplx(itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &) const) &itensor_type::cplx) + .def("cplx", + (Cplx(itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &) const) &itensor_type::cplx) + .def("cplx", + (Cplx(itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &) const) &itensor_type::cplx) + .def("cplx", + (Cplx(itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &) const) &itensor_type::cplx) + ; + } + + void initMethod() + { + type + .def("set", + (void (itensor_type::*)(Cplx)) &itensor_type::set + ) + .def("set", + (void (itensor_type::*)(std::vector const &, + Cplx)) &itensor_type::set + ) + .def("set", + (void (itensor_type::*)(indexval_type const &, + Cplx const &)) &itensor_type::set) + .def("set", + (void (itensor_type::*)(indexval_type const &, + indexval_type const &, + Cplx const &)) &itensor_type::set) + .def("set", + (void (itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + Cplx const &)) &itensor_type::set) + .def("set", + (void (itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + Cplx const &)) &itensor_type::set) + .def("set", + (void (itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + Cplx const &)) &itensor_type::set) + .def("set", + (void (itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + Cplx const &)) &itensor_type::set) + .def("set", + (void (itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + Cplx const &)) &itensor_type::set) + .def("set", + (void (itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + Cplx const &)) &itensor_type::set) + .def("set", + (void (itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + Cplx const &)) &itensor_type::set) + .def("set", + (void (itensor_type::*)(indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + indexval_type const &, + Cplx const &)) &itensor_type::set) + ; + + // Using IndexType + + type + .def("fill", &itensor_type::fill) + /* + .def("generate", [](itensor_type &self, py::function &func) { + auto f = [&func]() -> Cplx { + py::object ret = func(); + return ret.cast(); + }; + self.generate(f); + }) + .def("apply", [](itensor_type &self, py::function &func) { + // TODO: take Cplx? or Real? + auto f = [&func](Cplx x) -> Cplx { + py::object ret = func(x); + return ret.cast(); + }; + self.apply(f); + }) + .def("visit", [](itensor_type &self, py::function &func) { + auto f = [&func](Cplx x) { + func(x); + }; + self.visit(f); + }) + */ + // TODO: check interface + .def("generate", [](itensor_type &self, std::function func) { + self.generate(func); + }) + .def("apply", [](itensor_type &self, std::function func) { + self.apply(func); + }) + .def("visit", [](itensor_type &self, std::function func) { + self.visit(func); + }) + .def("conj", &itensor_type::conj) + .def("dag", &itensor_type::dag) + .def("takeReal", &itensor_type::takeReal) + .def("takeImag", &itensor_type::takeImag) + ; + + type + .def("scale", py::overload_cast<>(&itensor_type::scale, py::const_)) + .def("scale", py::overload_cast<>(&itensor_type::scale)) + .def("store", py::overload_cast<>(&itensor_type::store, py::const_)) + .def("store", py::overload_cast<>(&itensor_type::store)) + .def("scaleTo", py::overload_cast(&itensor_type::scaleTo)) + .def("scaleTo", py::overload_cast(&itensor_type::scaleTo)) + .def("swap", &itensor_type::swap) + ; + } + + void initPrime() { + auto matchAny = [](index_type const &i, py::iterable specs) { + auto cmp_index_type = detail::IndexCmp(); + for (auto const &spec : specs) { + if (py::isinstance(spec)) { + auto t = spec.cast(); + if (i.type() == t) { return true; } + } else if (py::isinstance(spec)) { + auto j = spec.cast(); + if (cmp_index_type(i, j)) { return true; } + } else { + throw std::domain_error("Unsupported type in crits"); + } + } + return false; + }; + + type + .def("prime", [&matchAny](itensor_type &self, py::args args, py::kwargs kwargs) { + // args can be a mixture of IndexType and Index. + // An index of the ITensor will be primed if it + int inc = kwargs.contains(py::cast("inc")) ? kwargs[py::cast("inc")].cast() : 1; + auto inds = self.inds(); + for (auto const &ind : inds) { + if (matchAny(ind, args)) { self.prime(ind, inc); } + } + return self; + }) + .def("noprime", [&matchAny](itensor_type &self, py::args args) -> itensor_type & { + auto inds = self.inds(); + for (auto const &ind : inds) { + if (matchAny(ind, args)) { self.noprime(ind); } + } + return self; + }) + .def("primeExcept", [&matchAny](itensor_type &self, py::args args, py::kwargs kwargs) -> itensor_type & { + int inc = kwargs.contains(py::cast("inc")) ? kwargs[py::cast("inc")].cast() : 1; + auto inds = self.inds(); + for (auto const &ind : inds) { + if (!matchAny(ind, args)) { self.prime(ind, inc); } + } + return self; + }) + .def("mapprime", + (itensor_type &(itensor_type::*)(int, + int, + IndexType)) &itensor_type::mapprime, + py::arg("plevold"), + py::arg("plevnew"), + py::arg("type") = All + ); + +#if 0 + type + // noprime + .def("noprime", + (itensor_type& (itensor_type::*)()) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(IndexType const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&)) &itensor_type::noprime + ) + // prime + .def("prime", + (itensor_type& (itensor_type::*)(int)) &itensor_type::prime, + py::arg("inc")=1 + ) + .def("prime", + (itensor_type& (itensor_type::*)(IndexType const&, + int)) &itensor_type::prime, + py::arg("type"), + py::arg("inc")=1 + ) + .def("prime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + int)) &itensor_type::prime, + py::arg("type1"), + py::arg("type2"), + py::arg("inc")=1 + ) + .def("prime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const& + int)) &itensor_type::prime, + py::arg("type1"), + py::arg("type2"), + py::arg("type3"), + py::arg("inc")=1 + ) + .def("prime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const&, + IndexType const& + int)) &itensor_type::prime, + py::arg("type1"), + py::arg("type2"), + py::arg("type3"), + py::arg("type4"), + py::arg("inc")=1 + ) + .def("prime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const& + int)) &itensor_type::prime, + py::arg("type1"), + py::arg("type2"), + py::arg("type3"), + py::arg("type4"), + py::arg("type5"), + py::arg("inc")=1 + ) + .def("prime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const& + int)) &itensor_type::prime, + py::arg("type1"), + py::arg("type2"), + py::arg("type3"), + py::arg("type4"), + py::arg("type5"), + py::arg("type6"), + py::arg("inc")=1 + ) + .def("prime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const& + int)) &itensor_type::prime, + py::arg("type1"), + py::arg("type2"), + py::arg("type3"), + py::arg("type4"), + py::arg("type5"), + py::arg("type6"), + py::arg("type7"), + py::arg("inc")=1 + ) + .def("prime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const& + int)) &itensor_type::prime, + py::arg("type1"), + py::arg("type2"), + py::arg("type3"), + py::arg("type4"), + py::arg("type5"), + py::arg("type6"), + py::arg("type7"), + py::arg("type8"), + py::arg("inc")=1 + ) + .def("prime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const& + int)) &itensor_type::prime, + py::arg("type1"), + py::arg("type2"), + py::arg("type3"), + py::arg("type4"), + py::arg("type5"), + py::arg("type6"), + py::arg("type7"), + py::arg("type8"), + py::arg("type9"), + py::arg("inc")=1 + ) + .def("prime", + (itensor_type& (itensor_type::*)(IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const&, + IndexType const& + int)) &itensor_type::prime, + py::arg("type1"), + py::arg("type2"), + py::arg("type3"), + py::arg("type4"), + py::arg("type5"), + py::arg("type6"), + py::arg("type7"), + py::arg("type8"), + py::arg("type9"), + py::arg("type10"), + py::arg("inc")=1 + ) + ; +#endif + + //TODO Use args, and kwargs for inc +#if 0 + type + .def("prime", [](itensor_type & self, py::args args, py::kwargs kwargs) { + int inc = 1; + if(kwargs.contains("inc"_a)) { + inc = kwargs["inc"_a].cast(); + // TODO: check domain of inc + } // TODO: check this works + + if (py::len(args) == 0) { + // prime all indices + return self.prime(inc); + } else { + bool all_IndexType = true; + bool all_IndexT = true; + for (auto const &item : args) { + all_IndexType = all_IndexType && (py::isinstance(item)); + all_IndexT = all_IndexT && (py::isinstance(item)); + } + + if(all_IndexType) { + //TODO MAtch + + } else if (all_IndexT) { + //TODO MAtch + } + } + //detail::computeMatchInc() }) - .def("conj", &itensor_type::conj) - .def("dag", &itensor_type::dag) - .def("takeReal", &itensor_type::takeReal) - .def("takeImag", &itensor_type::takeImag) - ; + ; +#endif - type - .def(py::self *= py::self) - .def(py::self /= py::self) - .def(py::self += py::self) - .def(py::self -= py::self) - .def(py::self *= Real()) - .def(py::self /= Real()) - .def(py::self *= Cplx()) - .def(py::self /= Cplx()) - .def("__neg__", [](itensor_type & self) { return -self; }) // TODO BEHAVIOR.... - ; +#if 0 + type + .def("noprime", + (itensor_type& (itensor_type::*)(index_type const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::noprime + ) + .def("noprime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::noprime + ) + // prime + .def("prime", + (itensor_type& (itensor_type::*)()) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + // primeExcept + .def("prime", + (itensor_type& (itensor_type::*)()) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + .def("prime", + (itensor_type& (itensor_type::*)(index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&, + index_type const&)) &itensor_type::prime + ) + ; +#endif - type - .def("scale", py::overload_cast<>(&itensor_type::scale, py::const_)) - .def("scale", py::overload_cast<>(&itensor_type::scale)) - .def("store", py::overload_cast<>(&itensor_type::store, py::const_)) - .def("store", py::overload_cast<>(&itensor_type::store)) - .def("scaleTo", py::overload_cast(&itensor_type::scaleTo)) - .def("scaleTo", py::overload_cast(&itensor_type::scaleTo)) - .def("swap", &itensor_type::swap) + } - .def("__repr__", [](itensor_type const & obj) { std::stringstream ss; ss << obj; return ss.str(); }) - ; - module - // TODO: setElt - // TODO: prime - // TODO: primeExcept - // TODO: noprime - // TODO: mapprime - // TODO: sim - .def("hasindex", - (bool (*)(itensor_type const &, index_type const &))&hasindex) // TODO: why redundant type spec? - .def("findtype", - (index_type (*)(itensor_type const &, IndexType))&findtype) - // TODO: findindex - .def("commonIndex", - (index_type (*)(itensor_type const &, itensor_type const &, IndexType))&commonIndex, - py::arg("A"), - py::arg("B"), - py::arg("t")=All) - .def("uniqueIndex", - (index_type (*)(itensor_type const &, itensor_type const &, IndexType))&uniqueIndex, - py::arg("A"), - py::arg("B"), - py::arg("t")) // TODO: default argument? - - .def("swapPrime", - (itensor_type (*)(itensor_type, int, int, IndexType))&swapPrime, - py::arg("T"), - py::arg("plev1"), - py::arg("plev2"), - py::arg("type")=All) - // TODO: apply - .def("realPart", - (itensor_type (*)(itensor_type)) &realPart) - .def("imagPart", - (itensor_type (*)(itensor_type)) &imagPart) - .def("isComplex", - (bool (*)(itensor_type const &)) &isComplex) - .def("isReal", - (bool (*)(itensor_type const &)) &isReal) - .def("rank", - (long (*)(itensor_type const &)) &rank) - .def("order", - (long (*)(itensor_type const &)) &order) - .def("norm", - (Real (*)(itensor_type const &)) &norm) - .def("randomize", - (void (*)(itensor_type &, Args const &)) &randomize, - py::arg("T"), - py::arg("args")=Args::global()) - .def("random", - (itensor_type (*)(itensor_type, Args const &)) &random, - py::arg("T"), - py::arg("args")=Args::global()) - .def("conj", - (itensor_type (*)(itensor_type)) &conj) - .def("dag", - (itensor_type (*)(itensor_type)) &dag) - .def("sumels", - (Real (*)(itensor_type const &)) &sumels) - .def("sumelsC", - (Cplx (*)(itensor_type const &)) &sumelsC) + + void initFunction() + { + module + // TODO: setElt + // TODO: Check prime + .def("prime", + [](itensor_type self, py::args args, py::kwargs kwargs) -> itensor_type { + int inc = kwargs.contains(py::cast("inc")) ? kwargs[py::cast("inc")].cast() : 1; + for (auto const &item : args) { + if (py::isinstance(item)) { + self.prime(item.cast(), inc); + // TODO: Can IndexType overlap? multiple prime? probably not... + // https://github.com/ITensor/ITensor/blob/e459a293b69a51c47844e57aa4b86cb75b8870ee/itensor/iqindex.h#L150 + } else if (py::isinstance(item)) { + self.prime(item.cast(), inc); + } + } + return self; + }) + // TODO: primeExcept + .def("noprime", [](itensor_type self, py::args args, py::kwargs kwargs) -> itensor_type { + for (auto const &item : args) { + if (py::isinstance(item)) { + self.noprime(item.cast()); + } else if (py::isinstance(item)) { + self.noprime(item.cast()); + } + } + return self; + }) + .def("mapprime", + (itensor_type (*)(itensor_type, int const &, int const &, IndexType const &)) &mapprime, + py::arg("A"), + py::arg("plevold"), + py::arg("plevnew"), + py::arg("type") = All + ) + // TODO: mapprime with variadic blah + // TODO: sim + .def("hasindex", + (bool (*)(itensor_type const &, index_type const &)) &hasindex) // TODO: why redundant type spec? + .def("findtype", + (index_type (*)(itensor_type const &, IndexType)) &findtype) + // TODO: findindex + .def("findindex", [](itensor_type const &T, std::function const &cond) { + return findindex(T, cond); + }) + .def("commonIndex", + (index_type (*)(itensor_type const &, itensor_type const &, IndexType)) &commonIndex, + py::arg("A"), + py::arg("B"), + py::arg("t") = All) + .def("uniqueIndex", + (index_type (*)(itensor_type const &, itensor_type const &, IndexType)) &uniqueIndex, + py::arg("A"), + py::arg("B"), + py::arg("t")) // TODO: default argument? + .def("swapPrime", + (itensor_type (*)(itensor_type, int, int, IndexType)) &swapPrime, + py::arg("T"), + py::arg("plev1"), + py::arg("plev2"), + py::arg("type") = All) + // TODO: apply + .def("realPart", + (itensor_type (*)(itensor_type)) &realPart) + .def("imagPart", + (itensor_type (*)(itensor_type)) &imagPart) + .def("isComplex", + (bool (*)(itensor_type const &)) &isComplex) + .def("isReal", + (bool (*)(itensor_type const &)) &isReal) + .def("rank", + (long (*)(itensor_type const &)) &rank) + .def("order", + (long (*)(itensor_type const &)) &order) + .def("norm", + (Real(*)(itensor_type const &)) &norm) + .def("randomize", + (void (*)(itensor_type &, Args const &)) &randomize, + py::arg("T"), + py::arg("args") = Args::global()) + .def("random", + (itensor_type (*)(itensor_type, Args const &)) &random, + py::arg("T"), + py::arg("args") = Args::global()) + .def("conj", + (itensor_type (*)(itensor_type)) &conj) + .def("dag", + (itensor_type (*)(itensor_type)) &dag) + .def("sumels", + (Real(*)(itensor_type const &)) &sumels) + .def("sumelsC", + (Cplx(*)(itensor_type const &)) &sumelsC) // TODO multiSiteOps - ; + ; + + return type; + } // initITensorT(pybind11::module& module, const char* name) +}; - return type; -} // initITensorT(pybind11::module& module, const char* name) void pitensor::itensor_interface(pybind11::module& module) { - auto typeITensor = initITensorT(module, "ITensor"); - auto typeIQTensor = initITensorT(module, "IQTensor"); + auto initITensor = InitializerITensorT(module, "ITensor"); + auto initIQTensor = InitializerITensorT(module, "IQTensor"); + + auto typeITensor = initITensor.type; + auto typeIQTensor = initIQTensor.type; + + //auto typeITensor = InitializerinitITensorT(module, "ITensor"); + //auto typeIQTensor = initITensorT(module, "IQTensor"); typeITensor .def(py::self *= IndexVal()) @@ -463,6 +1118,11 @@ void pitensor::itensor_interface(pybind11::module& module) Index const &)) &delta) ; + typeIQTensor + //TODO specialization for IQTensor + // .def('__imul__', ) + ; + //initDiagTensor<>(module); initDiagTensor >(module); From b72726e0a0eb53646e2c7cf3b898dff32d6edd78 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:24:32 -0400 Subject: [PATCH 19/41] Update real.h.cc --- src/itensor/real.h.cc | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/itensor/real.h.cc b/src/itensor/real.h.cc index 95f8fcb..c8ac746 100644 --- a/src/itensor/real.h.cc +++ b/src/itensor/real.h.cc @@ -28,11 +28,18 @@ void pitensor::real(pybind11::module& module) .def("isTooSmallForReal", &LogNum::isTooSmallForReal) .def("real", &LogNum::real) .def("real0", &LogNum::real0) + .def("approxEquals", &LogNum::approxEquals) + .def("negate", &LogNum::negate) + .def("swap", &LogNum::swap) + .def("magnitudeLessThan", &LogNum::magnitudeLessThan) + .def("pow", &LogNum::pow) + ; + // TODO read write + + type .def(py::self += py::self) .def(py::self == py::self) .def(py::self != py::self) - .def("approxEquals", &LogNum::approxEquals) - .def("negate", &LogNum::negate) .def(py::self *= py::self) .def(py::self *= Real()) .def(py::self /= py::self) @@ -46,16 +53,14 @@ void pitensor::real(pybind11::module& module) .def(py::self >= py::self) .def(py::self * Real()) .def(Real() * py::self) - .def("swap", &LogNum::swap) - .def("magnitudeLessThan", &LogNum::magnitudeLessThan) - .def("pow", &LogNum::pow) ; - module - .def("sqrt", - (LogNum (*)(LogNum)) &sqrt ) - ; type .def("__repr__", [](LogNum const & self) { std::stringstream ss; ss << std::scientific << self; ss.str(); }) ; + + module + .def("sqrt", (LogNum (*)(LogNum)) &sqrt ) + .def("isnan",[](LogNum const & i) -> bool { return isnan(i); }) + ; } From b5fa925a2a0897213143a2f6a04e19cff498835d Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:24:46 -0400 Subject: [PATCH 20/41] Update autompo.h.cc --- src/itensor/mps/autompo.h.cc | 56 +++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/itensor/mps/autompo.h.cc b/src/itensor/mps/autompo.h.cc index 677c1f0..480f4be 100644 --- a/src/itensor/mps/autompo.h.cc +++ b/src/itensor/mps/autompo.h.cc @@ -96,11 +96,65 @@ auto initAutoMPO(pybind11::module& module) .def("terms", &AutoMPO::terms) .def("toMPO", [](AutoMPO const & self) -> MPO { return MPO(self);}) .def("toIQMPO", [](AutoMPO const & self) -> IQMPO { return IQMPO(self);}) - // TODO Accumulator .def("add", &AutoMPO::add) .def("reset", &AutoMPO::reset) .def("__repr__", [](AutoMPO const & obj) { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) ; + + // TODO: Decision + // Using += iterable instead of Accumulator. Is this a good idea? + type + .def("__iadd__", + [](AutoMPO & ampo, HTerm const & hterm) { ampo.add(hterm); return ampo; } + ) + .def("__iadd__", + [](AutoMPO & ampo, py::iterable obj) { + Complex coeff = 1.0; + HTerm hterm; + enum class State {New, Op} state = State::New; + std::string op; + for (auto const & item : obj) { + if (py::isinstance(item)) { + coeff *= item.cast(); + } else if (py::isinstance>(item)) { // TODO: pybind11 does not implement complex type + coeff *= item.cast(); + } else if (py::isinstance(item)) { + switch(state) { + case State::New: + op = item.cast(); + state = State::Op; + break; + case State::Op: + throw std::domain_error("Invalid input to AutoMPO (two strings in a row?)"); + break; + } + } else if (py::isinstance(item)) { + auto i = item.cast(); + switch(state) { + case State::New: + hterm *= static_cast(i); + break; + case State::Op: + hterm.add(op, i); + state = State::New; + op = ""; + break; + } + } else { + throw std::domain_error("Invalid input to AutoMPO (unsupported type)"); + } + } + + if (!hterm) { + throw std::domain_error("Invalid input to AutoMPO (no operators)"); + } + hterm *= coeff; + ampo.add(hterm); + return ampo; + } + ) + ; + return type; } From db5a2ae2ecd62c4a91185dee4719db0b116afd0b Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:24:56 -0400 Subject: [PATCH 21/41] Update bondgate.h.cc --- src/itensor/mps/bondgate.h.cc | 54 +++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/itensor/mps/bondgate.h.cc b/src/itensor/mps/bondgate.h.cc index 62b6548..cd1409f 100644 --- a/src/itensor/mps/bondgate.h.cc +++ b/src/itensor/mps/bondgate.h.cc @@ -3,5 +3,59 @@ namespace py = pybind11; using namespace itensor; +template +static inline +auto +initBondGate(py::module& module, const char * typeName) +{ + using GateType = BondGate; + py::class_ type(module, typeName); + + py::enum_(type, "Type") + .value("tReal", GateType::tReal) + .value("tImag", GateType::tImag) + .value("Swap", GateType::Swap) + .export_values() + ; + + type + .def(py::init(), + py::arg("sites"), + py::arg("i1"), + py::arg("i2") + ) + .def(py::init(), + py::arg("sites"), + py::arg("i1"), + py::arg("i2"), + py::arg("type"), + py::arg("tau"), + py::arg("bondH") + ) + ; + + type + .def_property_readonly("i1", &GateType::i1) + .def_property_readonly("i2", &GateType::i2) + .def_property_readonly("gate", &GateType::gate) + .def_property_readonly("type", &GateType::type) + ; + + type + .def(py::self * Tensor()) + .def(Tensor() * py::self) + ; + + return type; +} void pitensor::mps::bondgate(pybind11::module& module) { + auto typeGate = initBondGate(module, "Gate"); + auto typeIQGate = initBondGate(module, "IQGate"); } From 90271b712ca7e428005488af82a5a28f44a96f8c Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:25:06 -0400 Subject: [PATCH 22/41] Update hambuilder.h.cc --- src/itensor/mps/hambuilder.h.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/itensor/mps/hambuilder.h.cc b/src/itensor/mps/hambuilder.h.cc index 632c844..a371ac0 100644 --- a/src/itensor/mps/hambuilder.h.cc +++ b/src/itensor/mps/hambuilder.h.cc @@ -71,7 +71,12 @@ initHamBuilder(pybind11::module& module, const char* typeName) type .def(py::self *= Real()) .def(py::self *= Complex()) + .def(py::self * Real()) + .def(Real() * py::self) + .def(py::self * Complex()) + .def(Complex() * py::self) // TODO operators + #if 0 .def("__mul__", [](HamBuilder const & hb, Real x) { return hb * x; }) @@ -84,6 +89,7 @@ initHamBuilder(pybind11::module& module, const char* typeName) .def("__mul__", [](Complex x, HamBuilder const & hb) { return x * hb; }) + #endif ; return type; } From f9f08ff242f482808ec7539a4b712f89f4e40de6 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:25:18 -0400 Subject: [PATCH 23/41] Update idmrg.h.cc --- src/itensor/mps/idmrg.h.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/itensor/mps/idmrg.h.cc b/src/itensor/mps/idmrg.h.cc index d38da30..4a5be99 100644 --- a/src/itensor/mps/idmrg.h.cc +++ b/src/itensor/mps/idmrg.h.cc @@ -1,5 +1,6 @@ #include "../../pitensor.h" #include "itensor/mps/idmrg.h" + namespace py = pybind11; using namespace itensor; From 67e0b4b547797622324c11a4b57c22e7c304143a Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:25:28 -0400 Subject: [PATCH 24/41] Update localmpo.h.cc --- src/itensor/mps/localmpo.h.cc | 91 +++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/src/itensor/mps/localmpo.h.cc b/src/itensor/mps/localmpo.h.cc index 3eff2ba..feef985 100644 --- a/src/itensor/mps/localmpo.h.cc +++ b/src/itensor/mps/localmpo.h.cc @@ -3,5 +3,96 @@ namespace py = pybind11; using namespace itensor; +template +auto +initLocalMPO(pybind11::module& module, const char* typeName) { + using Type = LocalMPO; + using mpo_type = MPOt; + using mps_type = MPSt; + + py::class_ type(module, typeName); + + type + .def(py::init<>()) + .def(py::init(), + py::arg("H"), + py::arg("args")=Args::global() + ) + .def(py::init(), + py::arg("psi"), + py::arg("args")=Args::global() + ) + .def(py::init(), + py::arg("H"), + py::arg("LH"), + py::arg("RH"), + py::arg("args")=Args::global() + ) + .def(py::init(), + py::arg("psi"), + py::arg("LP"), + py::arg("RP"), + py::arg("args")=Args::global() + ) + .def(py::init(), + py::arg("H"), + py::arg("LH"), + py::arg("LHlim"), + py::arg("RH"), + py::arg("RHlim"), + py::arg("args")=Args::global() + ) + ; + + type + .def("product", &Type::product) + .def("expect", &Type::expect) + .def("deltaRho", &Type::deltaRho) + .def("diag", &Type::diag) + // TODO position + .def("shift", &Type::shift) + .def("reset", &Type::reset) + // Accessor methods + .def_property("L", + (Tensor const & (Type::*)() const) &Type::L, + (void (Type::*)(Tensor const &)) &Type::L + ) + // TODO L with int and Tensor + .def_property("R", + (Tensor const & (Type::*)() const) &Type::R, + (void (Type::*)(Tensor const &)) &Type::R + ) + // TODO R with int and Tensor + .def_property_readonly("H", &Type::H) + .def_property("numCenter", + (int (Type::*)() const) &Type::numCenter, + (void (Type::*)(int)) &Type::numCenter + ) + .def_property_readonly("size", &Type::size) + .def("__bool__", [](Type const & self) { return static_cast(self); }) + .def_property("doWrite", + (bool (Type::*)() const) &Type::doWrite, + (void (Type::*)(bool)) &Type::doWrite + ) + .def_property_readonly("writeDir", &Type::writeDir) + .def_property_readonly("leftLim", &Type::leftLim) + .def_property_readonly("rightLim", &Type::rightLim) + ; + return type; +} + void pitensor::mps::localmpo(pybind11::module& module) { + auto typeLocalMPO = initLocalMPO(module, "LocalMPO"); + auto typeIQLocalMPO = initLocalMPO(module, "IQLocalMPO"); } From 4c652988ee0de183c7a481c3fc280b4502960198 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:25:40 -0400 Subject: [PATCH 25/41] Update localop.h.cc --- src/itensor/mps/localop.h.cc | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/itensor/mps/localop.h.cc b/src/itensor/mps/localop.h.cc index 9e887f3..4a6b0be 100644 --- a/src/itensor/mps/localop.h.cc +++ b/src/itensor/mps/localop.h.cc @@ -3,5 +3,61 @@ namespace py = pybind11; using namespace itensor; +template +auto +initLocalOp(pybind11::module& module, const char* typeName) +{ + using Type = LocalOp; + py::class_ type(module, typeName); + + type + .def(py::init<>()) + .def(py::init(), + py::arg("Op1"), + py::arg("Op2"), + py::arg("args")=Args::global() // TODO: report to ITensor (Global::args vs Args::global) + ) + .def(py::init(), + py::arg("Op1"), + py::arg("Op2"), + py::arg("L"), + py::arg("R"), + py::arg("args")=Args::global() // TODO: report to ITensor (Global::args vs Args::global) + ) + ; + type + .def("product", &Type::product) + .def("expect", &Type::expect) + .def("deltaRho", &Type::deltaRho) + .def("diag", &Type::diag) + .def("size", &Type::size) + .def("update", + (void (Type::*)(Tensor const &, Tensor const &)) &Type::update, + py::arg("Op1"), + py::arg("Op2") + ) + .def("update", + (void (Type::*)(Tensor const &, + Tensor const &, + Tensor const &, + Tensor const &)) &Type::update, + py::arg("Op1"), + py::arg("Op2"), + py::arg("L"), + py::arg("R") + ) + .def_property_readonly("Op1", &Type::Op1) + .def_property_readonly("Op2", &Type::Op2) + .def_property_readonly("L", &Type::L) + .def_property_readonly("R", &Type::R) + .def("__bool__", [](Type const & self) { return static_cast(self); }) + .def_property_readonly("LIsNull", &Type::LIsNull) + .def_property_readonly("RIsNull", &Type::RIsNull) + ; + return type; +} + void pitensor::mps::localop(pybind11::module& module) { + auto typeLocalOp = initLocalOp(module, "LocalOp"); + auto typeIQLocalOp = initLocalOp(module, "IQLocalOp"); } From 5ea73d55443d541dc4ef0d0e0c640da8e1883e32 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:25:49 -0400 Subject: [PATCH 26/41] Update mpo.h.cc --- src/itensor/mps/mpo.h.cc | 100 ++++++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 12 deletions(-) diff --git a/src/itensor/mps/mpo.h.cc b/src/itensor/mps/mpo.h.cc index ecaa1c4..567ead5 100644 --- a/src/itensor/mps/mpo.h.cc +++ b/src/itensor/mps/mpo.h.cc @@ -156,19 +156,95 @@ initMPOt(pybind11::module& module, const char* typeName) py::arg("args") = Args::global() // TODO: ITensor does not have default argument here. ) - // TODO fitApplyMPO - // TODO fitApplyMPO - // TODO fitApplyMPO - // TODO fitApplyMPO - // TODO fitApplyMPO - // TODO expH - // TODO applyExpH - // TODO putMPOLinks - // TODO putMPOLinks - // TODO exactApplyMPO - // TODO exactApplyMPO - .def("__repr__", [](mpo_type const & obj) { std::stringstream ss; ss << obj; return ss.str(); }) + .def("fitApplyMPO", + (Real (*)(mps_type const &, + Real, + mps_type const &, + mpo_type const &, + mps_type &, + Args const & + )) &fitApplyMPO, + py::arg("psiA"), + py::arg("mpofac"), + py::arg("psiB"), + py::arg("H"), + py::arg("res"), + py::arg("args") = Args::global() + ) + .def("fitApplyMPO", + (Real (*)(Real, + mps_type const &, + Real, + mps_type const &, + mpo_type const &, + mps_type &, + Args const & + )) &fitApplyMPO, + py::arg("mpsfac"), + py::arg("psiA"), + py::arg("mpofac"), + py::arg("psiB"), + py::arg("H"), + py::arg("res"), + py::arg("args") = Args::global() + ) + .def("expH", + (void (*)(mpo_type const &, + mpo_type &, + Real, + Real, + Real, + int, + Args // TODO: report to ITensor + )) &expH, + py::arg("H"), + py::arg("K"), + py::arg("tau"), + py::arg("Etot"), + py::arg("Kcutoff"), + py::arg("ndoub"), + py::arg("args") = Args::global() + ) + .def("applyExpH", + (void (*)(mps_type const &, + mpo_type const &, + Real, + mps_type &, + Args const & + )) &applyExpH, + py::arg("psi"), + py::arg("H"), + py::arg("tau"), + py::arg("res"), + py::arg("args") = Args::global() + ) + // TODO putMPOLinks + // TODO putMPOLinks + .def("exactApplyMPO", + (mps_type (*)(mps_type const &, + mpo_type const &, + Args const & + )) &exactApplyMPO, + py::arg("x"), + py::arg("K"), + py::arg("args") = Args::global() + ) + .def("exactApplyMPO", + (void (*)(mps_type const &, + mpo_type const &, + mps_type &, + Args const & + )) &exactApplyMPO, + py::arg("x"), + py::arg("K"), + py::arg("res"), + py::arg("args") = Args::global() + ) + .def("__repr__", [](mpo_type const & obj) { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) ; + // TODO: psiHphi + // TODO: psiHphiC + return type; } From 2e9f67b7e59852dfff2b2d806be8d694170c966e Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:25:59 -0400 Subject: [PATCH 27/41] Update mps.h.cc --- src/itensor/mps/mps.h.cc | 145 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 135 insertions(+), 10 deletions(-) diff --git a/src/itensor/mps/mps.h.cc b/src/itensor/mps/mps.h.cc index d7f89e3..aa57a9e 100644 --- a/src/itensor/mps/mps.h.cc +++ b/src/itensor/mps/mps.h.cc @@ -13,19 +13,37 @@ initMPSt(pybind11::module& module, const char* typeName) using IndexT = typename Tensor::index_type; using IndexValT = typename Tensor::indexval_type; using MPOType = MPOt; + using Type = mps_type; - py::class_> type(module, typeName); - type.def(py::init<>()); - type.def(py::init()); - type.def(py::init()); - type.def(py::init()); + py::class_ type(module, typeName); + + type + .def(py::init<>()) + .def(py::init()) + .def(py::init()) + .def(py::init()) + .def(py::init()) + ; + + type + .def("assign", [](mps_type & self, mps_type const & other) { + self = other; + return self; + }) + ; type .def("N", (int (mps_type::*)() const) &mps_type::N) - .def("sites", (SiteSet const & (mps_type::*)() const) &mps_type::sites) + .def_property_readonly("sites", (SiteSet const & (mps_type::*)() const) &mps_type::sites) .def("__bool__", [](mps_type const & self) { return static_cast(self);}) - .def("rightLim", (int (mps_type::*)() const) &mps_type::rightLim) - .def("leftLim", (int (mps_type::*)() const) &mps_type::leftLim) + .def_property("rightLim", + [](mps_type const & self) { return self.rightLim(); }, + [](mps_type & self, int i) { self.rightLim(i); } + ) + .def_property("leftLim", + [](mps_type const & self) { return self.leftLim(); }, + [](mps_type & self, int i) { self.leftLim(i); } + ) .def("A", (Tensor const & (mps_type::*)(int) const) &mps_type::A) .def("setA", (void (mps_type::*)(int, Tensor const &)) &mps_type::setA) //TODO void setA(int i, Tensor && nA) ; @@ -57,18 +75,125 @@ initMPSt(pybind11::module& module, const char* typeName) (void (mps_type::*)(Args const&)) &mps_type::orthogonalize, py::arg("args") = Args::global()) .def("swap", (void (mps_type::*)(mps_type& other)) &mps_type::swap) - .def("rightLim", (void (mps_type::*)(int)) &mps_type::rightLim) - .def("leftLim", (void (mps_type::*)(int)) &mps_type::leftLim) .def("norm", (Real (mps_type::*)() const) &mps_type::norm) .def("normalize", (Real (mps_type::*)()) &mps_type::normalize) .def("isOrtho", (bool (mps_type::*)() const) &mps_type::isOrtho) .def("orthoCenter", (int (mps_type::*)() const) &mps_type::orthoCenter) .def("isComplex", (bool (mps_type::*)() const) &mps_type::isComplex) ; + + type + /* + .def("write", [](Type const & self, py::object pyostream) { + pitensor::pythonbytebuf buffer(pyostream); + std::ostream output_stream(&buffer); + self.write(output_stream); + }) + */ + // TODO: read with file stream + //.def("write", [](Type const & self, std::string const & filename) { + .def("write", [](Type const & self, py::object arg) { + if (py::isinstance(arg)) { + std::ofstream output_stream(arg.cast()); + self.write(output_stream); + } else { + auto io = py::module::import("io"); + if (py::isinstance(arg, io.attr("BufferedWriter"))) { + // TODO: Create PyBind Wrapper for BufferedWriter + std::ostringstream output_stream; + self.write(output_stream); + arg.attr("write")(py::bytes(output_stream.str())); + } else { + throw std::domain_error("Unsupported argument type for write"); + } + } + return self; + }) + //.def("read", [](Type & self, std::string const & filename) { + .def("read", [](Type & self, py::object arg) { + if (py::isinstance(arg)) { + std::ifstream input_stream(arg.cast()); + self.read(input_stream); + } else { + auto io = py::module::import("io"); + if (py::isinstance(arg, io.attr("BufferedReader"))) { + py::bytes data = arg.attr("read")(); + std::istringstream input_stream(data); + self.read(input_stream); + } else { + throw std::domain_error("Unsupported argument type for read"); + } + } + return self; + }) + //.def("read", (void (mps_type::*)(std::istream&)) &mps_type::read) + ; + type + .def("__repr__", [](Type const & obj) { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) + ; + + + module + .def("isComplex", (bool (*)(mps_type const &)) &isComplex) + .def("isOrtho", (bool (*)(mps_type const &)) &isOrtho) + .def("orthoCenter", (int (*)(mps_type const&)) &orthoCenter) + .def("norm", (Real (*)(mps_type const&)) &norm) + .def("normalize", (Real (*)(mps_type &)) &normalize) + .def("linkInd", (IndexT (*)(mps_type const&, int)) &linkInd) + .def("rightLinkInd", (IndexT (*)(mps_type const&, int)) &rightLinkInd) + .def("leftLinkInd", (IndexT (*)(mps_type const&, int)) &leftLinkInd) + .def("averageM", (Real (*)(mps_type const&)) &averageM) + .def("maxM", (int (*)(mps_type const&)) &maxM) + .def("applyGate", (void (*)(const Tensor&, mps_type&, const Args&)) &applyGate) + .def("checkOrtho", (bool (*)(const mps_type& psi, int, bool)) &checkOrtho) + .def("checkOrtho", (bool (*)(mps_type const& psi)) &checkOrtho) + .def("checkQNs", (bool (*)(mps_type const& psi)) &checkQNs) + .def("overlap", (Real (*)(mps_type const&, mps_type const&)) &overlap) + .def("overlapC", (Cplx (*)(mps_type const&, mps_type const&)) &overlapC) + .def("overlap", (void (*)(mps_type const&, mps_type const&, Real&, Real&)) &overlap) + .def("fitWF", (void (*)(const mps_type&, mps_type&)) &fitWF) + .def("sum", (mps_type (*)(mps_type const&, mps_type const&, Args const&)) &sum) + .def("sum", (mps_type (*)(std::vector const&, Args const&)) &sum) + ; + + return type; +} + + +static inline +auto +initInitState(pybind11::module& module) +{ + using Type = InitState; + py::class_ type(module, "InitState"); + type + .def(py::init()) + .def(py::init()) + ; + type + .def("set", &InitState::set) + .def("setAll", &InitState::setAll) + .def("__getitem__", [](InitState const & state, int i) { + return state(i); + }) + .def_property_readonly("sites", &InitState::sites) + ; + + type + .def("__repr__", [](Type const & obj) { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) + ; + return type; } void pitensor::mps::mps(pybind11::module& module) { initMPSt(module, "MPS"); initMPSt(module, "IQMPS"); + + module + .def("findCenter", (int (*)(IQMPS const& psi)) &findCenter) + .def("totalQN", (QN (*)(IQMPS const& psi)) &totalQN) + ; + + initInitState(module); } From e9ba9a31feb50b02fc68ad1c9e498db94f9864f5 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:26:09 -0400 Subject: [PATCH 28/41] Update siteset.h.cc --- src/itensor/mps/siteset.h.cc | 93 ++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 41 deletions(-) diff --git a/src/itensor/mps/siteset.h.cc b/src/itensor/mps/siteset.h.cc index b9fb509..ab5c975 100644 --- a/src/itensor/mps/siteset.h.cc +++ b/src/itensor/mps/siteset.h.cc @@ -7,6 +7,7 @@ static inline auto initSiteSet(pybind11::module& module) { + using Type = SiteSet; using String = SiteSet::String; py::class_ type(module, "SiteSet"); @@ -16,57 +17,67 @@ initSiteSet(pybind11::module& module) type .def("__bool__", [](SiteSet const & self) { return static_cast(self); }) - .def("N", &SiteSet::N) + .def("__getitem__", [](SiteSet const & self, int i) { + if (i <= 0 || i > self.N()) { + throw std::invalid_argument("SiteSet::operator(i) out of bounds"); + } + return self(i); + }) .def("__call__", [](SiteSet const & self, int i) { - // TODO check for bound - if (i <= 0 || i > self.N()) { - throw ITError("SiteSet::operator(i) out of bounds"); - } - return self(i); - }) + // TODO check for bound + if (i <= 0 || i > self.N()) { + throw std::invalid_argument("SiteSet::operator(i) out of bounds"); + } + return self(i); + }) .def("__call__", [](SiteSet const & self, int i, - std::string const & state) { - // TODO check for bound - if (i <= 0 || i > self.N()) { - throw ITError("SiteSet::operator(i) out of bounds"); - } - return self(i, state); - }) + std::string const & state) { // TODO check for bound + if (i <= 0 || i > self.N()) { + throw std::invalid_argument("SiteSet::operator(i) out of bounds"); + } + return self(i, state); + }) + .def("__repr__", [](Type const & obj) { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) + ; + + type + .def("N", &SiteSet::N) .def("op", [](SiteSet const & self, String const & opname, int i, Args const & args) { - // TODO bound checking - return self.op(opname, i, args); - }, - py::arg("opname"), - py::arg("i"), - py::arg("args") = Args::global()) - // TODO read, write + return self.op(opname, i, args); + // TODO bound checking + }, + py::arg("opname"), + py::arg("i"), + py::arg("args")=Args::global() + ) .def("si", [](SiteSet const & self, int i) { - if (i <= 0 || i > self.N()) { // TODO check for bound - throw ITError("SiteSet::operator(i) out of bounds"); - } - return self.si(i); - }) + if (i <= 0 || i > self.N()) { // TODO check for bound + throw std::invalid_argument("SiteSet::si out of bounds"); + } + return self.si(i); + }) .def("siP", [](SiteSet const & self, int i) { - if (i <= 0 || i > self.N()) { // TODO check for bound - throw ITError("SiteSet::operator(i) out of bounds"); - } - return self.siP(i); - }) + if (i <= 0 || i > self.N()) { // TODO check for bound + throw std::invalid_argument("SiteSet::siP out of bounds"); + } + return self.siP(i); + }) .def("st", [](SiteSet const & self, int i, String const & state) { - if (i <= 0 || i > self.N()) { // TODO check for bound - throw ITError("SiteSet::operator(i) out of bounds"); - } - return self.st(i, state); - }) + if (i <= 0 || i > self.N()) { // TODO check for bound + throw std::invalid_argument("SiteSet::st out of bounds"); + } + return self.st(i, state); + }) .def("stP", [](SiteSet const & self, int i, String const & state) { - if (i <= 0 || i > self.N()) { // TODO check for bound - throw ITError("SiteSet::operator(i) out of bounds"); - } - return self.stP(i, state); - }) + if (i <= 0 || i > self.N()) { // TODO check for bound + throw std::invalid_argument("SiteSet::stP out of bounds"); + } + return self.stP(i, state); + }) + // TODO read, write ; return type; From 7ff3d3bb1b819f01d356738ab87f18039f403990 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:26:20 -0400 Subject: [PATCH 29/41] Update sweeps.h.cc --- src/itensor/mps/sweeps.h.cc | 199 +++++++++++++++++++++++------------- 1 file changed, 130 insertions(+), 69 deletions(-) diff --git a/src/itensor/mps/sweeps.h.cc b/src/itensor/mps/sweeps.h.cc index db8c30c..47767aa 100644 --- a/src/itensor/mps/sweeps.h.cc +++ b/src/itensor/mps/sweeps.h.cc @@ -18,10 +18,6 @@ initSweeps(pybind11::module& module) py::arg("cutoff")=1E-8); type.def(py::init()); // TODO: InputGroup - // std::vector maxm_, minm_, niter_; - // std::vector cutoff_, noise_; - // int nsweep_; - type .def_property("nsweep", (int (Sweeps::*)() const) &Sweeps::nsweep, @@ -30,78 +26,143 @@ initSweeps(pybind11::module& module) .def_property("minm", [](Sweeps const & self) -> std::vector { std::vector res; - // TODO: check 0-based or 1-based. for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { - res.push_back(self.minm(i)); + res.push_back(self.minm(i+1)); // 1-based. } return res; }, - [](Sweeps & self, std::vector const & minm) { - int curMinM = 1; - for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { - if (i < minm.size()) { curMinM = minm[i]; } - if (curMinM > 0) { self.setminm(i, curMinM); } - // TODO: document : set only positive + [](Sweeps & self, py::object obj) { // Overloading (list vs single Real) + if (py::isinstance(obj)) { + py::list lst(obj); + int v = 1; + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + if (i < py::len(lst)) { + v = lst[i].cast(); + } + self.setminm(i+1, v); + } + } else if (py::isinstance(obj)) { + int v = obj.cast(); + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + self.setminm(i+1, v); + } + } else { + throw std::domain_error("Unsupported type"); } - } - ) - .def("setminm", // TODO bound check - (int (Sweeps::*)(int, int)) &Sweeps::setminm) + }) .def_property("maxm", - [](Sweeps const & self) -> std::vector { - std::vector res; - // TODO: check 0-based or 1-based. - for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { - res.push_back(self.maxm(i)); - } - return res; - }, - [](Sweeps & self, std::vector const & maxm) { - int curMaxM = 1; - for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { - if (i < maxm.size()) { curMaxM = maxm[i]; } - if (curMaxM > 0) { self.setmaxm(i, curMaxM); } - // TODO: document : set only positive - } - } - ) - .def("setmaxm", // TODO bound check - (int (Sweeps::*)(int, int)) &Sweeps::setmaxm) - // TODO: bound check - .def("__repr__", [](Sweeps const & obj) { std::stringstream ss; ss << obj; return ss.str(); }) + [](Sweeps const & self) -> std::vector { + std::vector res; + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + res.push_back(self.maxm(i+1)); + } + return res; + }, + [](Sweeps & self, py::object obj) { // Overloading (list vs single Real) + if (py::isinstance(obj)) { + py::list lst(obj); + int v = 1; + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + if (i < py::len(lst)) { v = lst[i].cast(); } + self.setmaxm(i+1, v); + } + } else if (py::isinstance(obj)) { + int v = obj.cast(); + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + self.setmaxm(i+1, v); + } + } else { + throw std::domain_error("Unsupported type"); + } + }) + .def_property("niter", + [](Sweeps const & self) -> std::vector { + std::vector res; + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + res.push_back(self.niter(i+1)); + } + return res; + }, + [](Sweeps & self, py::object obj) { // Overloading (list vs single int) + if (py::isinstance(obj)) { + py::list lst(obj); + int v = 1; + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + if (i < py::len(lst)) { v = lst[i].cast(); } + self.setniter(i+1, v); + } + } else if (py::isinstance(obj)) { + int v = obj.cast(); + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + self.setniter(i+1, v); + } + } else { + throw std::domain_error("Unsupported type"); + } + }) .def_property("cutoff", - [](Sweeps const & self) -> std::vector { - std::vector res; - for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { - res.push_back(self.cutoff(i)); - } - return res; - }, - [](Sweeps & self, py::object obj) { // Overloading (list vs single Real) - if (py::isinstance(obj)) { - if (py::list(obj).size() != self.nsweep()) { - throw std::length_error("Length of the list does not match the number of sweeps"); - } - int i = 0; - for (auto const & item : py::list(obj)) { - Real r = item.cast(); // this does type check - self.setcutoff(i, r); - ++i; - } - } else if (py::isinstance(obj)) { - Real v = obj.cast(); - for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { - self.setcutoff(i, v); - } - } else { - throw std::domain_error("Unsupported type"); - } - } - ) - // TODO noise (peculiar behavior with single argument) - // TODO niter (peculiar behavior with single argument) - // TODO read - // TODO write + [](Sweeps const & self) -> std::vector { + std::vector res; + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + res.push_back(self.cutoff(i+1)); + } + return res; + }, + [](Sweeps & self, py::object obj) { // Overloading (list vs single Real) + if (py::isinstance(obj)) { + py::list lst(obj); + Real v = 0; + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + if (i < py::len(lst)) { v = lst[i].cast(); } + self.setcutoff(i+1, v); + } + } else if (py::isinstance(obj)) { + int v = obj.cast(); + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + self.setcutoff(i+1, v); + } + } else { + throw std::domain_error("Unsupported type"); + } + }) + .def_property("noise", + [](Sweeps const & self) -> std::vector { + std::vector res; + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + res.push_back(self.noise(i+1)); + } + return res; + }, + [](Sweeps & self, py::object obj) { // Overloading (list vs single Real) + if (py::isinstance(obj)) { + py::list lst(obj); + Real v = 0; + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + if (i < py::len(lst)) { v = lst[i].cast(); } + self.setnoise(i+1, v); + } + } else if (py::isinstance(obj)) { + Real v = obj.cast(); + for (int i = 0, ns = self.nsweep() ; i < ns ; ++i) { + self.setnoise(i+1, v); + } + } else { + throw std::domain_error("Unsupported type"); + } + }) + .def("setminm", // Bound check done by std::vector::at + (void (Sweeps::*)(int, int)) &Sweeps::setminm) + .def("setmaxm", + (void (Sweeps::*)(int, int)) &Sweeps::setmaxm) + .def("setniter", + (void (Sweeps::*)(int, int)) &Sweeps::setniter) + .def("setcutoff", + (void (Sweeps::*)(int, Real)) &Sweeps::setcutoff) + .def("setnoise", + (void (Sweeps::*)(int, Real)) &Sweeps::setnoise) + .def("__repr__", [](Sweeps const & obj) { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) + .def("read", &Sweeps::read) + .def("write", &Sweeps::write) ; } From 1fe3d2dc546f8cbfc56f04e18db9602f6bf59210 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:26:28 -0400 Subject: [PATCH 30/41] Update spintwo.h.cc --- src/itensor/mps/sites/spintwo.h.cc | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/itensor/mps/sites/spintwo.h.cc b/src/itensor/mps/sites/spintwo.h.cc index b8ed04f..51aaea5 100644 --- a/src/itensor/mps/sites/spintwo.h.cc +++ b/src/itensor/mps/sites/spintwo.h.cc @@ -6,6 +6,25 @@ namespace py = pybind11; using namespace itensor; +static inline +auto +initSpinTwo(pybind11::module& module) +{ + using Type = SpinTwo; + py::class_ type(module, "SpinTwo"); + + type.def(py::init<>()); + type.def(py::init(), + py::arg("N"), + py::arg("args")=Args::global()); + + // TODO: how should I treat istream? + type + .def("read", &Type::read) + ; + return type; +} + static inline auto initSpinTwoSite(pybind11::module& module) @@ -29,6 +48,6 @@ initSpinTwoSite(pybind11::module& module) void pitensor::mps::sites::spintwo(pybind11::module& module) { - py::class_ typeSpinTwo(module, "SpinTwo"); + auto typeSpinTwo = initSpinTwo(module); auto typeSpinTwoSite = initSpinTwoSite(module); } From 3ea5440ab71e456c0e9e5b52320de55264ebe42d Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:26:36 -0400 Subject: [PATCH 31/41] Update args.h.cc --- src/itensor/util/args.h.cc | 96 +++++++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 16 deletions(-) diff --git a/src/itensor/util/args.h.cc b/src/itensor/util/args.h.cc index 18797a8..2eed24f 100644 --- a/src/itensor/util/args.h.cc +++ b/src/itensor/util/args.h.cc @@ -5,54 +5,118 @@ namespace py = pybind11; using namespace itensor; -// TODO: Implement python version altogether? +// TODO: Implement python version altogether! + +#if 1 +class PyArgs : public Args +{ + public: + + PyArgs() : Args() {} + PyArgs(Args const & args) : Args(args) { } + PyArgs(Args && args) : Args(std::forward(args)) { } + + operator Args const &() const { return *this; } + operator Args () const { return *this; } + + PyArgs(py::dict kwargs) : Args() { + for (auto const & kv : kwargs) { + auto key = kv.first.cast(); + auto val = kv.second; + if (py::isinstance(val)) { + add(key, val.cast()); + } else if (py::isinstance(val)) { + add(key, val.cast()); + } else if (py::isinstance(val)) { + add(key, val.cast()); + } else if (py::isinstance(val)) { + add(key, val.cast()); + } else { + throw std::invalid_argument("unsupported argument type"); + } + } + } +}; +#endif static inline auto initArgs(pybind11::module& module) { - py::class_ type(module, "Args"); + //using PyArgs = Args; + py::class_ foo(module, "_Args"); + foo + .def(py::init([](const PyArgs& args) { + return new Args(args); + })) + ; + py::class_ type(module, "Args"); + using namespace pybind11::literals; + type .def(py::init<>()) + .def(py::init()) +#if 1 .def(py::init( [](py::kwargs kwargs) { - auto self = new Args(); + auto self = new PyArgs(); for (auto const & kv : kwargs) { auto key = kv.first.cast(); auto val = kv.second; - auto typestr = py::str(val.get_type()).cast(); - if (typestr == "") { + if (py::isinstance(val)) { self->add(key, val.cast()); - } else if (typestr == "") { + } else if (py::isinstance(val)) { self->add(key, val.cast()); - } else if (typestr == "") { + } else if (py::isinstance(val)) { self->add(key, val.cast()); - } else if (typestr == "") { + } else if (py::isinstance(val)) { self->add(key, val.cast()); - } // TODO: Find better way. + } else { + throw std::invalid_argument("unsupported argument type"); + } } return self; }) ) +#endif .def("add", - (void (Args::*)(std::string const &, bool)) &Args::add) + (void (PyArgs::*)(std::string const &, bool)) &PyArgs::add) .def("add", - (void (Args::*)(std::string const &, long)) &Args::add) + (void (PyArgs::*)(std::string const &, long)) &PyArgs::add) .def("add", - (void (Args::*)(std::string const &, std::string const &)) &Args::add) + (void (PyArgs::*)(std::string const &, std::string const &)) &PyArgs::add) .def("add", - (void (Args::*)(std::string const &, Real)) &Args::add) - .def("defined", &Args::defined) - .def("remove", &Args::remove) + (void (PyArgs::*)(std::string const &, Real)) &PyArgs::add) + .def("defined", &PyArgs::defined) + .def("remove", &PyArgs::remove) // TODO: getBool // TODO: getString // TODO: getInt // TODO: getReal + ; + type .def("__repr__", - [](Args const & obj) -> std::string { std::stringstream ss; ss << obj; return ss.str(); }) + [](PyArgs const & obj) -> std::string { std::stringstream ss; ss << std::scientific << obj; return ss.str(); }) + .def("__setitem__", + (void (PyArgs::*)(std::string const &, bool)) &PyArgs::add) + .def("__setitem__", + (void (PyArgs::*)(std::string const &, long)) &PyArgs::add) + .def("__setitem__", + (void (PyArgs::*)(std::string const &, std::string const &)) &PyArgs::add) + .def("__setitem__", + (void (PyArgs::*)(std::string const &, Real)) &PyArgs::add) + ; + + type .def(py::self + py::self) ; + + // TODO: test if this works + // https://github.com/pybind/pybind11/blob/086d53e8c66a84d0ec723d5435918c76edd878e8/tests/test_smart_ptr.cpp#L79 + py::implicitly_convertible(); + py::implicitly_convertible(); + return type; } From 5d25658039c45da0d773a0953c2ade9630a8ee0c Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:26:55 -0400 Subject: [PATCH 32/41] Update pitensor.h (pythonbuf WIP) --- src/pitensor.h | 83 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/src/pitensor.h b/src/pitensor.h index f5e396d..710f139 100644 --- a/src/pitensor.h +++ b/src/pitensor.h @@ -30,8 +30,89 @@ void recursiveConstructor(T & type) { type.def(pybind11::init()); } +#if 0 // First Test Recursive Call +template +struct RecursiveDefinition +{ + template + RecursiveDefinition(T & type, const char* funcName, FuncType &&f) + { + type.def(funcName, pybind11::overload_cast(f)); + } +}; + +template +struct RecursiveDefinition +{ + template + RecursiveDefinition(T & type, const char* funcName, FuncType &&f) + : RecursiveDefinition(T, funcName, f) + { + type.def(funcName, pybind11::overload_cast(f)); + } +}; +#endif + +template +void recursiveMember(T & type, const char* funcName, FuncType && f) +{ + type.def(funcName, pybind11::overload_cast(f)); +} + +template +void recursiveMember(T & type, const char* funcName, FuncType && f) +{ + type.def(funcName, pybind11::overload_cast(f)); + recursiveMember(type, funcName, f); +} + + +class pythonbytebuf : public std::streambuf { + private: + using traits_type = std::streambuf::traits_type; + + char d_buffer[1024]; + pybind11::object pywrite; + pybind11::object pyflush; + + int overflow(int c) { + if (!traits_type::eq_int_type(c, traits_type::eof())) { + *pptr() = traits_type::to_char_type(c); + pbump(1); + } + return sync() ? traits_type::not_eof(c) : traits_type::eof(); + } + + int sync() { + if (pbase() != pptr()) { + pybind11::bytes line(pbase(), static_cast(pptr() - pbase())); + pywrite(line); + pyflush(); + setp(pbase(), epptr()); + } + return 0; + } + public: + pythonbytebuf(pybind11::object pyostream) + : pywrite(pyostream.attr("write")) + , pyflush(pyostream.attr("flush")) { + if (!pyostream.attr("writable")().cast()) { + throw std::invalid_argument("input stream should be writeable"); + } + if (!pybind11::isinstance(pyostream, pybind11::module::import("io").attr("BufferedIOBase"))) { + throw std::invalid_argument("input stream should be binary-writeable"); + } -#if 1 + setp(d_buffer, d_buffer + sizeof(d_buffer) - 1); + } + + ~pythonbytebuf() { + sync(); + } +}; + + +#if 0 template Date: Mon, 9 Apr 2018 23:27:09 -0400 Subject: [PATCH 33/41] Update test_itensor.py --- tests/test_itensor.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/test_itensor.py b/tests/test_itensor.py index 7d8216a..a4d89e8 100644 --- a/tests/test_itensor.py +++ b/tests/test_itensor.py @@ -4,14 +4,8 @@ class PiTensorTest_ITensor(unittest.TestCase): def test(self): - self.testIndex() self.testITensor() - def testIndex(self): - i = pitensor.Index("I", 3) - s = str(i) - self.assertTrue(s.startswith('(I,3')) - def testITensor(self): i = pitensor.Index("I", 3) j = pitensor.Index("J", 4) @@ -25,5 +19,10 @@ def testITensor(self): self.assertTrue(math.isclose(pitensor.norm(T), math.sqrt(12.0), rel_tol=1E-6)) self.assertTrue(math.isclose(pitensor.norm(S), math.sqrt(12.0), rel_tol=1E-6)) + + j2 = pitensor.findindex(T, lambda x: x.name == 'J') + self.assertEqual(j, j2) + + if __name__=='__main__': unittest.main() From c5d936d3966151ae8b8087defe3693fa472312dc Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:27:53 -0400 Subject: [PATCH 34/41] Added test_index.py --- tests/test_index.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/test_index.py diff --git a/tests/test_index.py b/tests/test_index.py new file mode 100644 index 0000000..a5f00f2 --- /dev/null +++ b/tests/test_index.py @@ -0,0 +1,19 @@ +import unittest +import pitensor +import math + +class PiTensorTest_Index(unittest.TestCase): + def test(self): + self.testIndex() + self.testIQIndex() + + def testIndex(self): + i = pitensor.Index("I", 3) + s = str(i) + self.assertTrue(s.startswith('(I,3')) + + def testIQIndex(self): + pass + +if __name__=='__main__': + unittest.main() From 7009adcad31e7073d451c07c96f3d5eee8c503f3 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:28:16 -0400 Subject: [PATCH 35/41] Added examples (translated from ITensor) --- example/dmrg.py | 27 ++++++++++++ example/dmrg_table.py | 48 +++++++++++++++++++++ example/exthubbard.py | 70 +++++++++++++++++++++++++++++++ example/inputfile_dmrg_table.json | 11 +++++ example/inputfile_exthubbard.json | 16 +++++++ 5 files changed, 172 insertions(+) create mode 100644 example/dmrg.py create mode 100644 example/dmrg_table.py create mode 100644 example/exthubbard.py create mode 100644 example/inputfile_dmrg_table.json create mode 100644 example/inputfile_exthubbard.json diff --git a/example/dmrg.py b/example/dmrg.py new file mode 100644 index 0000000..5413b6b --- /dev/null +++ b/example/dmrg.py @@ -0,0 +1,27 @@ +import numpy as np +import pitensor + +def main(): + N = 100 + sites = pitensor.SpinOne(N) + psi = pitensor.MPS(sites) + ampo = pitensor.AutoMPO(sites) + for j in range(1, N): + # Testing all three patterns of term addition to AutoMPO + ampo += ("Sz", j, "Sz", j+1) + ampo += (0.5, "S+", j, "S-", j+1) + hm = pitensor.HTerm(0.5, [pitensor.SiteTerm("S-", j), pitensor.SiteTerm("S+", j+1)]) + ampo.add(hm) + + H = pitensor.toMPO(ampo) + + sweeps = pitensor.Sweeps(5); + sweeps.maxm = [10, 40, 100, 200, 200] + sweeps.cutoff = 1E-8 + + #energy = pitensor.dmrg(psi, H, sweeps, pitensor.Args(Quiet=True)) + energy = pitensor.dmrg(psi, H, sweeps, pitensor.Args({'Quiet': True})) + print("Ground state energy per site = {:.18f}".format(energy / N)) + +if __name__=='__main__': + main() diff --git a/example/dmrg_table.py b/example/dmrg_table.py new file mode 100644 index 0000000..598cc14 --- /dev/null +++ b/example/dmrg_table.py @@ -0,0 +1,48 @@ +import argparse +import json +import numpy as np +import pitensor + +def main(): + parser = argparse.ArgumentParser("dmrg_table") + parser.add_argument("inputjsonfile", type=argparse.FileType('r')) + args = parser.parse_args() + + inputjson = json.load(args.inputjsonfile) + N = inputjson['N'] + + sweepjson = inputjson['sweeps'] + sweeps = pitensor.Sweeps(len(sweepjson)) + sweeps.maxm = [s['maxm'] for s in sweepjson] + sweeps.minm = [s['minm'] for s in sweepjson] + sweeps.cutoff = [s['cutoff'] for s in sweepjson] + sweeps.niter = [s['niter'] for s in sweepjson] + sweeps.noise = [s['noise'] for s in sweepjson] + + quiet = inputjson['quiet'] + + print(sweeps) + + sites = pitensor.SpinOne(N) + ampo = pitensor.AutoMPO(sites) + for j in range(1, N): + ampo += (0.5, "S+", j, "S-", j+1) + ampo += (0.5, "S-", j, "S+", j+1) + ampo += ("Sz", j, "Sz", j+1) + + H = ampo.toMPO() + + state = pitensor.InitState(sites) + + for i in range(1, N): + state.set(i, "Up" if i % 2 == 1 else "Dn") + psi = pitensor.MPS(state) + print("Initial energy = {}".format(pitensor.overlap(psi, H, psi))) + + energy = pitensor.dmrg(psi, H, sweeps, pitensor.Args(Quiet=quiet)) + + print("Ground State energy = {}".format(energy)) + + +if __name__=='__main__': + main() \ No newline at end of file diff --git a/example/exthubbard.py b/example/exthubbard.py new file mode 100644 index 0000000..96de540 --- /dev/null +++ b/example/exthubbard.py @@ -0,0 +1,70 @@ +import argparse +import json +import pitensor + +def main(): + parser = argparse.ArgumentParser("exthubbard") + parser.add_argument("inputjsonfile", type=argparse.FileType('r')) + args = parser.parse_args() + + inputjson = json.load(args.inputjsonfile) + + N = inputjson['N'] + Npart = inputjson['Npart'] + sweepjson = inputjson['sweeps'] + sweeps = pitensor.Sweeps(len(sweepjson)) + sweeps.maxm = [s['maxm'] for s in sweepjson] + sweeps.minm = [s['minm'] for s in sweepjson] + sweeps.cutoff = [s['cutoff'] for s in sweepjson] + sweeps.niter = [s['niter'] for s in sweepjson] + sweeps.noise = [s['noise'] for s in sweepjson] + + t1 = inputjson['t1'] + t2 = inputjson['t2'] + U = inputjson['U'] + V1 = inputjson['V1'] + quiet = inputjson['quiet'] + + print(sweeps) + + sites = pitensor.Hubbard(N) + ampo = pitensor.AutoMPO(sites) + for i in range(1, N+1): + ampo += (U, "Nupdn", i) + for i in range(1, N): + ampo += (-t1, "Cdagup", i, "Cup", i+1) + ampo += (-t1, "Cdagup", i+1, "Cup", i) + ampo += (-t1, "Cdagdn", i, "Cdn", i+1) + ampo += (-t1, "Cdagdn", i+1, "Cdn", i) + ampo += (V1, "Ntot", i, "Ntot", i+1) + for i in range(1, N-1): + ampo += (-t2, "Cdagup", i, "Cup", i+1) + ampo += (-t2, "Cdagup", i+2, "Cup", i) + H = ampo.toIQMPO() + + state = pitensor.InitState(sites) + p = Npart + for i in range(N, 0, -1): + if p > i: + print("Doubly occupying site {}".format(i)) + state.set(i, "UpDn") + p -= 2 + elif p > 0: + print("Singly occupying site ".format(i)) + state.set(i, "Up" if i % 2 == 1 else "Dn") + p -= 1 + else: + state.set(i, "Emp") + + psi = pitensor.IQMPS(state) + print("Total QN = {}".format(pitensor.totalQN(psi))) + + energy = pitensor.dmrg(psi, H, sweeps, pitensor.Args(Quiet=quiet)) + + print("Ground State energy = {}".format(energy)) + + + + +if __name__=='__main__': + main() \ No newline at end of file diff --git a/example/inputfile_dmrg_table.json b/example/inputfile_dmrg_table.json new file mode 100644 index 0000000..85e23f8 --- /dev/null +++ b/example/inputfile_dmrg_table.json @@ -0,0 +1,11 @@ +{ + "N": 100, + "sweeps": [ + {"maxm": 50, "minm": 20, "cutoff": 1E-6, "niter": 4, "noise": 1E-7}, + {"maxm": 50, "minm": 20, "cutoff": 1E-6, "niter": 4, "noise": 1E-7}, + {"maxm": 50, "minm": 20, "cutoff": 1E-6, "niter": 4, "noise": 1E-7}, + {"maxm": 50, "minm": 20, "cutoff": 1E-6, "niter": 4, "noise": 1E-7}, + {"maxm": 50, "minm": 20, "cutoff": 1E-6, "niter": 4, "noise": 1E-7} + ], + "quiet": false +} \ No newline at end of file diff --git a/example/inputfile_exthubbard.json b/example/inputfile_exthubbard.json new file mode 100644 index 0000000..70613d4 --- /dev/null +++ b/example/inputfile_exthubbard.json @@ -0,0 +1,16 @@ +{ + "N": 100, + "Npart": 10, + "t1": 1.0, + "t2": 0.2, + "U" : 1.0, + "V1": 0.5, + "sweeps": [ + {"maxm": 50, "minm": 10, "cutoff": 1E-12, "niter": 2, "noise": 1E-7}, + {"maxm": 100, "minm": 20, "cutoff": 1E-12, "niter": 2, "noise": 1E-8}, + {"maxm": 200, "minm": 20, "cutoff": 1E-12, "niter": 2, "noise": 1E-10}, + {"maxm": 400, "minm": 20, "cutoff": 1E-12, "niter": 2, "noise": 0}, + {"maxm": 800, "minm": 20, "cutoff": 1E-12, "niter": 2, "noise": 0} + ], + "quiet": true +} \ No newline at end of file From 8b23858185248fe13cd5c519dcb3a8783aff6123 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 9 Apr 2018 23:30:33 -0400 Subject: [PATCH 36/41] Added dist and egg-info to gitignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5c05802..b712784 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,6 @@ cmake-build-*/ .idea repo build/ -lab/ \ No newline at end of file +lab/ +dist/ +*.egg-info/* From 8294ac8cdd0f8eea08eba402e1a1f26b82187e70 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Tue, 10 Apr 2018 00:00:30 -0400 Subject: [PATCH 37/41] Update itensor_interface.h.cc: added missing initializations --- src/itensor/itensor_interface.h.cc | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/itensor/itensor_interface.h.cc b/src/itensor/itensor_interface.h.cc index a90f7f7..a468b83 100644 --- a/src/itensor/itensor_interface.h.cc +++ b/src/itensor/itensor_interface.h.cc @@ -32,7 +32,10 @@ struct InitializerITensorT { : module (theModule), name(theName), type(module, name) { initConstructor(); initOperator(); + initMethod(); initRealCplx(); + initPrime(); + initFunction(); } void initConstructor() { @@ -1012,10 +1015,7 @@ struct InitializerITensorT { (Cplx(*)(itensor_type const &)) &sumelsC) // TODO multiSiteOps ; - - return type; - } // initITensorT(pybind11::module& module, const char* name) - + } }; @@ -1028,14 +1028,11 @@ void pitensor::itensor_interface(pybind11::module& module) auto typeITensor = initITensor.type; auto typeIQTensor = initIQTensor.type; - //auto typeITensor = InitializerinitITensorT(module, "ITensor"); - //auto typeIQTensor = initITensorT(module, "IQTensor"); - typeITensor .def(py::self *= IndexVal()) .def(py::self * IndexVal()) .def(IndexVal() * py::self) - ; + ; module .def("combiner", @@ -1123,12 +1120,9 @@ void pitensor::itensor_interface(pybind11::module& module) // .def('__imul__', ) ; - - //initDiagTensor<>(module); initDiagTensor >(module); initDiagTensor >(module); - // TODO operator IndexVal * IndexVal // TODO IndexVal * Cplx From fbd924b8849ad08338ebbe6944e4ba76d7388b0f Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 23 Apr 2018 23:14:42 -0400 Subject: [PATCH 38/41] Update itensor_interface.h.cc: formatting --- src/itensor/itensor_interface.h.cc | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/itensor/itensor_interface.h.cc b/src/itensor/itensor_interface.h.cc index a468b83..476a59d 100644 --- a/src/itensor/itensor_interface.h.cc +++ b/src/itensor/itensor_interface.h.cc @@ -299,7 +299,6 @@ struct InitializerITensorT { ; // Using IndexType - type .def("fill", &itensor_type::fill) /* @@ -396,13 +395,12 @@ struct InitializerITensorT { return self; }) .def("mapprime", - (itensor_type &(itensor_type::*)(int, - int, - IndexType)) &itensor_type::mapprime, + (itensor_type &(itensor_type::*)(int, int, IndexType)) &itensor_type::mapprime, py::arg("plevold"), py::arg("plevnew"), - py::arg("type") = All - ); + py::arg("type")=All + ) + ; #if 0 type @@ -954,7 +952,7 @@ struct InitializerITensorT { py::arg("A"), py::arg("plevold"), py::arg("plevnew"), - py::arg("type") = All + py::arg("type")=All ) // TODO: mapprime with variadic blah // TODO: sim @@ -970,7 +968,7 @@ struct InitializerITensorT { (index_type (*)(itensor_type const &, itensor_type const &, IndexType)) &commonIndex, py::arg("A"), py::arg("B"), - py::arg("t") = All) + py::arg("t")=All) .def("uniqueIndex", (index_type (*)(itensor_type const &, itensor_type const &, IndexType)) &uniqueIndex, py::arg("A"), @@ -981,7 +979,7 @@ struct InitializerITensorT { py::arg("T"), py::arg("plev1"), py::arg("plev2"), - py::arg("type") = All) + py::arg("type")=All) // TODO: apply .def("realPart", (itensor_type (*)(itensor_type)) &realPart) @@ -1000,7 +998,7 @@ struct InitializerITensorT { .def("randomize", (void (*)(itensor_type &, Args const &)) &randomize, py::arg("T"), - py::arg("args") = Args::global()) + py::arg("args")=Args::global()) .def("random", (itensor_type (*)(itensor_type, Args const &)) &random, py::arg("T"), @@ -1195,5 +1193,6 @@ void static initDiagTensor(pybind11::module& module) { Index const &, Index const &, Index const &, - Index const &)) &diagTensor); + Index const &)) &diagTensor) + ; } From 2c3d685c2a519ce08cdf3c2cdf948fea697188a8 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 23 Apr 2018 23:15:45 -0400 Subject: [PATCH 39/41] Update itensor_interface.h.cc: Structure change (WIP) --- src/itensor/itensor_interface.h.cc | 177 +++++++++++++++++++++++++---- 1 file changed, 156 insertions(+), 21 deletions(-) diff --git a/src/itensor/itensor_interface.h.cc b/src/itensor/itensor_interface.h.cc index 476a59d..43840c9 100644 --- a/src/itensor/itensor_interface.h.cc +++ b/src/itensor/itensor_interface.h.cc @@ -6,10 +6,11 @@ namespace py = pybind11; using namespace itensor; +#if 0 template void static inline initDiagTensor(pybind11::module& module); - +#endif template void static inline @@ -36,9 +37,11 @@ struct InitializerITensorT { initRealCplx(); initPrime(); initFunction(); + initSpecialization(); } void initConstructor() { +#if 0 pitensor::recursiveConstructor< py::class_, index_type const &, @@ -52,8 +55,16 @@ struct InitializerITensorT { index_type const &, index_type const & >(type); // includes default constructor - +#endif type + .def(py::init([](py::args args) { + for (auto const & arg : args) { + if (!py::isinstance(arg)) { throw std::domain_error("Argument type should be of index_type"); } + } + std::vector v_args; v_args.reserve(py::len(args)); + for (auto const & arg : args) { v_args.push_back(arg.cast()); } + return new itensor_type(std::move(v_args)); + })) .def(py::init const &>()) // don't need std::array or initializer list .def(py::init()) @@ -214,13 +225,14 @@ struct InitializerITensorT { void initMethod() { type - .def("set", - (void (itensor_type::*)(Cplx)) &itensor_type::set - ) .def("set", (void (itensor_type::*)(std::vector const &, Cplx)) &itensor_type::set ) + .def("set", + (void (itensor_type::*)(Cplx)) &itensor_type::set + ) +#if 1 .def("set", (void (itensor_type::*)(indexval_type const &, Cplx const &)) &itensor_type::set) @@ -296,6 +308,7 @@ struct InitializerITensorT { indexval_type const &, indexval_type const &, Cplx const &)) &itensor_type::set) +#endif ; // Using IndexType @@ -914,9 +927,6 @@ struct InitializerITensorT { } - - - void initFunction() { module @@ -1014,24 +1024,79 @@ struct InitializerITensorT { // TODO multiSiteOps ; } + + void initSpecialization(); }; +void static +initDiagTensor(pybind11::module& module) { + module + .def("diagTensor", + [](std::vector const & values, + std::vector const & indices) -> ITensor { + if (values.size() < indices.size()) { throw std::domain_error("Small number of values"); } + auto is = IndexSet(indices); + return ITensor(std::move(is),Diag(values.begin(),values.end())); + }) + .def("diagTensor", + [](std::vector const & values, + std::vector const & indices) -> ITensor { + if (values.size() < indices.size()) { throw std::domain_error("Small number of values"); } + auto is = IndexSet(indices); + return ITensor(std::move(is),Diag(values.begin(),values.end())); + }) + ; +} -void pitensor::itensor_interface(pybind11::module& module) +template<> +void +InitializerITensorT::initSpecialization() { - auto initITensor = InitializerITensorT(module, "ITensor"); - auto initIQTensor = InitializerITensorT(module, "IQTensor"); - - auto typeITensor = initITensor.type; - auto typeIQTensor = initIQTensor.type; - - typeITensor + type .def(py::self *= IndexVal()) .def(py::self * IndexVal()) .def(IndexVal() * py::self) + .def(py::self *= IQIndexVal()) + .def(py::self * IQIndexVal()) + .def(IQIndexVal() * py::self) + ; + + module + .def("combiner", + [](Index const &i1, py::args args) -> ITensor { + for (auto const & arg : args) { + if (!py::isinstance(arg)) { throw std::domain_error("Arguments should be of Index type"); } + } + std::vector indices; + indices.reserve(1+py::len(args)); + indices.push_back(i1); + for (auto const & arg : args) { + indices.push_back(arg.cast()); + } + return combiner(std::move(indices)); + }) + .def("delta", + [](Index const &i1, py::args args) -> ITensor { + for (auto const & arg : args) { + if (!py::isinstance(arg)) { throw std::domain_error("Arguments should be of Index type"); } + } + std::vector indices; + indices.reserve(1+py::len(args)); + indices.push_back(i1); + for (auto const & arg : args) { + indices.push_back(arg.cast()); + } + IndexSet indexset(std::move(indices)); + auto len = minM(indexset); + return ITensor(std::move(indexset),DiagReal(len,1.)); + }) + .def("combinedIndex", + (Index (*)(ITensor const &)) &combinedIndex) ; + +#if 0 module .def("combiner", (ITensor (*)(Index const &)) &combiner) @@ -1074,8 +1139,7 @@ void pitensor::itensor_interface(pybind11::module& module) Index const &, Index const &, Index const &)) &combiner) - .def("combinedIndex", - (Index (*)(ITensor const &)) &combinedIndex) + .def("delta", (ITensor (*)(Index const &)) &delta) .def("delta", @@ -1111,15 +1175,83 @@ void pitensor::itensor_interface(pybind11::module& module) Index const &, Index const &, Index const &)) &delta) - ; + ; +#endif +} + +template <> +void InitializerITensorT::initSpecialization() +{ + type + .def(py::self *= IQIndexVal()) + .def(py::self * IQIndexVal()) + .def(IQIndexVal() * py::self) + .def(IndexVal() * py::self) //TODO Check Type + .def(py::self += ITensor()) + .def(py::self + ITensor()) + .def(py::self * ITensor()) + .def(ITensor() * py::self) + .def(py::self * IndexVal()) + .def(IndexVal() * py::self) + ; + + module + .def("toITensor", (ITensor (*)(IQTensor const &))&toITensor) + .def("div", (QN (*)(IQTensor const &)) &div) + .def("combiner", + [](IQIndex const &i1, py::args args) -> IQTensor { + for (auto const & arg : args) { + if (!py::isinstance(arg)) { throw std::domain_error("Arguments should be of IQIndex type"); } + } + std::vector indices; + indices.reserve(1+py::len(args)); + indices.push_back(i1); + for (auto const & arg : args) { + indices.push_back(arg.cast()); + } + return combiner(std::move(indices)); + }) + .def("delta", + [](IQIndex const &i1, py::args args) -> IQTensor { + for (auto const & arg : args) { + if (!py::isinstance(arg)) { throw std::domain_error("Arguments should be of IQIndex type"); } + } + std::vector indices; + indices.reserve(1+py::len(args)); + indices.push_back(i1); + for (auto const & arg : args) { indices.push_back(arg.cast()); } + auto indexset = IQIndexSet(std::move(indices)); + auto dat = QDiagReal(indexset, 1.0); + return IQTensor(std::move(indexset), std::move(dat)); + }) + // TODO findIQInd + // TODO qn + // TODO dir + // TODO randomTensor with IQIndVals + // TODO mixedIQTensor + // TODO typeNameOf + ; + + py::implicitly_convertible(); +} + +void pitensor::itensor_interface(pybind11::module& module) +{ + auto initITensor = InitializerITensorT(module, "ITensor"); + auto initIQTensor = InitializerITensorT(module, "IQTensor"); + + auto typeITensor = initITensor.type; + auto typeIQTensor = initIQTensor.type; typeIQTensor //TODO specialization for IQTensor // .def('__imul__', ) ; - initDiagTensor >(module); - initDiagTensor >(module); + //initDiagTensor >(module); + //initDiagTensor >(module); + + initDiagTensor(module); // TODO operator IndexVal * IndexVal // TODO IndexVal * Cplx @@ -1152,12 +1284,14 @@ void static inline initRandomTensor(pybind11::module& module) { module + // TODO: Pythonic randomTensor .def("randomTensor", (ITensorT (*)(IndexSetT const &)) &randomTensor) ; } +#if 0 template void static initDiagTensor(pybind11::module& module) { module @@ -1196,3 +1330,4 @@ void static initDiagTensor(pybind11::module& module) { Index const &)) &diagTensor) ; } +#endif From 08aefc7ad07210a379a694b683b0ebbb8042a1e5 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Mon, 7 May 2018 23:35:35 -0400 Subject: [PATCH 40/41] Update CMakeLists.txt: Change branch of ITensor Use `pitensor-2.1.1-1` branch of ITensor --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 173b230..298f1c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -302,7 +302,7 @@ ExternalProject_Add(ITensor_external BINARY_DIR "${PITENSOR_DEPENDENCY_DIR}/ITensor" INSTALL_DIR "${PITENSOR_DEPENDENCY_DIR}/ITensor" GIT_REPOSITORY https://github.com/kyungminlee/ITensor.git - GIT_TAG pitensor + GIT_TAG "pitensor-2.1.1-1" UPDATE_COMMAND "" PATCH_COMMAND "" CONFIGURE_COMMAND "${CMAKE_COMMAND}" -E copy From a8e5fb832b2b2990028bce228fdcbd10ca2e85a9 Mon Sep 17 00:00:00 2001 From: Kyungmin Lee Date: Sun, 10 Feb 2019 10:42:34 -0500 Subject: [PATCH 41/41] Update pybind11 --- .gitattributes | 7 +++++++ pybind11 | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6731ce2 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +* text=lf + +*.h text +*.hpp text +*.c text +*.cc text +*.cpp text diff --git a/pybind11 b/pybind11 index 2fb4e95..25abf7e 160000 --- a/pybind11 +++ b/pybind11 @@ -1 +1 @@ -Subproject commit 2fb4e9532e55ca12d05373f0a1b53f50cdf919d6 +Subproject commit 25abf7efba0b2990f5a6dfb0a31bc65c0f2f4d17