Skip to content

Commit 29f9586

Browse files
committed
Updates + more pyqpp stuff
Signed-off-by: Vlad Gheorghiu <[email protected]>
1 parent fa9a0aa commit 29f9586

File tree

11 files changed

+792
-20
lines changed

11 files changed

+792
-20
lines changed

CHANGES.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
`${CMAKE_BUILD_DIR}`
3535
- Added benchmarking suite using [Catch2](https://github.com/catchorg/Catch2)
3636
in ["benchmarks"](https://github.com/softwareQinc/qpp/blob/main/benchmarks)
37+
- Bugfixes for `qpp::QFT()` and `qpp::TFQ()`
38+
- Finalized pyqpp, now all Quantum++ functions have corresponding bindings in
39+
Python
3740

3841
# Version 6.0 - 14 April 2025
3942

@@ -114,8 +117,7 @@
114117
as we now use Markdown format to keep track of changes in new releases
115118
- Removed Eigen3, pybind11, and GoogleTest dependencies; if not detected,
116119
they are installed automatically as build dependencies by CMake
117-
- Bumped GoogleTest version to HEAD latest, as
118-
[recommended by Google](https://github.com/google/googletest?tab=readme-ov-file#live-at-head)
120+
- Updated GoogleTest to the latest HEAD, as recommended by Google
119121
- Removed `-DWITH_EXAMPLES` and `-DWITH_UNIT_TESTS` CMake flags. Now both
120122
`examples` and `unit_tests` CMake targets are enabled.
121123
- Renamed ["qpp/classes/circuits/circuits.hpp"] to

include/qpp/classes/states.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ class States final : public internal::Singleton<const States> // const Singleton
287287
std::sqrt(static_cast<realT>(2.0)));
288288
z0 << 1, 0;
289289
z1 << 0, 1;
290+
290291
px0 = x0 * x0.adjoint();
291292
px1 = x1 * x1.adjoint();
292293
py0 = y0 * y0.adjoint();

include/qpp/operations.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3536,7 +3536,7 @@ expr_t<Derived> QFT(const Eigen::MatrixBase<Derived>& A, idx d = 2,
35363536

35373537
std::vector<idx> subsys(n);
35383538
std::iota(subsys.begin(), subsys.end(), 0);
3539-
ket result = applyQFT(rA, subsys, d, swap);
3539+
expr_t<Derived> result = applyQFT(rA, subsys, d, swap);
35403540

35413541
return result;
35423542
}
@@ -3588,7 +3588,7 @@ expr_t<Derived> TFQ(const Eigen::MatrixBase<Derived>& A, idx d = 2,
35883588

35893589
std::vector<idx> subsys(n);
35903590
std::iota(subsys.begin(), subsys.end(), 0);
3591-
ket result = applyTFQ(rA, subsys, d, swap);
3591+
expr_t<Derived> result = applyTFQ(rA, subsys, d, swap);
35923592

35933593
return result;
35943594
}

pyqpp/include/pyqpp/classes/states_bind.hpp

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,32 @@ inline void init_classes_states(py::module_& m) {
3434
using namespace qpp;
3535

3636
auto states = m.def_submodule("states");
37-
states.attr("x0") = qpp::st.x0;
38-
states.attr("x1") = qpp::st.x1;
39-
states.attr("y0") = qpp::st.y0;
40-
states.attr("y1") = qpp::st.y1;
41-
states.attr("z0") = qpp::st.z0;
42-
states.attr("z1") = qpp::st.z1;
37+
states.attr("x0") = qpp::cmat(qpp::st.x0);
38+
states.attr("x1") = qpp::cmat(qpp::st.x1);
39+
states.attr("y0") = qpp::cmat(qpp::st.y0);
40+
states.attr("y1") = qpp::cmat(qpp::st.y1);
41+
states.attr("z0") = qpp::cmat(qpp::st.z0);
42+
states.attr("z1") = qpp::cmat(qpp::st.z1);
4343

44-
states.attr("b00") = qpp::st.b00;
45-
states.attr("b01") = qpp::st.b01;
46-
states.attr("b10") = qpp::st.b10;
47-
states.attr("b11") = qpp::st.b11;
44+
states.attr("px0") = qpp::st.px0;
45+
states.attr("px1") = qpp::st.px1;
46+
states.attr("py0") = qpp::st.py0;
47+
states.attr("py1") = qpp::st.py1;
48+
states.attr("pz0") = qpp::st.pz0;
49+
states.attr("pz1") = qpp::st.pz1;
50+
51+
states.attr("b00") = qpp::cmat(qpp::st.b00);
52+
states.attr("b01") = qpp::cmat(qpp::st.b01);
53+
states.attr("b10") = qpp::cmat(qpp::st.b10);
54+
states.attr("b11") = qpp::cmat(qpp::st.b11);
4855

4956
states.attr("pb00") = qpp::st.pb00;
5057
states.attr("pb01") = qpp::st.pb01;
5158
states.attr("pb10") = qpp::st.pb10;
5259
states.attr("pb11") = qpp::st.pb11;
5360

54-
states.attr("GHZ") = qpp::st.GHZ;
55-
states.attr("W") = qpp::st.W;
61+
states.attr("GHZ") = qpp::cmat(qpp::st.GHZ);
62+
states.attr("W") = qpp::cmat(qpp::st.W);
5663

5764
states.attr("pGHZ") = qpp::st.pGHZ;
5865
states.attr("pW") = qpp::st.pW;

pyqpp/include/pyqpp/constants_bind.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@
2929

3030
#include "pyqpp/pyqpp_common.hpp"
3131

32-
/* Constants from constants.hpp */
32+
/* Bindings for constants.hpp */
3333
inline void init_constants(py::module_& m) {
3434
using namespace qpp;
3535

3636
m.attr("ee") = qpp::ee;
37-
m.def("omega", &qpp::omega, "D-th root of unity", py::arg("D"));
37+
m.attr("infty") = qpp::infty;
3838
m.attr("pi") = qpp::pi;
39+
40+
m.def("omega", &qpp::omega, "D-th root of unity", py::arg("D"));
3941
}
4042

4143
#endif /* PYQPP_CONSTANTS_BIND_HPP_ */
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* This file is part of pyqpp.
3+
*
4+
* Copyright (c) 2017 - 2025 softwareQ Inc. All rights reserved.
5+
*
6+
* MIT License
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24+
* SOFTWARE.
25+
*/
26+
27+
#ifndef PYQPP_ENTANGLEMENT_BIND_HPP_
28+
#define PYQPP_ENTANGLEMENT_BIND_HPP_
29+
30+
#include "pyqpp/pyqpp_common.hpp"
31+
32+
/* Bindings for entropies.hpp */
33+
inline void init_entanglement(py::module_& m) {
34+
using namespace qpp;
35+
36+
// --- Schmidt Decomposition and Coefficients ---
37+
38+
m.def(
39+
"schmidtcoeffs",
40+
[](const cmat& A, const std::vector<idx>& dims) {
41+
return qpp::schmidtcoeffs(A, dims);
42+
},
43+
"Schmidt coefficients of the bi-partite pure state A.", py::arg("A"),
44+
py::arg("dims"));
45+
46+
m.def(
47+
"schmidtcoeffs",
48+
[](const cmat& A, idx d) { return qpp::schmidtcoeffs(A, d); },
49+
"Schmidt coefficients of the bi-partite pure state A (uniform "
50+
"dimensions).",
51+
py::arg("A"), py::arg("d") = 2);
52+
53+
m.def(
54+
"schmidtA",
55+
[](const cmat& A, const std::vector<idx>& dims) {
56+
return qpp::schmidtA(A, dims);
57+
},
58+
"Schmidt basis on Alice side.", py::arg("A"), py::arg("dims"));
59+
60+
m.def(
61+
"schmidtB",
62+
[](const cmat& A, const std::vector<idx>& dims) {
63+
return qpp::schmidtB(A, dims);
64+
},
65+
"Schmidt basis on Bob side.", py::arg("A"), py::arg("dims"));
66+
67+
m.def(
68+
"schmidtprobs",
69+
[](const cmat& A, const std::vector<idx>& dims) {
70+
return qpp::schmidtprobs(A, dims);
71+
},
72+
"Schmidt probabilities (squares of coefficients) of the bi-partite "
73+
"pure state A.",
74+
py::arg("A"), py::arg("dims"));
75+
76+
m.def(
77+
"schmidt",
78+
[](const cmat& A, const std::vector<idx>& dims) {
79+
return qpp::schmidt(A, dims);
80+
},
81+
"Full Schmidt decomposition: returns tuple(U, V, coeffs, probs).",
82+
py::arg("A"), py::arg("dims"));
83+
84+
// --- Entanglement Measures ---
85+
86+
m.def(
87+
"entanglement",
88+
[](const cmat& A, const std::vector<idx>& dims) {
89+
return qpp::entanglement(A, dims);
90+
},
91+
"von-Neumann entanglement entropy of the bi-partite pure state A.",
92+
py::arg("A"), py::arg("dims"));
93+
94+
m.def(
95+
"gconcurrence", [](const cmat& A) { return qpp::gconcurrence(A); },
96+
"G-concurrence of the bi-partite pure state A.", py::arg("A"));
97+
98+
m.def(
99+
"negativity",
100+
[](const cmat& A, const std::vector<idx>& dims) {
101+
return qpp::negativity(A, dims);
102+
},
103+
"Negativity of the bi-partite mixed state A.", py::arg("A"),
104+
py::arg("dims"));
105+
106+
m.def(
107+
"lognegativity",
108+
[](const cmat& A, const std::vector<idx>& dims) {
109+
return qpp::lognegativity(A, dims);
110+
},
111+
"Logarithmic negativity of the bi-partite mixed state A.", py::arg("A"),
112+
py::arg("dims"));
113+
114+
m.def(
115+
"concurrence", [](const cmat& A) { return qpp::concurrence(A); },
116+
"Wootters concurrence of the bi-partite qubit mixed state A.",
117+
py::arg("A"));
118+
}
119+
#endif /* PYQPP_ENTANGLEMENT_BIND_HPP_ */
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* This file is part of pyqpp.
3+
*
4+
* Copyright (c) 2017 - 2025 softwareQ Inc. All rights reserved.
5+
*
6+
* MIT License
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24+
* SOFTWARE.
25+
*/
26+
27+
#ifndef PYQPP_ENTROPIES_BIND_HPP_
28+
#define PYQPP_ENTROPIES_BIND_HPP_
29+
30+
#include "pyqpp/pyqpp_common.hpp"
31+
32+
/* Bindings for entropies.hpp */
33+
inline void init_entropies(py::module_& m) {
34+
using namespace qpp;
35+
36+
// --- Entropy Bindings ---
37+
38+
// von-Neumann entropy (Templated for MatrixBase)
39+
m.def(
40+
"entropy", [](const cmat& A) { return qpp::entropy(A); },
41+
"Computes the von-Neumann entropy of a density matrix (base 2).",
42+
py::arg("A"));
43+
44+
// Shannon entropy (Non-templated, but kept as lambda for consistency)
45+
m.def(
46+
"entropy",
47+
[](const std::vector<realT>& prob) { return qpp::entropy(prob); },
48+
"Computes the Shannon entropy of a probability distribution (base 2).",
49+
py::arg("prob"));
50+
51+
// Renyi entropy (Templated for MatrixBase)
52+
m.def(
53+
"renyi",
54+
[](const cmat& A, realT alpha) { return qpp::renyi(A, alpha); },
55+
"Computes the Renyi-alpha entropy of a density matrix.", py::arg("A"),
56+
py::arg("alpha"));
57+
58+
// Renyi entropy (Vector version)
59+
m.def(
60+
"renyi",
61+
[](const std::vector<realT>& prob, realT alpha) {
62+
return qpp::renyi(prob, alpha);
63+
},
64+
"Computes the Renyi-alpha entropy of a probability distribution.",
65+
py::arg("prob"), py::arg("alpha"));
66+
67+
// Tsallis entropy (Templated for MatrixBase)
68+
m.def(
69+
"tsallis", [](const cmat& A, realT q) { return qpp::tsallis(A, q); },
70+
"Computes the Tsallis-q entropy of a density matrix.", py::arg("A"),
71+
py::arg("q"));
72+
73+
// Tsallis entropy (Vector version)
74+
m.def(
75+
"tsallis",
76+
[](const std::vector<realT>& prob, realT q) {
77+
return qpp::tsallis(prob, q);
78+
},
79+
"Computes the Tsallis-q entropy of a probability distribution.",
80+
py::arg("prob"), py::arg("q"));
81+
82+
// --- Mutual Information Bindings ---
83+
84+
// Quantum Mutual Information (Templated, varied dimensions)
85+
m.def(
86+
"qmutualinfo",
87+
[](const cmat& A, const std::vector<idx>& subsysA,
88+
const std::vector<idx>& subsysB, const std::vector<idx>& dims) {
89+
return qpp::qmutualinfo(A, subsysA, subsysB, dims);
90+
},
91+
"Computes the quantum mutual information between two subsystems A and "
92+
"B with given dimensions.",
93+
py::arg("A"), py::arg("subsysA"), py::arg("subsysB"), py::arg("dims"));
94+
95+
// Quantum Mutual Information (Templated, uniform dimensions)
96+
m.def(
97+
"qmutualinfo",
98+
[](const cmat& A, const std::vector<idx>& subsysA,
99+
const std::vector<idx>& subsysB,
100+
idx d) { return qpp::qmutualinfo(A, subsysA, subsysB, d); },
101+
"Computes the quantum mutual information between two subsystems A and "
102+
"B assuming uniform dimensions d.",
103+
py::arg("A"), py::arg("subsysA"), py::arg("subsysB"), py::arg("d") = 2);
104+
}
105+
106+
#endif /* PYQPP_ENTROPIES_BIND_HPP_ */

0 commit comments

Comments
 (0)