pyspin.cpp 5.32 KB
Newer Older
1
#include <boost/python.hpp>
2
#include "spin_system.h"
3
#include "ladder.h"
4
#include "hamiltonian_heisenberg.h"
5
6
#include "hamiltonian_kagome.h"
#include "hamiltonian_flower.h"
7
#include "heisenberg_nnn.h"
Hylke Donker's avatar
Hylke Donker committed
8
#include "hamiltonian_lieb_mattis.h"
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// psi0 = To apply time evolution
// dim = dimension of system (2^N)
// E = vector of eigenvalues
// v = vector of eigenvectors
// time = Calculate magnetization at this time
// psi_t = Wave function exp(iHt)|psi_0>
template <typename T> void time_evolution(T &spin_sys, psi &psi_0, double time, psi &psi_t) // Somehow this function has to be defined in this file
{
	if(!spin_sys.get_initialized())
		throw;
	if(spin_sys.eigenvectors.size() == 0 || spin_sys.eigenvalues.size() == 0)
		throw;


	// Calculate exp(iHT)|psi_0> = v exp(iEt) v^-1 |psi_0>
	// Hamiltonian is diagonal for: H = v E v^-1 

	int dim = spin_sys.dim;
	// Step 1) |psi'> = v^-1 |psi0>
	std::vector< std::complex<double> > psi_prime(dim);
	for(unsigned int i=0;i < dim;i++)
	{
	for(unsigned int j=0; j < dim;j++)
	{
		// v^-1 = (v*)^T = v^dagger
		// |psi>' = R^-1 P|psi> <==> rho' = R^-1 P |psi><psi> P R
		// Real matrix -> only transpose
		//psi_prime.at(i) += (~v[i*dim+j])*psi_0[j];
		psi_prime[i] += spin_sys.eigenvectors[i*dim+j] * psi_0.elements[j];
	}
	}

	// Step 2) |psi(t)> = v exp(iEt) |psi'>
	// = v exp(iEt) v^-1 P |psi>
	for(unsigned int i=0;i < dim;i++)
	{
	for(unsigned int j=0; j < dim;j++)
	{
		// psi_t.at(i) += v[j*dim+i] * cmplx<float>{(float)std::cos(E[j]*time), (float)std::sin(E[j]*time)} * psi_prime[j];
		psi_t.elements[i] += spin_sys.eigenvectors[j*dim+i] * std::complex<double>{std::cos(spin_sys.eigenvalues[j]*time), std::sin(spin_sys.eigenvalues[j]*time)} * psi_prime[j];
	}
	}

	psi_prime.clear();

}

57
58
59
using namespace boost::python;
BOOST_PYTHON_MODULE(pyspin)
{
60
61
	int (psi::*set1)(list) = &psi::set;
	int (psi::*set2)(tuple) = &psi::set;
62
63
	list (psi::*get1)() = &psi::get;
	std::complex<double> (psi::*get2)(unsigned int) = &psi::get;
64
65
66

	class_<psi>("psi", init<optional<int>>())
	.def("set_size", &psi::set_size)
67
	.def("get_size", &psi::get_size)
68
69
70
	.def("set", set1)
	.def("set", set2)
	.def("normalize", &psi::normalize)
71
72
	.def("get", get1)
	.def("get", get2)
73
74
	.def("set_subset", &psi::set_subset)
	;
75

76
77
78
79
80
	class_<hamiltonian>("hamiltonian")
	.def("get_eigenvalues", &hamiltonian::get_eigenvalues)
	.def("get_eigenvectors", &hamiltonian::get_eigenvectors)
	.def("groundstate", &hamiltonian::groundstate)
	.def("H", &hamiltonian::H)
81
82
	;

83
84
	class_<heisenberg_system, bases<hamiltonian>>("heisenberg_system",  init<int, optional<bool, double, double, double, double, double, double, double, double, double> >())
	.def("initialize", &heisenberg_system::initialize)
85
	.def("get_initialized", &heisenberg_system::get_initialized)
86
	;
87

88
	class_<heisenberg_system_subsp, bases<hamiltonian>>("heisenberg_system_subsp",  init<int, optional<bool, double, double, double, double> >())
89
	.def("initialize", &heisenberg_system_subsp::initialize)
90
	.def("get_initialized", &heisenberg_system_subsp::get_initialized)
91
92
93
	;


94
95
	class_<ladder_system, bases<hamiltonian>>("ladder", init<int, optional<double, double, double, double, int, bool> >())
	.def("initialize", &ladder_system::initialize)
96
	.def("get_initialized", &ladder_system::get_initialized)
97
98
	;

99
100
	class_<heisenberg_system_nnn_subsp, bases<hamiltonian>>("heisenberg_nnn",  init<int, optional<double, double, double, double, double, double> >())
	.def("initialize", &heisenberg_system_nnn_subsp::initialize)
101
	.def("get_initialized", &heisenberg_system_nnn_subsp::get_initialized)
102
103
	;

104
	class_<kagome_system, bases<hamiltonian>>("kagome_system",  init< optional<double, double, double, bool> >())
105
	.def("initialize", &kagome_system::initialize)
106
	.def("get_initialized", &kagome_system::get_initialized)
107
108
	;

109
110
	class_<kagome_system_subsp, bases<hamiltonian>>("kagome_system_subsp",  init< optional<double, double, double> >())
	.def("initialize", &kagome_system_subsp::initialize)
111
	.def("get_initialized", &kagome_system_subsp::get_initialized)
112
113
	;

114
	class_<flower_system, bases<hamiltonian>>("flower_system",  init< optional<double, double, double> >())
115
	.def("initialize", &flower_system::initialize)
116
	.def("get_initialized", &flower_system::get_initialized)
117
118
	;

Hylke Donker's avatar
Hylke Donker committed
119
120
121
122
123
	class_<lieb_mattis_system, bases<hamiltonian>>("lieb_mattis_system",  init<int, optional<double, double, double> >())
	.def("initialize", &lieb_mattis_system::initialize)
	.def("get_initialized", &lieb_mattis_system::get_initialized)
	;

124

125
	class_<heisenberg_local_field_system, bases<hamiltonian>>("heisenberg_local_field_system",  init<int, bpy::list, optional<bool, double, double, double> >())
126
	.def("initialize", &heisenberg_local_field_system::initialize)
127
	.def("get_initialized", &heisenberg_local_field_system::get_initialized)
128
129
	;

130
131
132
	def("site_magnetization", site_magnetization);
	def("correlation", correlation);
	def("total_magnetization", total_magnetization);
133
	def("time_evolution", time_evolution<heisenberg_system>);
134
	def("time_evolution", time_evolution<heisenberg_local_field_system>);
135
136
	def("time_evolution", time_evolution<heisenberg_system_subsp>);
	def("time_evolution", time_evolution<kagome_system_subsp>);
137
138
	def("time_evolution", time_evolution<kagome_system>);
	def("time_evolution", time_evolution<flower_system>);
Hylke Donker's avatar
Hylke Donker committed
139
	def("time_evolution", time_evolution<lieb_mattis_system>);
140
	def("time_evolution", time_evolution<heisenberg_system_nnn_subsp>);
141
	def("vneumann_projection", vneumann_projection);
142
143
}

144

145
146