@@ -48,6 +48,20 @@ function Rimu.starting_address(h::BoseHubbardReal1D2C)
48
48
return BoseFS2C (starting_address (h. ha), starting_address (h. hb))
49
49
end
50
50
51
+ struct BoseHubbardReal1D2CColumn{
52
+ A,T,O<: BoseHubbardReal1D2C{T}
53
+ } <: Rimu.AbstractOperatorColumn{A,T,O}
54
+ address:: A
55
+ hamiltonian:: O
56
+ diagonal_element:: T
57
+ end
58
+
59
+ function Rimu. operator_column (h:: BoseHubbardReal1D2C , address:: BoseFS2C )
60
+ diagonal_element = Rimu. diagonal_element (h, address)
61
+ return BoseHubbardReal1D2CColumn (address, h, diagonal_element)
62
+ end
63
+
64
+
51
65
Rimu. LOStructure (:: Type{<:BoseHubbardReal1D2C{<:Real}} ) = IsHermitian ()
52
66
53
67
Base. getproperty (h:: BoseHubbardReal1D2C , s:: Symbol ) = getproperty (h, Val (s))
@@ -56,9 +70,17 @@ Base.getproperty(h::BoseHubbardReal1D2C, ::Val{:hb}) = getfield(h, :hb)
56
70
Base. getproperty (h:: BoseHubbardReal1D2C{<:Any,<:Any,<:Any,V} , :: Val{:v} ) where {V} = V
57
71
58
72
# number of excitations that can be made
59
- function Rimu. num_offdiagonals (:: BoseHubbardReal1D2C , address)
73
+ function Rimu. num_offdiagonals (c:: BoseHubbardReal1D2CColumn )
74
+ address = starting_address (c)
60
75
return 2 * (num_occupied_modes (address. bsa) + num_occupied_modes (address. bsb))
61
76
end
77
+ function Rimu. num_offdiagonals (h:: BoseHubbardReal1D2C )
78
+ address = starting_address (h)
79
+ num_particles_a = Rimu. num_particles (address. bsa)
80
+ num_particles_b = Rimu. num_particles (address. bsb)
81
+ return 2 * (min (num_particles_a, num_modes (h)) +
82
+ min (num_particles_b, num_modes (h)))
83
+ end
62
84
63
85
"""
64
86
bose_hubbard_2c_interaction(::BoseFS2C)
79
101
80
102
function Rimu. diagonal_element (ham:: BoseHubbardReal1D2C , address:: BoseFS2C )
81
103
return (
82
- diagonal_element (ham. ha, address. bsa) +
83
- diagonal_element (ham. hb, address. bsb) +
104
+ diagonal_element (ham. ha, address. bsa) + # still makes use of the old interface
105
+ diagonal_element (ham. hb, address. bsb) + # old interface
84
106
ham. v * bose_hubbard_2c_interaction (address)
85
107
)
86
108
end
87
-
88
- function Rimu. get_offdiagonal (ham:: BoseHubbardReal1D2C , address, chosen)
89
- nhops = num_offdiagonals (ham,address)
90
- nhops_a = 2 * num_occupied_modes (address. bsa)
91
- if chosen ≤ nhops_a
92
- naddress_from_bsa, onproduct = hopnextneighbour (address. bsa, chosen)
93
- elem = - ham. ha. t * onproduct
94
- return BoseFS2C (naddress_from_bsa,address. bsb), elem
95
- else
96
- chosen -= nhops_a
97
- naddress_from_bsb, onproduct = hopnextneighbour (address. bsb, chosen)
98
- elem = - ham. hb. t * onproduct
99
- return BoseFS2C (address. bsa,naddress_from_bsb), elem
100
- end
101
- # return new address and matrix element
102
- end
109
+ Rimu. diagonal_element (c:: BoseHubbardReal1D2CColumn ) = c. diagonal_element
110
+
111
+
112
+ # function Rimu.get_offdiagonal(ham::BoseHubbardReal1D2C, address, chosen)
113
+ # nhops = num_offdiagonals(ham,address)
114
+ # nhops_a = 2 * num_occupied_modes(address.bsa)
115
+ # if chosen ≤ nhops_a
116
+ # naddress_from_bsa, onproduct = hopnextneighbour(address.bsa, chosen)
117
+ # elem = - ham.ha.t * onproduct
118
+ # return BoseFS2C(naddress_from_bsa,address.bsb), elem
119
+ # else
120
+ # chosen -= nhops_a
121
+ # naddress_from_bsb, onproduct = hopnextneighbour(address.bsb, chosen)
122
+ # elem = -ham.hb.t * onproduct
123
+ # return BoseFS2C(address.bsa,naddress_from_bsb), elem
124
+ # end
125
+ # # return new address and matrix element
126
+ # end
103
127
104
128
struct OffdiagonalsBoseReal1D2C{
105
129
A<: BoseFS2C ,T,H<: TwoComponentHamiltonian{T}
@@ -110,9 +134,11 @@ struct OffdiagonalsBoseReal1D2C{
110
134
num_hops_a:: Int
111
135
end
112
136
113
- function Rimu. offdiagonals (h:: BoseHubbardReal1D2C , a:: BoseFS2C )
114
- hops_a = num_offdiagonals (h. ha, a. bsa)
115
- hops_b = num_offdiagonals (h. hb, a. bsb)
137
+ function Rimu. offdiagonals (c:: BoseHubbardReal1D2CColumn )
138
+ h = c. hamiltonian
139
+ a = c. address
140
+ hops_a = num_offdiagonals (h. ha, a. bsa) # old interface
141
+ hops_b = num_offdiagonals (h. hb, a. bsb) # old interface
116
142
length = hops_a + hops_b
117
143
118
144
return OffdiagonalsBoseReal1D2C (h, a, length, hops_a)
@@ -122,10 +148,12 @@ function Base.getindex(s::OffdiagonalsBoseReal1D2C{A,T}, i)::Tuple{A,T} where {A
122
148
@boundscheck 1 ≤ i ≤ s. length || throw (BoundsError (s, i))
123
149
if i ≤ s. num_hops_a
124
150
new_a, matrix_element = get_offdiagonal (s. hamiltonian. ha, s. address. bsa, i)
151
+ # old interface
125
152
new_add = A (new_a, s. address. bsb)
126
153
else
127
154
i -= s. num_hops_a
128
155
new_b, matrix_element = get_offdiagonal (s. hamiltonian. hb, s. address. bsb, i)
156
+ # old interface
129
157
new_add = A (s. address. bsa, new_b)
130
158
end
131
159
return new_add, matrix_element
0 commit comments