Linopt
Linear optics circuit calculator
states.h
1 /* Copyright © 2018, 2019, Quantum Optical Technologies Laboratories
2  * <https://www.qotlabs.org/en/>
3  * Contributed by: Struchalin Gleb <struchalin.gleb@physics.msu.ru>
4  * Dyakonov Ivan <iv.dyakonov@physics.msu.ru>
5  *
6  * This file is part of Linopt.
7  *
8  * Linopt is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * Linopt is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with Linopt. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef STATES_H
23 #define STATES_H
24 
25 #include <vector>
26 #include <set>
27 #include <map>
28 #include <ostream>
29 #include <initializer_list>
30 #include <functional>
31 #include "types.h"
32 
33 namespace linopt
34 {
35 
36 class Fock;
37 class Basis;
38 class State;
39 
44 using FockAmpFunction = std::function<Complex(const Fock&)>;
45 
56 class Fock: private std::vector<int>
57 {
58  using Base = std::vector<int>;
59 
60 public:
62  using Vector = std::vector<int>; // In principle this can be different from Base
63  using Value = int;
64  using value_type = Value;
65  using Reference = Value&;
66  using reference = Reference;
67 
68  using Base::Base;
69  using Base::operator=;
70 
71  using Iterator = Base::iterator;
72  using ConstIterator = Base::const_iterator;
73  using ReverseIterator = Base::reverse_iterator;
74  using ConstReverseIterator = Base::const_reverse_iterator;
75 
76  using Base::begin;
77  using Base::end;
78  using Base::rbegin;
79  using Base::rend;
80  using Base::cbegin;
81  using Base::cend;
82  using Base::crbegin;
83  using Base::crend;
84 
85  using Base::front;
86  using Base::back;
87  using Base::operator[];
88 
90  using Base::empty;
92  int size() const { return static_cast<int>(Base::size()); }
93  using Base::resize;
94  using Base::assign;
95  void pushBack(Value n) { Base::push_back(n); }
96  void popBack() { Base::pop_back(); }
97  using Base::insert;
98  using Base::erase;
100  using Base::clear;
101 
103  Fock() = default;
105  Fock(const Vector &v): Base(v) {}
106  int total() const;
107  Real prodFact() const;
108  Fock operator*(const Fock &f) const;
109  Fock &operator*=(const Fock &f);
110  Fock operator+(const Fock &f) const;
111  Fock &operator+=(const Fock &f);
112 };
113 
117 inline bool operator==(const Fock &f, const Fock &g)
118 {
119  return f.size() == g.size() &&
120  std::equal(f.begin(), f.end(), g.begin());
121 }
122 
129 inline bool operator<(const Fock &f, const Fock &g)
130 {
131  return std::lexicographical_compare(f.begin(), f.end(),
132  g.begin(), g.end());
133 }
134 
138 inline bool operator!=(const Fock &f, const Fock &g)
139 {
140  return !(f == g);
141 }
142 
149 inline bool operator>(const Fock &f, const Fock &g)
150 {
151  return g < f;
152 }
153 
160 inline bool operator<=(const Fock &f, const Fock &g)
161 {
162  return !(f > g);
163 }
164 
171 inline bool operator>=(const Fock &f, const Fock &g)
172 {
173  return !(f < g);
174 }
175 
181 class Basis: private std::set<Fock>
182 {
183  using Base = std::set<Fock>;
184 
185 public:
187  using Set = std::set<Fock>; // In principle this can be different from Base
188  using Value = Fock;
189  using value_type = Value;
190  using Reference = Value&;
191  using reference = Reference;
192 
193  using Iterator = Base::iterator;
194  using ConstIterator = Base::const_iterator;
195  using ReverseIterator = Base::reverse_iterator;
196  using ConstReverseIterator = Base::const_reverse_iterator;
197 
198  using Base::begin;
199  using Base::end;
200  using Base::rbegin;
201  using Base::rend;
202  using Base::cbegin;
203  using Base::cend;
204  using Base::crbegin;
205  using Base::crend;
206 
207  using Base::empty;
209  int size() const { return static_cast<int>(Base::size()); }
210  using Base::insert;
211  using Base::erase;
212  using Base::clear;
213  using Base::find;
214 
215  using Base::operator=;
216  Basis(): Base() {}
217  Basis(const Set &s): Base(s) {}
218  Basis(std::initializer_list<Fock> il): Base(il) {}
219  explicit Basis(int nphot, int modes);
220 
221  Basis operator+(const Basis &b) const;
222  Basis &operator+=(const Basis &b);
223  Basis operator*(const Basis &b) const;
224  Basis &operator*=(const Basis &b);
225  Basis &generateBasis(const int nphot, const int modes, const Fock &head = Fock());
226  Basis postselect(const Fock &ancilla) const;
227  template<typename ExecPolicy = execution::Seq>
228  State applyFunction(const FockAmpFunction &f) const;
229 };
230 
236 class State: private std::map<Fock, Complex>
237 {
238  using Base = std::map<Fock, Complex>;
239 
240 public:
241  using Element = std::pair<Fock, Complex>;
242  using Map = std::map<Fock, Complex>; // In principle this can be different from Base
243  using Value = Complex;
244  using value_type = Value;
245  using Reference = Value&;
246  using reference = Reference;
247 
248  using Iterator = Base::iterator;
249  using ConstIterator = Base::const_iterator;
250  using ReverseIterator = Base::reverse_iterator;
251  using ConstReverseIterator = Base::const_reverse_iterator;
252 
253  using Base::begin;
254  using Base::end;
255  using Base::rbegin;
256  using Base::rend;
257  using Base::cbegin;
258  using Base::cend;
259  using Base::crbegin;
260  using Base::crend;
261 
262  using Base::empty;
263  int size() const { return static_cast<int>(Base::size()); }
264  using Base::operator[];
265  using Base::insert;
266  using Base::erase;
267  using Base::clear;
268  using Base::find;
269 
270  using Base::operator=;
272  State(): Base() {}
273  State(const Map &m): Base(m) {}
275  State(const Fock &f): Base() { (*this)[f] = 1; }
276  State(const Basis &b): Base() { setBasis(b); }
277 
278  State operator+(const State &s) const;
279  State &operator+=(const State &s);
281  State operator-(const State &s) const { return *this + (-s); }
282  State &operator-=(const State &s);
283  State operator*(const State &s) const;
284  State &operator*=(const State &s);
285  State operator-() const;
286  State operator*(Complex x) const;
287  State &operator*=(Complex x);
288  State operator/(Complex x) const;
289  State &operator/=(Complex x);
290  Real norm() const;
291  State &normalize();
292  Complex dot(const State &s) const;
293  State postselect(const Fock &ancilla) const;
294  std::map<Fock, State> postselect(int modes) const;
295  std::map<Fock, State> postselect(const Basis &b) const;
296  Basis getBasis() const;
297  void setBasis(const Basis &b);
298  std::vector<State::Value> getAmplitudes() const;
299  template<typename ExecPolicy = execution::Seq>
300  void setAmplitudes(const std::vector<Complex> &amps);
301  template<typename ExecPolicy = execution::Seq>
302  void setAmplitudes(const FockAmpFunction &f);
303 };
304 
305 State operator*(Complex x, const State &s);
306 Complex dot(const State &a, const State &b);
307 
308 } // Namespace linopt
309 
310 std::ostream &operator<<(std::ostream &stream, const linopt::Fock &f);
311 std::ostream &operator<<(std::ostream &stream, const linopt::Basis &b);
312 std::ostream &operator<<(std::ostream &stream, const linopt::State::Element &e);
313 std::ostream &operator<<(std::ostream &stream, const linopt::State &s);
314 
315 #endif // STATES_H
bool operator<=(const Fock &f, const Fock &g)
Compares two Fock states in lexicographic order.
Definition: states.h:160
State()
Default constructor.
Definition: states.h:272
The class representing a linear optical state.
Definition: states.h:236
The main namespace containing all library classes, functions, etc.
Definition: circuit.h:28
Fock operator*(const Fock &f) const
Returns a tensor product of *this and f.
Definition: states.cpp:71
Fock & operator+=(const Fock &f)
Effectively equivalent to *this = (*this) + f.
Definition: states.cpp:102
Fock operator+(const Fock &f) const
Returns a sum of two Fock states (elementwise addition of corresponding occupation numbers)...
Definition: states.cpp:93
Real prodFact() const
Returns a product of factorials of occupation numbers.
Definition: states.cpp:60
Complex dot(const State &a, const State &b)
Calculates a dot (scalar) product.
Definition: states.cpp:434
bool operator!=(const Fock &f, const Fock &g)
Tests whether two Fock states differ.
Definition: states.h:138
Fock & operator*=(const Fock &f)
Effectively equivalent to *this = (*this) * f.
Definition: states.cpp:80
The class representing a Fock state.
Definition: states.h:56
std::vector< int > Vector
Convenience typedef to std::vector.
Definition: states.h:62
State(const Fock &f)
Constructs a state from fock with unit amplitude.
Definition: states.h:275
bool operator<(const Fock &f, const Fock &g)
Compares two Fock states in lexicographic order.
Definition: states.h:129
The class representing a collection of Fock states.
Definition: states.h:181
bool operator>(const Fock &f, const Fock &g)
Compares two Fock states in lexicographic order.
Definition: states.h:149
int size() const
Returns the number of modes in a Fock state.
Definition: states.h:92
bool operator>=(const Fock &f, const Fock &g)
Compares two Fock states in lexicographic order.
Definition: states.h:171
Fock(const Vector &v)
Construct a Fock state from a fock::vector_class.
Definition: states.h:105
bool operator==(const Fock &f, const Fock &g)
Tests whether two Fock states are equal.
Definition: states.h:117
std::function< Complex(const Fock &)> FockAmpFunction
A typedef of a function taking a Fock state as an argument and returning a corresponding complex_type...
Definition: states.h:44
State operator-(const State &s) const
Subtracts two states.
Definition: states.h:281
int size() const
Returns the number of Fock states in the basis.
Definition: states.h:209
Fock()=default
Default constructor.
int total() const
Returns the total number of photons in all modes.
Definition: states.cpp:41
std::set< Fock > Set
Convenience typedef to std::set.
Definition: states.h:187