Reputation: 4114
I have a vector containing complex values (either defined as std::vector<std::complex<double>>
or arma::cx_vec
) and would like to convert them into vectors containing double-values of twice the size. Afterwards I would like to convert them back again. Currently I use two loops (here from going from double-vectors to complex vectors and back):
//get x and dx as vectors containing real values, with a size of 2 * dim
arma::cx_colvec local_x(dim), local_dx(dim);
for(size_t i = 0; i < x.size(); i += 2) {
local_x(i / 2) = std::complex<double>(x(i), x(i + 1));
}
//Do something with local_x and local_dx
for(size_t i = 0; i < 2 * dim; i += 2) {
dx(i) = local_dx(i / 2).real();
dx(i + 1) = local_dx(i / 2).imag();
}
//Send dx back
I can imagine that that might be rather slow. Therefore, are there other possibilities of reshaping those vectors from complex to double and back? Ideally involving iterators (such that I can use methods such as transform()
) instead of a loop over a size.
Background to this question is: I have complex input data which has to be put into a function A
which I can not modify, but which calls a user-supplied function again (called U
). This function does not support complex data types, only real types. Therefore, my intention was to flatten the vector before putting it into A
, unflatten it in U
, do the calculations on it, reflatten it and send it back again.
Upvotes: 2
Views: 1184
Reputation: 62686
std::complex<double>
is explicitly called out as something that can be treated as a double[2]
Array-oriented access
For any object
z
of typecomplex<T>
,reinterpret_cast<T(&)[2]>(z)[0]
is the real part ofz
andreinterpret_cast<T(&)[2]>(z)[1]
is the imaginary part ofz
.For any pointer to an element of an array of
complex<T>
namedp
and any valid array indexi
,reinterpret_cast<T*>(p)[2*i]
is the real part of the complex numberp[i]
, andreinterpret_cast<T*>(p)[2*i + 1]
is the imaginary part of the complex numberp[i]
The intent of this requirement is to preserve binary compatibility between the C++ library complex number types and the C language complex number types (and arrays thereof), which have an identical object representation requirement.
So you can use std::vector::data()
to obtain a complex<double> *
, and reinterpret it as a double *
with twice as many elements.
Upvotes: 2