27 #ifndef INTERNAL_UTIL_H_
28 #define INTERNAL_UTIL_H_
32 #if (__GNUC__ && !__clang__)
33 #pragma GCC diagnostic ignored "-Warray-bounds"
34 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
52 for (
idx i = 0; i < numdims; ++i)
54 result[numdims - i - 1] = n % (dims[numdims - i - 1]);
55 n /= (dims[numdims - i - 1]);
71 part_prod[numdims - 1] = 1;
72 for (
idx i = 1; i < numdims; ++i)
74 part_prod[numdims - i - 1] =
75 part_prod[numdims - i] * dims[numdims - i];
76 result += midx[numdims - i - 1] * part_prod[numdims - i - 1];
79 return result + midx[numdims - 1];
83 template<
typename Derived>
86 return A.rows() == A.cols();
90 template<
typename Derived>
93 return A.rows() == 1 || A.cols() == 1;
97 template<
typename Derived>
100 return A.rows() == 1;
104 template<
typename Derived>
107 return A.cols() == 1;
114 return x.size() != 0;
118 template<
typename T1,
typename T2>
121 return lhs.size() == rhs.size();
127 if (dims.size() == 0)
130 return std::find_if(std::begin(dims), std::end(dims),
131 [dims](
idx i) ->
bool
133 if (i == 0)
return true;
135 }) == std::end(dims);
140 template<
typename Derived>
142 const Eigen::MatrixBase<Derived>& A)
144 idx proddim = std::accumulate(std::begin(dims), std::end(dims),
145 static_cast<idx>(1), std::multiplies<idx>());
147 return proddim ==
static_cast<idx>(A.rows());
151 template<
typename Derived>
153 const Eigen::MatrixBase<Derived>& V)
155 idx proddim = std::accumulate(std::begin(dims), std::end(dims),
156 static_cast<idx>(1), std::multiplies<idx>());
158 return proddim ==
static_cast<idx>(V.rows());
162 template<
typename Derived>
164 const Eigen::MatrixBase<Derived>& V)
166 idx proddim = std::accumulate(std::begin(dims), std::end(dims),
167 static_cast<idx>(1), std::multiplies<idx>());;
169 return proddim ==
static_cast<idx>(V.cols());
184 const std::vector<idx>& dims)
191 if (subsys.size() > dims.size())
195 std::vector<idx> subsyssort = subsys;
196 std::sort(std::begin(subsyssort), std::end(subsyssort));
199 if (std::unique(std::begin(subsyssort), std::end(subsyssort))
200 != std::end(subsyssort))
204 return std::find_if(std::begin(subsyssort), std::end(subsyssort),
205 [dims](
idx i) ->
bool
207 return i > dims.size() - 1;
208 }) == std::end(subsyssort);
212 template<
typename Derived>
215 return A.rows() == 2 && A.cols() == 2;
219 template<
typename Derived>
222 return V.rows() == 2 && V.cols() == 1;
226 template<
typename Derived>
229 return V.rows() == 1 && V.cols() == 2;
233 template<
typename Derived>
236 return (V.rows() == 1 && V.cols() == 2) ||
237 (V.rows() == 2 && V.cols() == 1);
244 if (perm.size() == 0)
247 std::vector<idx> ordered(perm.size());
248 std::iota(std::begin(ordered), std::end(ordered), 0);
250 return std::is_permutation(std::begin(ordered), std::end(ordered),
256 template<
typename Derived1,
typename Derived2>
258 const Eigen::MatrixBase<Derived2>& B)
266 if (!std::is_same<
typename Derived1::Scalar,
267 typename Derived2::Scalar>::value)
279 idx Acols =
static_cast<idx>(rA.cols());
280 idx Arows =
static_cast<idx>(rA.rows());
281 idx Bcols =
static_cast<idx>(rB.cols());
282 idx Brows =
static_cast<idx>(rB.rows());
285 result.resize(Arows * Brows, Acols * Bcols);
288 #pragma omp parallel for collapse(2)
289 #endif // WITH_OPENMP_
290 for (
idx j = 0; j < Acols; ++j)
291 for (
idx i = 0; i < Arows; ++i)
292 result.block(i * Brows, j * Bcols, Brows, Bcols) = rA(i, j) * rB;
299 template<
typename Derived1,
typename Derived2>
301 const Eigen::MatrixBase<Derived1>& A,
302 const Eigen::MatrixBase<Derived2>& B)
310 if (!std::is_same<
typename Derived1::Scalar,
311 typename Derived2::Scalar>::value)
323 idx Acols =
static_cast<idx>(rA.cols());
324 idx Arows =
static_cast<idx>(rA.rows());
325 idx Bcols =
static_cast<idx>(rB.cols());
326 idx Brows =
static_cast<idx>(rB.rows());
332 result.block(0, 0, Arows, Acols) = rA;
333 result.block(Arows, Acols, Brows, Bcols) = rB;
346 template<
typename T,
typename First,
typename ... Args>
349 v.emplace_back(std::forward<First>(first));
357 return static_cast<idx>(std::llround(std::log2(sz) / std::log2(d)));
366 return static_cast<idx>(std::llround(std::sqrt(sz)));
368 return static_cast<idx>(std::llround(std::pow(sz, 1./N)));
bool check_nonzero_size(const T &x) noexcept
Definition: util.h:112
constexpr idx maxn
Maximum number of allowed qu(d)its (subsystems)
Definition: constants.h:74
bool check_subsys_match_dims(const std::vector< idx > &subsys, const std::vector< idx > &dims)
Definition: util.h:183
dyn_mat< typename Derived1::Scalar > kron2(const Eigen::MatrixBase< Derived1 > &A, const Eigen::MatrixBase< Derived2 > &B)
Definition: util.h:257
bool check_cvector(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:105
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > dyn_mat
Dynamic Eigen matrix over the field specified by Scalar.
Definition: types.h:78
bool check_dims_match_mat(const std::vector< idx > &dims, const Eigen::MatrixBase< Derived > &A)
Definition: util.h:141
bool check_qubit_cvector(const Eigen::MatrixBase< Derived > &V) noexcept
Definition: util.h:220
Quantum++ main namespace.
Definition: codes.h:30
bool check_perm(const std::vector< idx > &perm)
Definition: util.h:242
idx get_num_subsys(idx sz, idx d)
Definition: util.h:355
bool check_rvector(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:98
bool check_dims_match_cvect(const std::vector< idx > &dims, const Eigen::MatrixBase< Derived > &V)
Definition: util.h:152
bool check_eq_dims(const std::vector< idx > &dims, idx dim) noexcept
Definition: util.h:173
bool check_vector(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:91
bool check_qubit_rvector(const Eigen::MatrixBase< Derived > &V) noexcept
Definition: util.h:227
bool check_qubit_vector(const Eigen::MatrixBase< Derived > &V) noexcept
Definition: util.h:234
bool check_matching_sizes(const T1 &lhs, const T2 &rhs) noexcept
Definition: util.h:119
Generates custom exceptions, used when validating function parameters.
Definition: exception.h:39
void n2multiidx(idx n, idx numdims, const idx *dims, idx *result) noexcept
Definition: util.h:48
void variadic_vector_emplace(std::vector< T > &)
Definition: util.h:341
idx get_dim_subsys(idx sz, idx N)
Definition: util.h:363
bool check_square_mat(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:84
dyn_mat< typename Derived1::Scalar > dirsum2(const Eigen::MatrixBase< Derived1 > &A, const Eigen::MatrixBase< Derived2 > &B)
Definition: util.h:300
bool check_dims_match_rvect(const std::vector< idx > &dims, const Eigen::MatrixBase< Derived > &V)
Definition: util.h:163
bool check_dims(const std::vector< idx > &dims)
Definition: util.h:125
std::size_t idx
Non-negative integer index.
Definition: types.h:36
bool check_qubit_matrix(const Eigen::MatrixBase< Derived > &A) noexcept
Definition: util.h:213
idx multiidx2n(const idx *midx, idx numdims, const idx *dims) noexcept
Definition: util.h:61