2 #include "catch2/catch_all.hpp"
4 #include "purify/directories.h"
8 #include "purify/test_data.h"
11 #include <sopt/power_method.h>
17 const t_int imsizex = 256;
18 const t_int imsizey = 256;
19 Vector<t_real>
u = Vector<t_real>::Random(10) * imsizex / 2;
20 Vector<t_real>
v = Vector<t_real>::Random(10) * imsizey / 2;
21 Vector<t_complex> input = Vector<t_complex>::Zero(imsizex * imsizey);
22 input(
static_cast<t_int
>(imsizex * 0.5 + imsizey * 0.5 * imsizex)) = 1.;
23 const t_uint M =
u.size();
24 const t_real oversample_ratio = 2;
25 const t_int ftsizev = std::floor(imsizey * oversample_ratio);
26 const t_int ftsizeu = std::floor(imsizex * oversample_ratio);
30 const Vector<t_complex> y = Vector<t_complex>::Ones(
u.size());
36 const std::shared_ptr<sopt::LinearTransform<Vector<t_complex>>> measure_op =
37 measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
38 u,
v, Vector<t_real>::Zero(M), Vector<t_complex>::Ones(M), imsizey, imsizex,
39 oversample_ratio,
kernel, Ju, Jv);
40 const Vector<t_complex> y_test = *measure_op * input;
41 CAPTURE(y_test.array() / y.array());
42 const t_real max_test = y_test.cwiseAbs().mean();
43 CAPTURE(y_test / max_test);
45 CHECK((y_test / max_test).isApprox((y), 1e-6));
49 const auto measure_op = measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
50 u,
v, Vector<t_real>::Zero(M), Vector<t_complex>::Ones(M), imsizey, imsizex,
51 oversample_ratio,
kernel, 6, 6);
52 const Vector<t_complex> y_test = *measure_op * input;
53 CAPTURE(y_test.array() / y.array());
54 const t_real max_test = y_test.cwiseAbs().mean();
55 CAPTURE(y_test / max_test);
57 CHECK((y_test / max_test).isApprox((y), 1e-3));
61 const auto measure_op = measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
62 u,
v, Vector<t_real>::Zero(M), Vector<t_complex>::Ones(M), imsizey, imsizex,
63 oversample_ratio,
kernel, 10, 10);
64 const Vector<t_complex> y_test = *measure_op * input;
65 CAPTURE(y_test.array() / y.array());
66 const t_real max_test = y_test.cwiseAbs().mean();
67 CAPTURE(y_test / max_test);
69 CHECK((y_test / max_test).isApprox((y), 1e-4));
74 const t_real oversample_ratio = 2;
75 Vector<t_real>
u = Vector<t_real>::Random(10);
76 Vector<t_real>
v = Vector<t_real>::Random(10);
77 const t_uint M =
u.size();
78 const Vector<t_complex> y = Vector<t_complex>::Ones(
u.size());
81 for (
auto& J : {4, 5, 6, 7, 8}) {
82 for (
auto& imsize : {128, 256, 512}) {
83 const std::shared_ptr<sopt::LinearTransform<Vector<t_complex>>> measure_op =
84 measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
85 u * imsize / 2,
v * imsize / 2, Vector<t_real>::Zero(M), Vector<t_complex>::Ones(M),
86 imsize, imsize, oversample_ratio,
kernel, J, J);
87 Vector<t_complex> input = Vector<t_complex>::Zero(imsize * imsize);
88 input(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize)) = 1.;
89 const Vector<t_complex> y_test = (*measure_op * input).eval();
90 CAPTURE(y_test.cwiseAbs().mean());
95 CHECK(y_test.isApprox(y, 1e-3));
96 const Vector<t_complex> psf = (measure_op->adjoint() * y) * 1. / M;
97 CHECK(std::real(psf(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize))) ==
98 Approx(1.).margin(0.001));
104 for (
auto& J : {4, 5, 6, 7, 8}) {
105 for (
auto& imsize : {128, 256, 512}) {
108 u * imsize / 2,
v * imsize / 2, Vector<t_real>::Zero(M), Vector<t_complex>::Ones(M),
109 imsize, imsize, oversample_ratio,
kernel, J, J));
111 const std::shared_ptr<sopt::LinearTransform<Vector<t_complex>>> measure_op =
112 measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
113 u * imsize / 2,
v * imsize / 2, Vector<t_real>::Zero(M),
114 Vector<t_complex>::Ones(M), imsize, imsize, oversample_ratio,
kernel, J, J);
115 Vector<t_complex> input = Vector<t_complex>::Zero(imsize * imsize);
116 input(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize)) = 1.;
117 const Vector<t_complex> y_test = (*measure_op * input).eval();
118 CAPTURE(y_test.cwiseAbs().mean());
123 CHECK(y_test.isApprox(y, 1e-3));
124 const Vector<t_complex> psf = (measure_op->adjoint() * y) * 1. / M;
125 CHECK(std::real(psf(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize))) ==
126 Approx(1.).margin(0.001));
133 for (
auto& J : {4, 5, 6, 7, 8}) {
134 for (
auto& imsize : {128, 256, 512}) {
135 const std::shared_ptr<sopt::LinearTransform<Vector<t_complex>>> measure_op =
136 measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
137 u * imsize / 2,
v * imsize / 2, Vector<t_real>::Zero(M), Vector<t_complex>::Ones(M),
138 imsize, imsize, oversample_ratio,
kernel, J, J);
139 Vector<t_complex> input = Vector<t_complex>::Zero(imsize * imsize);
140 input(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize)) = 1.;
141 const Vector<t_complex> y_test = (*measure_op * input).eval();
142 CAPTURE(y_test.cwiseAbs().mean());
147 CHECK(y_test.isApprox(y, 1e-2));
148 const Vector<t_complex> psf = (measure_op->adjoint() * y) * 1. / M;
149 CHECK(std::real(psf(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize))) ==
150 Approx(1.).margin(0.01));
156 for (
auto& J : {4, 5, 6, 7, 8}) {
157 for (
auto& imsize : {128, 256, 512}) {
158 const std::shared_ptr<sopt::LinearTransform<Vector<t_complex>>> measure_op =
159 measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
160 u * imsize / 2,
v * imsize / 2, Vector<t_real>::Zero(M), Vector<t_complex>::Ones(M),
161 imsize, imsize, oversample_ratio,
kernel, J, J);
162 Vector<t_complex> input = Vector<t_complex>::Zero(imsize * imsize);
163 input(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize)) = 1.;
164 const Vector<t_complex> y_test = (*measure_op * input).eval();
165 CAPTURE(y_test.cwiseAbs().mean());
170 CHECK(y_test.isApprox(y, 1e-3));
171 const Vector<t_complex> psf = (measure_op->adjoint() * y) * 1. / M;
172 CHECK(std::real(psf(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize))) ==
173 Approx(1.).margin(0.001));
177 SECTION(
"wproj kb") {
179 for (
auto& J : {4, 5, 6, 7, 8}) {
180 for (
auto& imsize : {128, 256, 512}) {
181 const std::shared_ptr<sopt::LinearTransform<Vector<t_complex>>> measure_op =
182 measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
183 u * imsize / 2,
v * imsize / 2, Vector<t_real>::Zero(M), Vector<t_complex>::Ones(M),
184 imsize, imsize, oversample_ratio,
kernel, J, J,
false, 1e-6, 1e-6);
185 Vector<t_complex> input = Vector<t_complex>::Zero(imsize * imsize);
186 input(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize)) = 1.;
187 const Vector<t_complex> y_test = (*measure_op * input).eval();
188 CAPTURE(y_test.cwiseAbs().mean());
193 CHECK(y_test.isApprox(y, 1e-3));
194 const Vector<t_complex> psf = (measure_op->adjoint() * y) * 1. / M;
195 CHECK(std::real(psf(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize))) ==
196 Approx(1.).margin(0.001));
200 SECTION(
"wproj pswf") {
202 for (
auto& J : {4, 5, 6, 7, 8}) {
203 for (
auto& imsize : {128, 256, 512}) {
206 u * imsize / 2,
v * imsize / 2, Vector<t_real>::Zero(M), Vector<t_complex>::Ones(M),
207 imsize, imsize, oversample_ratio,
kernel, J, J,
false, 1e-6, 1e-6));
209 const std::shared_ptr<sopt::LinearTransform<Vector<t_complex>>> measure_op =
210 measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
211 u * imsize / 2,
v * imsize / 2, Vector<t_real>::Zero(M),
212 Vector<t_complex>::Ones(M), imsize, imsize, oversample_ratio,
kernel, J, J,
false,
214 Vector<t_complex> input = Vector<t_complex>::Zero(imsize * imsize);
215 input(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize)) = 1.;
216 const Vector<t_complex> y_test = (*measure_op * input).eval();
217 CAPTURE(y_test.cwiseAbs().mean());
222 CHECK(y_test.isApprox(y, 1e-3));
223 const Vector<t_complex> psf = (measure_op->adjoint() * y) * 1. / M;
224 CHECK(std::real(psf(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize))) ==
225 Approx(1.).margin(0.001));
230 SECTION(
"wproj gauss") {
232 for (
auto& J : {4, 5, 6, 7, 8}) {
233 for (
auto& imsize : {128, 256, 512}) {
234 const std::shared_ptr<sopt::LinearTransform<Vector<t_complex>>> measure_op =
235 measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
236 u * imsize / 2,
v * imsize / 2, Vector<t_real>::Zero(M), Vector<t_complex>::Ones(M),
237 imsize, imsize, oversample_ratio,
kernel, J, J,
false, 1e-6, 1e-6);
238 Vector<t_complex> input = Vector<t_complex>::Zero(imsize * imsize);
239 input(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize)) = 1.;
240 const Vector<t_complex> y_test = (*measure_op * input).eval();
241 CAPTURE(y_test.cwiseAbs().mean());
246 CHECK(y_test.isApprox(y, 1e-2));
247 const Vector<t_complex> psf = (measure_op->adjoint() * y) * 1. / M;
248 CHECK(std::real(psf(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize))) ==
249 Approx(1.).margin(0.01));
253 SECTION(
"wproj box") {
255 for (
auto& J : {4, 5, 6, 7, 8}) {
256 for (
auto& imsize : {128, 256, 512}) {
257 const std::shared_ptr<sopt::LinearTransform<Vector<t_complex>>> measure_op =
258 measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
259 u * imsize / 2,
v * imsize / 2, Vector<t_real>::Zero(M), Vector<t_complex>::Ones(M),
260 imsize, imsize, oversample_ratio,
kernel, J, J,
false, 1e-6, 1e-6);
261 Vector<t_complex> input = Vector<t_complex>::Zero(imsize * imsize);
262 input(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize)) = 1.;
263 const Vector<t_complex> y_test = (*measure_op * input).eval();
264 CAPTURE(y_test.cwiseAbs().mean());
269 CHECK(y_test.isApprox(y, 1e-2));
270 const Vector<t_complex> psf = (measure_op->adjoint() * y) * 1. / M;
271 CHECK(std::real(psf(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize))) ==
272 Approx(1.).margin(0.001));
278 const t_real oversample_ratio = 2;
279 const t_int power_iters = 1000;
280 const t_real power_tol = 1e-4;
281 Vector<t_real>
u = Vector<t_real>::Random(10);
282 Vector<t_real>
v = Vector<t_real>::Random(10);
283 const t_uint M =
u.size();
284 const Vector<t_complex> y = Vector<t_complex>::Ones(
u.size());
287 for (
auto& J : {4, 5, 6, 7, 8}) {
288 for (
auto& imsize : {128, 256, 512}) {
289 const Vector<t_complex> init = Vector<t_complex>::Ones(imsize * imsize);
290 auto power_method_result = sopt::algorithm::normalise_operator<Vector<t_complex>>(
291 measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
292 u * imsize / 2,
v * imsize / 2, Vector<t_real>::Zero(M), Vector<t_complex>::Ones(M),
293 imsize, imsize, oversample_ratio,
kernel, J, J),
294 power_iters, power_tol, init);
295 const t_real norm = std::get<0>(power_method_result);
296 const std::shared_ptr<sopt::LinearTransform<Vector<t_complex>>> measure_op =
297 std::get<2>(power_method_result);
299 Vector<t_complex> input = Vector<t_complex>::Zero(imsize * imsize);
300 input(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize)) = 1.;
301 const Vector<t_complex> y_test = (*measure_op * input).eval();
302 CAPTURE(y_test.cwiseAbs().mean());
307 CHECK((y_test * norm).isApprox(y, 1e-3));
308 const Vector<t_complex> psf = (measure_op->adjoint() * y) * 1. / M * norm;
309 CHECK(std::real(psf(
static_cast<t_int
>(imsize * 0.5 + imsize * 0.5 * imsize))) ==
310 Approx(1.).margin(0.001));
#define CHECK(CONDITION, ERROR)
#define CHECK_THROWS(STATEMENT, ERROR)
const std::vector< t_real > u
data for u coordinate
const std::vector< t_real > v
data for v coordinate
std::shared_ptr< sopt::LinearTransform< T > > init_degrid_operator_2d(const Vector< t_real > &u, const Vector< t_real > &v, const Vector< t_real > &w, const Vector< t_complex > &weights, const t_uint &imsizey, const t_uint &imsizex, const t_real &oversample_ratio=2, const kernels::kernel kernel=kernels::kernel::kb, const t_uint Ju=4, const t_uint Jv=4, const bool w_stacking=false, const t_real &cellx=1, const t_real &celly=1)
Returns linear transform that is the standard degridding operator.
TEST_CASE("regression_degrid")