diff --git a/base/Apply.cc b/base/Apply.cc index 4b08fa9f0dcfd94082c1de82ab91293ce7018c80..4ad026b79e932c6297cb6733e54ac5c50925ebbf 100644 --- a/base/Apply.cc +++ b/base/Apply.cc @@ -11,7 +11,7 @@ namespace dp3 { namespace base { void apply(size_t nBaseline, size_t nChannel, const_cursor<Baseline> baselines, - const_cursor<double> coeff, cursor<dcomplex> data) { + const_cursor<double> coeff, cursor<std::complex<double>> data) { for (size_t bl = 0; bl < nBaseline; ++bl) { const size_t p = baselines->first; const size_t q = baselines->second; @@ -19,36 +19,36 @@ void apply(size_t nBaseline, size_t nChannel, const_cursor<Baseline> baselines, if (p != q) { // Jones matrix for station P. coeff.forward(1, p); - const dcomplex Jp_00(coeff[0], coeff[1]); - const dcomplex Jp_01(coeff[2], coeff[3]); - const dcomplex Jp_10(coeff[4], coeff[5]); - const dcomplex Jp_11(coeff[6], coeff[7]); + const std::complex<double> Jp_00(coeff[0], coeff[1]); + const std::complex<double> Jp_01(coeff[2], coeff[3]); + const std::complex<double> Jp_10(coeff[4], coeff[5]); + const std::complex<double> Jp_11(coeff[6], coeff[7]); coeff.backward(1, p); // Jones matrix for station Q, conjugated. coeff.forward(1, q); - const dcomplex Jq_00(coeff[0], -coeff[1]); - const dcomplex Jq_01(coeff[2], -coeff[3]); - const dcomplex Jq_10(coeff[4], -coeff[5]); - const dcomplex Jq_11(coeff[6], -coeff[7]); + const std::complex<double> Jq_00(coeff[0], -coeff[1]); + const std::complex<double> Jq_01(coeff[2], -coeff[3]); + const std::complex<double> Jq_10(coeff[4], -coeff[5]); + const std::complex<double> Jq_11(coeff[6], -coeff[7]); coeff.backward(1, q); // Compute (Jp x conj(Jq)) * vec(data), where 'x' denotes the // Kronecker product. for (size_t ch = 0; ch < nChannel; ++ch) { // Fetch visibilities. - const dcomplex xx = data[0]; - const dcomplex xy = data[1]; - const dcomplex yx = data[2]; - const dcomplex yy = data[3]; + const std::complex<double> xx = data[0]; + const std::complex<double> xy = data[1]; + const std::complex<double> yx = data[2]; + const std::complex<double> yy = data[3]; // Precompute terms involving conj(Jq) and data. Each term // appears twice in the computation of (Jp x conj(Jq)) // * vec(data). - const dcomplex Jq_00xx_01xy = Jq_00 * xx + Jq_01 * xy; - const dcomplex Jq_00yx_01yy = Jq_00 * yx + Jq_01 * yy; - const dcomplex Jq_10xx_11xy = Jq_10 * xx + Jq_11 * xy; - const dcomplex Jq_10yx_11yy = Jq_10 * yx + Jq_11 * yy; + const std::complex<double> Jq_00xx_01xy = Jq_00 * xx + Jq_01 * xy; + const std::complex<double> Jq_00yx_01yy = Jq_00 * yx + Jq_01 * yy; + const std::complex<double> Jq_10xx_11xy = Jq_10 * xx + Jq_11 * xy; + const std::complex<double> Jq_10yx_11yy = Jq_10 * yx + Jq_11 * yy; // Compute (Jp x conj(Jq)) * vec(data) from the precomputed // terms. diff --git a/base/Cursor.h b/base/Cursor.h index 2571ed1de743e021c953257ae5515720e7de376d..4c1221ac5e6c6167ce7ccb631ae6b4dffe24639a 100644 --- a/base/Cursor.h +++ b/base/Cursor.h @@ -3,15 +3,12 @@ // Copyright (C) 2020 ASTRON (Netherlands Institute for Radio Astronomy) // SPDX-License-Identifier: GPL-3.0-or-later -#ifndef DPPP_CURSOR_H -#define DPPP_CURSOR_H +#ifndef DP3_BASE_CURSOR_H_ +#define DP3_BASE_CURSOR_H_ #include <cassert> #include <complex> -typedef std::complex<double> dcomplex; -typedef std::complex<float> fcomplex; - namespace dp3 { namespace base { diff --git a/base/EstimateMixed.cc b/base/EstimateMixed.cc index 99ff743cf97d0d90d3070e1dda7b67798959c685..597f733d38abc1da98b12cfa7237ef8d29304c20 100644 --- a/base/EstimateMixed.cc +++ b/base/EstimateMixed.cc @@ -49,10 +49,11 @@ void makeIndex(std::size_t n_direction, std::size_t n_station, bool estimate(size_t nDirection, size_t nStation, size_t nBaseline, size_t nChannel, const_cursor<Baseline> baselines, - vector<const_cursor<fcomplex>> data, - vector<const_cursor<dcomplex>> model, const_cursor<bool> flag, - const_cursor<float> weight, const_cursor<dcomplex> mix, - double *unknowns, size_t maxiter) { + std::vector<const_cursor<std::complex<float>>> data, + std::vector<const_cursor<std::complex<double>>> model, + const_cursor<bool> flag, const_cursor<float> weight, + const_cursor<std::complex<double>> mix, double *unknowns, + size_t maxiter) { assert(data.size() == nDirection && model.size() == nDirection); // Initialize LSQ solver. @@ -70,8 +71,8 @@ bool estimate(size_t nDirection, size_t nStation, size_t nBaseline, vector<unsigned int> dIndex(4 * nPartial); // Allocate space for intermediate results. - vector<dcomplex> M(nDirection * 4), dM(nDirection * 16); - vector<double> dR(nPartial), dI(nPartial); + std::vector<std::complex<double>> M(nDirection * 4), dM(nDirection * 16); + std::vector<double> dR(nPartial), dI(nPartial); // Iterate until convergence. size_t nIterations = 0; @@ -88,30 +89,30 @@ bool estimate(size_t nDirection, size_t nStation, size_t nBaseline, for (size_t dr = 0; dr < nDirection; ++dr) { // Jones matrix for station P. const double *Jp = &(unknowns[dr * nStation * 8 + p * 8]); - const dcomplex Jp_00(Jp[0], Jp[1]); - const dcomplex Jp_01(Jp[2], Jp[3]); - const dcomplex Jp_10(Jp[4], Jp[5]); - const dcomplex Jp_11(Jp[6], Jp[7]); + const std::complex<double> Jp_00(Jp[0], Jp[1]); + const std::complex<double> Jp_01(Jp[2], Jp[3]); + const std::complex<double> Jp_10(Jp[4], Jp[5]); + const std::complex<double> Jp_11(Jp[6], Jp[7]); // Jones matrix for station Q, conjugated. const double *Jq = &(unknowns[dr * nStation * 8 + q * 8]); - const dcomplex Jq_00(Jq[0], -Jq[1]); - const dcomplex Jq_01(Jq[2], -Jq[3]); - const dcomplex Jq_10(Jq[4], -Jq[5]); - const dcomplex Jq_11(Jq[6], -Jq[7]); + const std::complex<double> Jq_00(Jq[0], -Jq[1]); + const std::complex<double> Jq_01(Jq[2], -Jq[3]); + const std::complex<double> Jq_10(Jq[4], -Jq[5]); + const std::complex<double> Jq_11(Jq[6], -Jq[7]); // Fetch model visibilities for the current direction. - const dcomplex xx = model[dr][0]; - const dcomplex xy = model[dr][1]; - const dcomplex yx = model[dr][2]; - const dcomplex yy = model[dr][3]; + const std::complex<double> xx = model[dr][0]; + const std::complex<double> xy = model[dr][1]; + const std::complex<double> yx = model[dr][2]; + const std::complex<double> yy = model[dr][3]; // Precompute terms involving conj(Jq) and the model // visibilities. - const dcomplex Jq_00xx_01xy = Jq_00 * xx + Jq_01 * xy; - const dcomplex Jq_00yx_01yy = Jq_00 * yx + Jq_01 * yy; - const dcomplex Jq_10xx_11xy = Jq_10 * xx + Jq_11 * xy; - const dcomplex Jq_10yx_11yy = Jq_10 * yx + Jq_11 * yy; + const std::complex<double> Jq_00xx_01xy = Jq_00 * xx + Jq_01 * xy; + const std::complex<double> Jq_00yx_01yy = Jq_00 * yx + Jq_01 * yy; + const std::complex<double> Jq_10xx_11xy = Jq_10 * xx + Jq_11 * xy; + const std::complex<double> Jq_10yx_11yy = Jq_10 * yx + Jq_11 * yy; // Precompute (Jp x conj(Jq)) * vec(data), where 'x' // denotes the Kronecker product. This is the model @@ -152,16 +153,16 @@ bool estimate(size_t nDirection, size_t nStation, size_t nBaseline, { if (!flag[cr]) { for (size_t tg = 0; tg < nDirection; ++tg) { - dcomplex visibility(0.0, 0.0); + std::complex<double> visibility(0.0, 0.0); for (size_t dr = 0; dr < nDirection; ++dr) { // Look-up mixing weight. - const dcomplex mix_weight = *mix; + const std::complex<double> mix_weight = *mix; // Weight model visibility. visibility += mix_weight * M[dr * 4 + cr]; // Compute weighted partial derivatives. - dcomplex derivative(0.0, 0.0); + std::complex<double> derivative(0.0, 0.0); derivative = mix_weight * dM[dr * 16 + cr * 4]; dR[dr * 8] = real(derivative); // for cr==0: Re(d/dRe(p_00))) dI[dr * 8] = imag(derivative); // for cr==0: Re(d/dIm(p_00))) @@ -205,16 +206,14 @@ bool estimate(size_t nDirection, size_t nStation, size_t nBaseline, } // Source directions. // Compute the residual. - dcomplex residual = - static_cast<dcomplex>(data[tg][cr]) - visibility; + std::complex<double> residual = + std::complex<double>{data[tg][cr]} - visibility; // Update the normal equations. solver.makeNorm(nPartial, &(dIndex[cr * nPartial]), &(dR[0]), - static_cast<double>(weight[cr]), - real(residual)); + double{weight[cr]}, residual.real()); solver.makeNorm(nPartial, &(dIndex[cr * nPartial]), &(dI[0]), - static_cast<double>(weight[cr]), - imag(residual)); + double{weight[cr]}, residual.imag()); // Move to next target direction. mix.backward(1, nDirection); diff --git a/base/EstimateMixed.h b/base/EstimateMixed.h index fac09ab6233b77e29185d78526e38289860d165e..9dc1fb0a2e6ff1c093499c595273d7391d695862 100644 --- a/base/EstimateMixed.h +++ b/base/EstimateMixed.h @@ -57,10 +57,10 @@ namespace base { /// A pointer to a buffer of unknowns of size nDirection * nStation * 8. bool estimate(size_t nDirection, size_t nStation, size_t nBaseline, size_t nChannel, const_cursor<Baseline> baselines, - std::vector<const_cursor<fcomplex>> data, - std::vector<const_cursor<dcomplex>> model, + std::vector<const_cursor<std::complex<float>>> data, + std::vector<const_cursor<std::complex<double>>> model, const_cursor<bool> flag, const_cursor<float> weight, - const_cursor<dcomplex> mix, double* unknowns, + const_cursor<std::complex<double>> mix, double* unknowns, size_t maxiter = 50); #ifdef HAVE_LIBDIRAC @@ -73,10 +73,10 @@ bool estimate(size_t nDirection, size_t nStation, size_t nBaseline, bool estimate(std::size_t n_direction, std::size_t n_station, std::size_t n_baseline, std::size_t n_channel, const_cursor<Baseline> baselines, - std::vector<const_cursor<fcomplex>> data, - std::vector<const_cursor<dcomplex>> model, + std::vector<const_cursor<std::complex<float>>> data, + std::vector<const_cursor<std::complex<double>>> model, const_cursor<bool> flag, const_cursor<float> weight, - const_cursor<dcomplex> mix, double* unknowns, + const_cursor<std::complex<double>> mix, double* unknowns, std::size_t lbfgs_mem, double robust_nu, std::size_t max_iter = 50); #endif /* HAVE_LIBDIRAC */ diff --git a/base/EstimateMixedLBFGS.cc b/base/EstimateMixedLBFGS.cc index d6112f3400c58fa621d6cb8e5a84fc21032a0e09..25efdb5dfebce2b4795f8e4660f4aede3cfe213b 100644 --- a/base/EstimateMixedLBFGS.cc +++ b/base/EstimateMixedLBFGS.cc @@ -18,6 +18,9 @@ #include <iostream> #ifdef HAVE_LIBDIRAC #include <Dirac.h> +// Dirac.h incorrectly defines "complex". +// -> Undefining it avoids conflicts with std::complex. +#undef complex #endif /* HAVE_LIBDIRAC */ using dp3::common::operator<<; @@ -33,18 +36,18 @@ struct LBFGSData { std::size_t n_baseline; std::size_t n_channel; const_cursor<Baseline> baselines; - std::vector<const_cursor<fcomplex>> data; - std::vector<const_cursor<dcomplex>> model; + std::vector<const_cursor<std::complex<float>>> data; + std::vector<const_cursor<std::complex<double>>> model; const_cursor<bool> flag; const_cursor<float> weight; - const_cursor<dcomplex> mix; + const_cursor<std::complex<double>> mix; double robust_nu; LBFGSData(std::size_t n_dir_, std::size_t n_st_, std::size_t n_base_, std::size_t n_chan_, const_cursor<Baseline> baselines_, - std::vector<const_cursor<fcomplex>> data_, - std::vector<const_cursor<dcomplex>> model_, + std::vector<const_cursor<std::complex<float>>> data_, + std::vector<const_cursor<std::complex<double>>> model_, const_cursor<bool> flag_, const_cursor<float> weight_, - const_cursor<dcomplex> mix_, double robust_nu_ = 2.0) + const_cursor<std::complex<double>> mix_, double robust_nu_ = 2.0) : n_direction(n_dir_), n_station(n_st_), n_baseline(n_base_), @@ -69,7 +72,7 @@ double cost_func(double *unknowns, int m, void *adata) { assert(static_cast<std::size_t>(m) == t->n_direction * t->n_station * 4 * 2); // Allocate space for intermediate results. - std::vector<dcomplex> M(t->n_direction * 4); + std::vector<std::complex<double>> M(t->n_direction * 4); double fcost = 0.0; @@ -83,30 +86,30 @@ double cost_func(double *unknowns, int m, void *adata) { for (std::size_t dr = 0; dr < t->n_direction; ++dr) { // Jones matrix for station P. const double *Jp = &(unknowns[dr * t->n_station * 8 + p * 8]); - const dcomplex Jp_00(Jp[0], Jp[1]); - const dcomplex Jp_01(Jp[2], Jp[3]); - const dcomplex Jp_10(Jp[4], Jp[5]); - const dcomplex Jp_11(Jp[6], Jp[7]); + const std::complex<double> Jp_00(Jp[0], Jp[1]); + const std::complex<double> Jp_01(Jp[2], Jp[3]); + const std::complex<double> Jp_10(Jp[4], Jp[5]); + const std::complex<double> Jp_11(Jp[6], Jp[7]); // Jones matrix for station Q, conjugated. const double *Jq = &(unknowns[dr * t->n_station * 8 + q * 8]); - const dcomplex Jq_00(Jq[0], -Jq[1]); - const dcomplex Jq_01(Jq[2], -Jq[3]); - const dcomplex Jq_10(Jq[4], -Jq[5]); - const dcomplex Jq_11(Jq[6], -Jq[7]); + const std::complex<double> Jq_00(Jq[0], -Jq[1]); + const std::complex<double> Jq_01(Jq[2], -Jq[3]); + const std::complex<double> Jq_10(Jq[4], -Jq[5]); + const std::complex<double> Jq_11(Jq[6], -Jq[7]); // Fetch model visibilities for the current direction. - const dcomplex xx = t->model[dr][0]; - const dcomplex xy = t->model[dr][1]; - const dcomplex yx = t->model[dr][2]; - const dcomplex yy = t->model[dr][3]; + const std::complex<double> xx = t->model[dr][0]; + const std::complex<double> xy = t->model[dr][1]; + const std::complex<double> yx = t->model[dr][2]; + const std::complex<double> yy = t->model[dr][3]; // Precompute terms involving conj(Jq) and the model // visibilities. - const dcomplex Jq_00xx_01xy = Jq_00 * xx + Jq_01 * xy; - const dcomplex Jq_00yx_01yy = Jq_00 * yx + Jq_01 * yy; - const dcomplex Jq_10xx_11xy = Jq_10 * xx + Jq_11 * xy; - const dcomplex Jq_10yx_11yy = Jq_10 * yx + Jq_11 * yy; + const std::complex<double> Jq_00xx_01xy = Jq_00 * xx + Jq_01 * xy; + const std::complex<double> Jq_00yx_01yy = Jq_00 * yx + Jq_01 * yy; + const std::complex<double> Jq_10xx_11xy = Jq_10 * xx + Jq_11 * xy; + const std::complex<double> Jq_10yx_11yy = Jq_10 * yx + Jq_11 * yy; // Precompute (Jp x conj(Jq)) * vec(data), where 'x' // denotes the Kronecker product. This is the model @@ -124,10 +127,10 @@ double cost_func(double *unknowns, int m, void *adata) { if (!(t->flag[cr])) { const double mwt = static_cast<double>(t->weight[cr]); for (std::size_t tg = 0; tg < t->n_direction; ++tg) { - dcomplex visibility(0.0, 0.0); + std::complex<double> visibility(0.0, 0.0); for (std::size_t dr = 0; dr < t->n_direction; ++dr) { // Look-up mixing weight. - const dcomplex mix_weight = *(t->mix); + const std::complex<double> mix_weight = *(t->mix); // Weight model visibility. visibility += mix_weight * M[dr * 4 + cr]; @@ -137,17 +140,17 @@ double cost_func(double *unknowns, int m, void *adata) { } // Source directions. // Compute the residual. - dcomplex residual = - static_cast<dcomplex>(t->data[tg][cr]) - visibility; + std::complex<double> residual = + std::complex<double>{t->data[tg][cr]} - visibility; // sum up cost // For reference: Gaussian cost is - // fcost += mwt * (real(residual) * real(residual) + - // imag(residual) * imag(residual)); + // fcost += mwt * (residual.real() * residual.real() + + // residual.imag() * residual.imag()); // Robust cost function - fcost += std::log(1.0 + mwt * real(residual) * real(residual) / + fcost += std::log(1.0 + mwt * residual.real() * residual.real() / t->robust_nu); - fcost += std::log(1.0 + mwt * imag(residual) * imag(residual) / + fcost += std::log(1.0 + mwt * residual.imag() * residual.imag() / t->robust_nu); // Move to next target direction. @@ -236,8 +239,8 @@ void grad_func(double *unknowns, double *grad, int m, void *adata) { t->n_direction * 8; // note: this for real,imag separately // Allocate space for intermediate results. - std::vector<dcomplex> M(t->n_direction * 4); - std::vector<dcomplex> dM(t->n_direction * 16); + std::vector<std::complex<double>> M(t->n_direction * 4); + std::vector<std::complex<double>> dM(t->n_direction * 16); std::vector<double> dR(n_partial); std::vector<double> dI(n_partial); std::vector<unsigned int> dIndex(4 * n_partial); // 4 correlations @@ -257,30 +260,30 @@ void grad_func(double *unknowns, double *grad, int m, void *adata) { for (std::size_t dr = 0; dr < t->n_direction; ++dr) { // Jones matrix for station P. const double *Jp = &(unknowns[dr * t->n_station * 8 + p * 8]); - const dcomplex Jp_00(Jp[0], Jp[1]); - const dcomplex Jp_01(Jp[2], Jp[3]); - const dcomplex Jp_10(Jp[4], Jp[5]); - const dcomplex Jp_11(Jp[6], Jp[7]); + const std::complex<double> Jp_00(Jp[0], Jp[1]); + const std::complex<double> Jp_01(Jp[2], Jp[3]); + const std::complex<double> Jp_10(Jp[4], Jp[5]); + const std::complex<double> Jp_11(Jp[6], Jp[7]); // Jones matrix for station Q, conjugated. const double *Jq = &(unknowns[dr * t->n_station * 8 + q * 8]); - const dcomplex Jq_00(Jq[0], -Jq[1]); - const dcomplex Jq_01(Jq[2], -Jq[3]); - const dcomplex Jq_10(Jq[4], -Jq[5]); - const dcomplex Jq_11(Jq[6], -Jq[7]); + const std::complex<double> Jq_00(Jq[0], -Jq[1]); + const std::complex<double> Jq_01(Jq[2], -Jq[3]); + const std::complex<double> Jq_10(Jq[4], -Jq[5]); + const std::complex<double> Jq_11(Jq[6], -Jq[7]); // Fetch model coherencies for the current direction. - const dcomplex xx = t->model[dr][0]; - const dcomplex xy = t->model[dr][1]; - const dcomplex yx = t->model[dr][2]; - const dcomplex yy = t->model[dr][3]; + const std::complex<double> xx = t->model[dr][0]; + const std::complex<double> xy = t->model[dr][1]; + const std::complex<double> yx = t->model[dr][2]; + const std::complex<double> yy = t->model[dr][3]; // Precompute terms involving conj(Jq) and the model // visibilities. - const dcomplex Jq_00xx_01xy = Jq_00 * xx + Jq_01 * xy; - const dcomplex Jq_00yx_01yy = Jq_00 * yx + Jq_01 * yy; - const dcomplex Jq_10xx_11xy = Jq_10 * xx + Jq_11 * xy; - const dcomplex Jq_10yx_11yy = Jq_10 * yx + Jq_11 * yy; + const std::complex<double> Jq_00xx_01xy = Jq_00 * xx + Jq_01 * xy; + const std::complex<double> Jq_00yx_01yy = Jq_00 * yx + Jq_01 * yy; + const std::complex<double> Jq_10xx_11xy = Jq_10 * xx + Jq_11 * xy; + const std::complex<double> Jq_10yx_11yy = Jq_10 * yx + Jq_11 * yy; // Precompute (Jp x conj(Jq)) * vec(model), where 'x' // denotes the Kronecker product. This is the model @@ -322,75 +325,75 @@ void grad_func(double *unknowns, double *grad, int m, void *adata) { if (!(t->flag[cr])) { const double mwt = static_cast<double>(t->weight[cr]); for (std::size_t tg = 0; tg < t->n_direction; ++tg) { - dcomplex visibility(0.0, 0.0); + std::complex<double> visibility(0.0, 0.0); for (std::size_t dr = 0; dr < t->n_direction; ++dr) { // Look-up mixing weight. - const dcomplex mix_weight = *(t->mix); + const std::complex<double> mix_weight = *(t->mix); // Weight model visibility. visibility += mix_weight * M[dr * 4 + cr]; // Compute weighted partial derivatives. - dcomplex derivative(0.0, 0.0); + std::complex<double> derivative(0.0, 0.0); derivative = mix_weight * dM[dr * 16 + cr * 4]; - dR[dr * 8] = real(derivative); // for cr==0: Re(d/dRe(p_00))) - dI[dr * 8] = imag(derivative); // for cr==0: Re(d/dIm(p_00))) + dR[dr * 8] = derivative.real(); // for cr==0: Re(d/dRe(p_00))) + dI[dr * 8] = derivative.imag(); // for cr==0: Re(d/dIm(p_00))) dR[dr * 8 + 1] = - -imag(derivative); // for cr==0: Im(d/dRe(p_00))) + -derivative.imag(); // for cr==0: Im(d/dRe(p_00))) dI[dr * 8 + 1] = - real(derivative); // for cr==0: Im(d/dIm(p_00))) + derivative.real(); // for cr==0: Im(d/dIm(p_00))) derivative = mix_weight * dM[dr * 16 + cr * 4 + 1]; dR[dr * 8 + 2] = - real(derivative); // for cr==0: Re(d/dRe(p_01))) + derivative.real(); // for cr==0: Re(d/dRe(p_01))) dI[dr * 8 + 2] = - imag(derivative); // for cr==0: Re(d/dIm(p_01))) + derivative.imag(); // for cr==0: Re(d/dIm(p_01))) dR[dr * 8 + 3] = - -imag(derivative); // for cr==0: Im(d/dRe(p_01))) + -derivative.imag(); // for cr==0: Im(d/dRe(p_01))) dI[dr * 8 + 3] = - real(derivative); // for cr==0: Im(d/dIm(p_01))) + derivative.real(); // for cr==0: Im(d/dIm(p_01))) derivative = mix_weight * dM[dr * 16 + cr * 4 + 2]; dR[dr * 8 + 4] = - real(derivative); // for cr==0: Re(d/dRe(q_00))) + derivative.real(); // for cr==0: Re(d/dRe(q_00))) dI[dr * 8 + 4] = - imag(derivative); // for cr==0: Re(d/dIm(q_00))) + derivative.imag(); // for cr==0: Re(d/dIm(q_00))) dR[dr * 8 + 5] = - imag(derivative); // for cr==0: Im(d/dRe(q_00))) + derivative.imag(); // for cr==0: Im(d/dRe(q_00))) dI[dr * 8 + 5] = - -real(derivative); // for cr==0: Im(d/dIm(q_00))) + -derivative.real(); // for cr==0: Im(d/dIm(q_00))) derivative = mix_weight * dM[dr * 16 + cr * 4 + 3]; dR[dr * 8 + 6] = - real(derivative); // for cr==0: Re(d/dRe(q_01))) + derivative.real(); // for cr==0: Re(d/dRe(q_01))) dI[dr * 8 + 6] = - imag(derivative); // for cr==0: Re(d/dIm(q_01))) + derivative.imag(); // for cr==0: Re(d/dIm(q_01))) dR[dr * 8 + 7] = - imag(derivative); // for cr==0: Im(d/dRe(q_01))) + derivative.imag(); // for cr==0: Im(d/dRe(q_01))) dI[dr * 8 + 7] = - -real(derivative); // for cr==0: Im(d/dIm(q_01))) + -derivative.real(); // for cr==0: Im(d/dIm(q_01))) // Move to next source direction. t->mix.forward(1); } // Source directions. // Compute the residual. - dcomplex residual = - static_cast<dcomplex>(t->data[tg][cr]) - visibility; + const std::complex<double> residual = + std::complex<double>{t->data[tg][cr]} - visibility; // accumulate gradient (for this correlation 'cr') // For reference, gradient for Gaussian noise is: // grad[dIndex[cr * n_partial + ci]] += - // 2.0 * dR[ci] * mwt * real(residual); + // 2.0 * dR[ci] * mwt * residual.real(); // grad[dIndex[cr * n_partial + ci]] += - // 2.0 * dI[ci] * mwt * imag(residual); + // 2.0 * dI[ci] * mwt * residual.imag(); for (std::size_t ci = 0; ci < n_partial; ci++) { grad[dIndex[cr * n_partial + ci]] -= - 2.0 * dR[ci] * mwt * real(residual) / - (t->robust_nu + mwt * real(residual) * real(residual)); + 2.0 * dR[ci] * mwt * residual.real() / + (t->robust_nu + mwt * residual.real() * residual.real()); grad[dIndex[cr * n_partial + ci]] -= - 2.0 * dI[ci] * mwt * imag(residual) / - (t->robust_nu + mwt * imag(residual) * imag(residual)); + 2.0 * dI[ci] * mwt * residual.imag() / + (t->robust_nu + mwt * residual.imag() * residual.imag()); } // Move to next target direction. @@ -456,10 +459,10 @@ void grad_func(double *unknowns, double *grad, int m, void *adata) { bool estimate(std::size_t n_direction, std::size_t n_station, std::size_t n_baseline, std::size_t n_channel, const_cursor<Baseline> baselines, - std::vector<const_cursor<fcomplex>> data, - std::vector<const_cursor<dcomplex>> model, + std::vector<const_cursor<std::complex<float>>> data, + std::vector<const_cursor<std::complex<double>>> model, const_cursor<bool> flag, const_cursor<float> weight, - const_cursor<dcomplex> mix, double *unknowns, + const_cursor<std::complex<double>> mix, double *unknowns, std::size_t lbfgs_mem, double robust_nu, std::size_t max_iter) { LBFGSData t(n_direction, n_station, n_baseline, n_channel, baselines, data, model, flag, weight, mix, robust_nu); diff --git a/base/Simulate.h b/base/Simulate.h index a3c179b3c62e35f0f3ba76df1b1e2d7ab6be2302..05a89cc530ba4eb572881bb0338233c707b5678d 100644 --- a/base/Simulate.h +++ b/base/Simulate.h @@ -119,7 +119,7 @@ void simulate(const Direction& reference, const std::shared_ptr<const Patch>& patch, size_t nStation, size_t nBaseline, size_t nChannel, const_cursor<Baseline> baselines, const_cursor<double> freq, - const_cursor<double> uvw, cursor<dcomplex> buffer); + const_cursor<double> uvw, cursor<std::complex<double>> buffer); } // namespace base } // namespace dp3 diff --git a/base/SubtractMixed.cc b/base/SubtractMixed.cc index ea40d398a530aee141f06a4e471b10a88ad0c659..3b1b2d5183c8b88c051d96d346566e6056de981d 100644 --- a/base/SubtractMixed.cc +++ b/base/SubtractMixed.cc @@ -12,8 +12,10 @@ namespace dp3 { namespace base { void subtract(size_t nBaseline, size_t nChannel, - const_cursor<Baseline> baselines, cursor<fcomplex> data, - const_cursor<dcomplex> model, const_cursor<dcomplex> weight) { + const_cursor<Baseline> baselines, + cursor<std::complex<float>> data, + const_cursor<std::complex<double>> model, + const_cursor<std::complex<double>> weight) { for (size_t bl = 0; bl < nBaseline; ++bl) { const size_t p = baselines->first; const size_t q = baselines->second; @@ -21,19 +23,19 @@ void subtract(size_t nBaseline, size_t nChannel, if (p != q) { for (size_t ch = 0; ch < nChannel; ++ch) { // Subtract weighted model from data. - *data -= static_cast<fcomplex>((*weight) * (*model)); + *data -= std::complex<float>((*weight) * (*model)); ++weight; ++model; ++data; - *data -= static_cast<fcomplex>((*weight) * (*model)); + *data -= std::complex<float>((*weight) * (*model)); ++weight; ++model; ++data; - *data -= static_cast<fcomplex>((*weight) * (*model)); + *data -= std::complex<float>((*weight) * (*model)); ++weight; ++model; ++data; - *data -= static_cast<fcomplex>((*weight) * (*model)); + *data -= std::complex<float>((*weight) * (*model)); ++weight; ++model; ++data; diff --git a/base/SubtractMixed.h b/base/SubtractMixed.h index 362e682a6663919309a109b9192123a73031df18..6377540747e58ab7d3f4d5537ab56f2adedb0127 100644 --- a/base/SubtractMixed.h +++ b/base/SubtractMixed.h @@ -34,8 +34,10 @@ namespace base { /// A cursor for a 3-D buffer of mixing weight of shape /// (\p nBaseline, \p nChannel, 4). void subtract(size_t nBaseline, size_t nChannel, - const_cursor<Baseline> baselines, cursor<fcomplex> data, - const_cursor<dcomplex> model, const_cursor<dcomplex> weight); + const_cursor<Baseline> baselines, + cursor<std::complex<float>> data, + const_cursor<std::complex<double>> model, + const_cursor<std::complex<double>> weight); } // namespace base } // namespace dp3 diff --git a/blob/BlobOStream.cc b/blob/BlobOStream.cc index 000d34320f9bf936d410dec0f739509e7d54ef47..0744e6ece7d932dbe9e29a3d7f0761c385211935 100644 --- a/blob/BlobOStream.cc +++ b/blob/BlobOStream.cc @@ -137,11 +137,11 @@ BlobOStream& BlobOStream::operator<<(const double& var) { putBuf(&var, sizeof(var)); return *this; } -BlobOStream& BlobOStream::operator<<(const fcomplex& var) { +BlobOStream& BlobOStream::operator<<(const std::complex<float>& var) { putBuf(&var, sizeof(var)); return *this; } -BlobOStream& BlobOStream::operator<<(const dcomplex& var) { +BlobOStream& BlobOStream::operator<<(const std::complex<double>& var) { putBuf(&var, sizeof(var)); return *this; } @@ -201,11 +201,11 @@ void BlobOStream::put(const float* values, uint64_t nrval) { void BlobOStream::put(const double* values, uint64_t nrval) { putBuf(values, nrval * sizeof(double)); } -void BlobOStream::put(const fcomplex* values, uint64_t nrval) { - putBuf(values, nrval * sizeof(fcomplex)); +void BlobOStream::put(const std::complex<float>* values, uint64_t nrval) { + putBuf(values, nrval * sizeof(std::complex<float>)); } -void BlobOStream::put(const dcomplex* values, uint64_t nrval) { - putBuf(values, nrval * sizeof(dcomplex)); +void BlobOStream::put(const std::complex<double>* values, uint64_t nrval) { + putBuf(values, nrval * sizeof(std::complex<double>)); } void BlobOStream::put(const std::string* values, uint64_t nrval) { for (uint64_t i = 0; i < nrval; i++) { diff --git a/blob/BlobOStream.h b/blob/BlobOStream.h index 3264ec9969d299f82c6199d5b1e6300dc4ab9eb3..b6ec57c2d20a0d473e7aa647010af2bf5b1414b1 100644 --- a/blob/BlobOStream.h +++ b/blob/BlobOStream.h @@ -14,9 +14,6 @@ #include <complex> #include <cstring> -typedef std::complex<double> dcomplex; -typedef std::complex<float> fcomplex; - namespace dp3 { namespace blob { @@ -83,12 +80,6 @@ class BlobOStream { /// Put a single value. /// A string will be stored as a length followed by the characters. - /// Note that a function is defined for the standard complex class - /// and for the types fcomplex, dcomplex, i16complex and u16complex. - /// This should be fine for the case where fcomplex is the builtin - /// complex type and the case where it is the standard class. - /// In the first case the fcomplex function is a separate function, - /// in the second case a specialisation of the templated function. /// @{ BlobOStream& operator<<(const bool& value); BlobOStream& operator<<(const char& value); @@ -102,13 +93,8 @@ class BlobOStream { BlobOStream& operator<<(const uint64_t& value); BlobOStream& operator<<(const float& value); BlobOStream& operator<<(const double& value); - template <class T> - BlobOStream& operator<<(const std::complex<T>& value); - // BlobOStream& operator<< (const i4complex& value); - // BlobOStream& operator<< (const i16complex& value); - // BlobOStream& operator<< (const u16complex& value); - BlobOStream& operator<<(const fcomplex& value); - BlobOStream& operator<<(const dcomplex& value); + BlobOStream& operator<<(const std::complex<float>& value); + BlobOStream& operator<<(const std::complex<double>& value); BlobOStream& operator<<(const std::string& value); BlobOStream& operator<<(const char* value); /// @} @@ -128,13 +114,8 @@ class BlobOStream { void put(const uint64_t* values, uint64_t nrval); void put(const float* values, uint64_t nrval); void put(const double* values, uint64_t nrval); - template <class T> - void put(const std::complex<T>* values, uint64_t nrval); - // void put (const i4complex* values, uint64_t nrval); - // void put (const i16complex* values, uint64_t nrval); - // void put (const u16complex* values, uint64_t nrval); - void put(const fcomplex* values, uint64_t nrval); - void put(const dcomplex* values, uint64_t nrval); + void put(const std::complex<float>* values, uint64_t nrval); + void put(const std::complex<double>* values, uint64_t nrval); void put(const std::string* values, uint64_t nrval); /// @} @@ -217,16 +198,6 @@ inline unsigned int BlobOStream::putStart(const char* objectType, inline int64_t BlobOStream::tellPos() const { return itsStream->tellPos(); } -template <class T> -inline BlobOStream& BlobOStream::operator<<(const std::complex<T>& value) { - putBuf(&value, sizeof(value)); - return *this; -} -template <class T> -inline void BlobOStream::put(const std::complex<T>* values, uint64_t nrval) { - putBuf(values, nrval * sizeof(std::complex<T>)); -} - template <class T> inline void BlobOStream::put(const std::vector<T>& vec) { operator<<(uint64_t(vec.size())); diff --git a/common/TypeNames.cc b/common/TypeNames.cc index b617b8d205f37dde5f1e833127afd81ecc4df0eb..6f79a8e015ea23f0f309f03cfc31bdd3bb7a67eb 100644 --- a/common/TypeNames.cc +++ b/common/TypeNames.cc @@ -80,6 +80,7 @@ const std::string& typeName(const std::complex<float>*) { static std::string str("fcomplex"); return str; } + const std::string& typeName(const std::complex<double>*) { static std::string str("dcomplex"); return str; diff --git a/steps/Demixer.cc b/steps/Demixer.cc index 503227f7b7c69d2e9b19c263c30a10fce430c464..321a0de70981a2488129791180ba7bb3a85c77c5 100644 --- a/steps/Demixer.cc +++ b/steps/Demixer.cc @@ -870,8 +870,8 @@ namespace { struct ThreadPrivateStorage { std::vector<double> unknowns; xt::xtensor<double, 2> uvw; - std::vector<casacore::Cube<dcomplex>> model; - casacore::Cube<dcomplex> model_subtr; + std::vector<casacore::Cube<std::complex<double>>> model; + casacore::Cube<std::complex<double>> model_subtr; size_t count_converged; }; @@ -977,17 +977,18 @@ void Demixer::demix() { itsFactors[ts].shape(0)); const casacore::Array<casacore::DComplex> demix_factor( shape, itsFactors[ts].data(), casacore::SHARE); - base::const_cursor<dcomplex> cr_mix = base::casa_const_cursor(demix_factor); + base::const_cursor<std::complex<double>> cr_mix = + base::casa_const_cursor(demix_factor); /// cout << "demixfactor "<<ts<<" = "<<itsFactors[ts]<<'\n'; - std::vector<base::const_cursor<fcomplex>> cr_data(nDr); - std::vector<base::const_cursor<dcomplex>> cr_model(nDr); + std::vector<base::const_cursor<std::complex<float>>> cr_data(nDr); + std::vector<base::const_cursor<std::complex<double>>> cr_model(nDr); for (size_t dr = 0; dr < nDr; ++dr) { cr_data[dr] = base::casa_const_cursor(casacore::Cube<casacore::Complex>( cube_shape, itsAvgResults[dr]->get()[ts]->GetData().data(), casacore::SHARE)); - cr_model[dr] = base::const_cursor<dcomplex>(storage.model[dr].data(), 3, - stride_model); + cr_model[dr] = base::const_cursor<std::complex<double>>( + storage.model[dr].data(), 3, stride_model); } const bool converged = @@ -1021,8 +1022,8 @@ void Demixer::demix() { ts_subtr != ts_subtr_end; ++ts_subtr) { for (size_t dr = 0; dr < nDrSubtr; ++dr) { // Re-use simulation used for estimating Jones matrices if possible. - base::cursor<dcomplex> cr_model_subtr(storage.model[dr].data(), 3, - stride_model); + base::cursor<std::complex<double>> cr_model_subtr( + storage.model[dr].data(), 3, stride_model); // Re-simulate if required. if (multiplier != 1 || nCh != nChSubtr) { @@ -1051,12 +1052,12 @@ void Demixer::demix() { storage.uvw.data()); // Zero the visibility buffer. - storage.model_subtr = dcomplex(); + storage.model_subtr = std::complex<double>(); // Simulate visibilities at the resolution of the residual. size_t stride_model_subtr[3] = {1, nCr, nCr * nChSubtr}; - cr_model_subtr = base::cursor<dcomplex>(storage.model_subtr.data(), 3, - stride_model_subtr); + cr_model_subtr = base::cursor<std::complex<double>>( + storage.model_subtr.data(), 3, stride_model_subtr); base::Simulator simulator(itsPatchList[dr]->direction(), nSt, itsBaselines, @@ -1083,7 +1084,8 @@ void Demixer::demix() { casacore::Cube<casacore::Complex> cube_residual( cube_shape, itsAvgResultSubtr->get()[ts_subtr]->GetData().data(), casacore::SHARE); - base::cursor<fcomplex> cr_residual = base::casa_cursor(cube_residual); + base::cursor<std::complex<float>> cr_residual = + base::casa_cursor(cube_residual); // Construct a cursor to iterate over a slice of the mixing matrix // at the resolution of the residual. The "to" and "from" direction @@ -1109,9 +1111,8 @@ void Demixer::demix() { itsFactorsSubtr[ts_subtr].data(), casacore::SHARE); IPosition offset(5, itsNDir - 1, dr, 0, 0, 0); - base::const_cursor<dcomplex> cr_mix_subtr = - base::const_cursor<dcomplex>(&(demix_factors_subtr(offset)), 3, - stride_mix_subtr_slice); + base::const_cursor<std::complex<double>> cr_mix_subtr( + &(demix_factors_subtr(offset)), 3, stride_mix_subtr_slice); // Subtract the source. subtract(nBl, nChSubtr, cr_baseline, cr_residual, cr_model_subtr, diff --git a/steps/OnePredict.cc b/steps/OnePredict.cc index 147fa6d601807a278cb098072d4c45c0ec5c9d31..306a54c6c0c138f61ad7180c81e55d94efdc1922 100644 --- a/steps/OnePredict.cc +++ b/steps/OnePredict.cc @@ -55,7 +55,6 @@ #include <boost/algorithm/string/case_conv.hpp> -using casacore::Cube; using casacore::MDirection; using casacore::MEpoch; using casacore::MVDirection; @@ -479,7 +478,8 @@ bool OnePredict::process(std::unique_ptr<DPBuffer> buffer) { const casacore::IPosition shape(3, thread_buffer.shape(2), thread_buffer.shape(1), thread_buffer.shape(0)); - Cube<dcomplex> simulatedest(shape, thread_buffer.data(), casacore::SHARE); + casacore::Cube<std::complex<double>> simulatedest( + shape, thread_buffer.data(), casacore::SHARE); simulators.emplace_back(phase_ref_, nSt, baselines_split[thread_index], casacore::Vector<double>(info().chanFreqs()), @@ -507,7 +507,8 @@ bool OnePredict::process(std::unique_ptr<DPBuffer> buffer) { // Always use model.shape(), since it's equal to the patch model shape. const casacore::IPosition shape(3, model.shape(2), model.shape(1), model.shape(0)); - Cube<dcomplex> simulatedest(shape, model_data, casacore::SHARE); + casacore::Cube<std::complex<double>> simulatedest(shape, model_data, + casacore::SHARE); simulators.emplace_back(phase_ref_, nSt, baselines_, casacore::Vector<double>(info().chanFreqs()),