NFFT  3.3.2
solver.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2002, 2016 Jens Keiner, Stefan Kunis, Daniel Potts
00003  *
00004  * This program is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU General Public License as published by the Free Software
00006  * Foundation; either version 2 of the License, or (at your option) any later
00007  * version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but WITHOUT
00010  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00011  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00012  * details.
00013  *
00014  * You should have received a copy of the GNU General Public License along with
00015  * this program; if not, write to the Free Software Foundation, Inc., 51
00016  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00023 #include "config.h"
00024 
00025 #ifdef HAVE_COMPLEX_H
00026 #include <complex.h>
00027 #endif
00028 #include "nfft3.h"
00029 #include "infft.h"
00030 
00031 #undef X
00032 #if defined(NFFT_SINGLE)
00033 #define X(name) CONCAT(solverf_,name)
00034 #elif defined(NFFT_LDOUBLE)
00035 #define X(name) CONCAT(solverl_,name)
00036 #else
00037 #define X(name) CONCAT(solver_,name)
00038 #endif
00039 
00040 void X(init_advanced_complex)(X(plan_complex)* ths, Y(mv_plan_complex) *mv,
00041     unsigned flags)
00042 {
00043   ths->mv = mv;
00044   ths->flags = flags;
00045 
00046   ths->y          = (C*)Y(malloc)((size_t)(ths->mv->M_total) * sizeof(C));
00047   ths->r_iter     = (C*)Y(malloc)((size_t)(ths->mv->M_total) * sizeof(C));
00048   ths->f_hat_iter = (C*)Y(malloc)((size_t)(ths->mv->N_total) * sizeof(C));
00049   ths->p_hat_iter = (C*)Y(malloc)((size_t)(ths->mv->N_total) * sizeof(C));
00050 
00051   if(ths->flags & LANDWEBER)
00052     ths->z_hat_iter = ths->p_hat_iter;
00053 
00054   if(ths->flags & STEEPEST_DESCENT)
00055     {
00056       ths->z_hat_iter = ths->p_hat_iter;
00057       ths->v_iter     = (C*)Y(malloc)((size_t)(ths->mv->M_total) * sizeof(C));
00058     }
00059 
00060   if(ths->flags & CGNR)
00061     {
00062       ths->z_hat_iter = (C*)Y(malloc)((size_t)(ths->mv->N_total) * sizeof(C));
00063       ths->v_iter     = (C*)Y(malloc)((size_t)(ths->mv->M_total) * sizeof(C));
00064     }
00065 
00066   if(ths->flags & CGNE)
00067     ths->z_hat_iter = ths->p_hat_iter;
00068 
00069   if(ths->flags & PRECOMPUTE_WEIGHT)
00070     ths->w = (R*) Y(malloc)((size_t)(ths->mv->M_total) * sizeof(R));
00071 
00072   if(ths->flags & PRECOMPUTE_DAMP)
00073     ths->w_hat = (R*) Y(malloc)((size_t)(ths->mv->N_total) * sizeof(R));
00074 }
00075 
00076 void X(init_complex)(X(plan_complex)* ths, Y(mv_plan_complex) *mv)
00077 {
00078   X(init_advanced_complex)(ths, mv, CGNR);
00079 }
00080 
00081 void X(before_loop_complex)(X(plan_complex)* ths)
00082 {
00083   Y(cp_complex)(ths->mv->f_hat, ths->f_hat_iter, ths->mv->N_total);
00084 
00085   CSWAP(ths->r_iter, ths->mv->f);
00086   ths->mv->mv_trafo(ths->mv);
00087   CSWAP(ths->r_iter, ths->mv->f);
00088 
00089   Y(upd_axpy_complex)(ths->r_iter, K(-1.0), ths->y, ths->mv->M_total);
00090 
00091   if((!(ths->flags & LANDWEBER)) || (ths->flags & NORMS_FOR_LANDWEBER))
00092     {
00093       if(ths->flags & PRECOMPUTE_WEIGHT)
00094   ths->dot_r_iter = Y(dot_w_complex)(ths->r_iter, ths->w,
00095                ths->mv->M_total);
00096       else
00097   ths->dot_r_iter = Y(dot_complex)(ths->r_iter, ths->mv->M_total);
00098     }
00099 
00100   /*-----------------*/
00101   if(ths->flags & PRECOMPUTE_WEIGHT)
00102     Y(cp_w_complex)(ths->mv->f, ths->w, ths->r_iter, ths->mv->M_total);
00103   else
00104     Y(cp_complex)(ths->mv->f, ths->r_iter, ths->mv->M_total);
00105 
00106   CSWAP(ths->z_hat_iter, ths->mv->f_hat);
00107   ths->mv->mv_adjoint(ths->mv);
00108   CSWAP(ths->z_hat_iter, ths->mv->f_hat);
00109 
00110   if((!(ths->flags & LANDWEBER)) || (ths->flags & NORMS_FOR_LANDWEBER))
00111     {
00112       if(ths->flags & PRECOMPUTE_DAMP)
00113   ths->dot_z_hat_iter = Y(dot_w_complex)(ths->z_hat_iter, ths->w_hat,
00114              ths->mv->N_total);
00115       else
00116   ths->dot_z_hat_iter = Y(dot_complex)(ths->z_hat_iter,
00117                  ths->mv->N_total);
00118     }
00119 
00120   if(ths->flags & CGNE)
00121     ths->dot_p_hat_iter = ths->dot_z_hat_iter;
00122 
00123   if(ths->flags & CGNR)
00124     Y(cp_complex)(ths->p_hat_iter, ths->z_hat_iter, ths->mv->N_total);
00125 } /* void solver_before_loop */
00126 
00128 static void solver_loop_one_step_landweber_complex(X(plan_complex)* ths)
00129 {
00130   if(ths->flags & PRECOMPUTE_DAMP)
00131     Y(upd_xpawy_complex)(ths->f_hat_iter, ths->alpha_iter, ths->w_hat,
00132          ths->z_hat_iter, ths->mv->N_total);
00133   else
00134     Y(upd_xpay_complex)(ths->f_hat_iter, ths->alpha_iter, ths->z_hat_iter,
00135         ths->mv->N_total);
00136 
00137   /*-----------------*/
00138   Y(cp_complex)(ths->mv->f_hat, ths->f_hat_iter, ths->mv->N_total);
00139 
00140   CSWAP(ths->r_iter,ths->mv->f);
00141   ths->mv->mv_trafo(ths->mv);
00142   CSWAP(ths->r_iter,ths->mv->f);
00143 
00144   Y(upd_axpy_complex)(ths->r_iter, K(-1.0), ths->y, ths->mv->M_total);
00145 
00146   if(ths->flags & NORMS_FOR_LANDWEBER)
00147     {
00148       if(ths->flags & PRECOMPUTE_WEIGHT)
00149   ths->dot_r_iter = Y(dot_w_complex)(ths->r_iter,ths->w,
00150                ths->mv->M_total);
00151       else
00152   ths->dot_r_iter = Y(dot_complex)(ths->r_iter, ths->mv->M_total);
00153     }
00154 
00155   /*-----------------*/
00156   if(ths->flags & PRECOMPUTE_WEIGHT)
00157     Y(cp_w_complex)(ths->mv->f, ths->w, ths->r_iter, ths->mv->M_total);
00158   else
00159     Y(cp_complex)(ths->mv->f, ths->r_iter, ths->mv->M_total);
00160 
00161   CSWAP(ths->z_hat_iter,ths->mv->f_hat);
00162   ths->mv->mv_adjoint(ths->mv);
00163   CSWAP(ths->z_hat_iter,ths->mv->f_hat);
00164 
00165   if(ths->flags & NORMS_FOR_LANDWEBER)
00166     {
00167       if(ths->flags & PRECOMPUTE_DAMP)
00168   ths->dot_z_hat_iter = Y(dot_w_complex)(ths->z_hat_iter, ths->w_hat,
00169              ths->mv->N_total);
00170       else
00171   ths->dot_z_hat_iter = Y(dot_complex)(ths->z_hat_iter,
00172                  ths->mv->N_total);
00173     }
00174 } /* void solver_loop_one_step_landweber */
00175 
00177 static void solver_loop_one_step_steepest_descent_complex(X(plan_complex) *ths)
00178 {
00179   if(ths->flags & PRECOMPUTE_DAMP)
00180     Y(cp_w_complex)(ths->mv->f_hat, ths->w_hat, ths->z_hat_iter,
00181           ths->mv->N_total);
00182   else
00183     Y(cp_complex)(ths->mv->f_hat, ths->z_hat_iter, ths->mv->N_total);
00184 
00185   CSWAP(ths->v_iter,ths->mv->f);
00186   ths->mv->mv_trafo(ths->mv);
00187   CSWAP(ths->v_iter,ths->mv->f);
00188 
00189   if(ths->flags & PRECOMPUTE_WEIGHT)
00190     ths->dot_v_iter = Y(dot_w_complex)(ths->v_iter,ths->w,ths->mv->M_total);
00191   else
00192     ths->dot_v_iter = Y(dot_complex)(ths->v_iter, ths->mv->M_total);
00193 
00194   /*-----------------*/
00195   ths->alpha_iter = ths->dot_z_hat_iter / ths->dot_v_iter;
00196 
00197   /*-----------------*/
00198   if(ths->flags & PRECOMPUTE_DAMP)
00199     Y(upd_xpawy_complex)(ths->f_hat_iter, ths->alpha_iter, ths->w_hat,
00200          ths->z_hat_iter, ths->mv->N_total);
00201   else
00202     Y(upd_xpay_complex)(ths->f_hat_iter, ths->alpha_iter, ths->z_hat_iter,
00203         ths->mv->N_total);
00204 
00205   /*-----------------*/
00206   Y(upd_xpay_complex)(ths->r_iter, -ths->alpha_iter, ths->v_iter,
00207       ths->mv->M_total);
00208 
00209   if(ths->flags & PRECOMPUTE_WEIGHT)
00210     ths->dot_r_iter = Y(dot_w_complex)(ths->r_iter,ths->w,ths->mv->M_total);
00211   else
00212     ths->dot_r_iter = Y(dot_complex)(ths->r_iter, ths->mv->M_total);
00213 
00214   /*-----------------*/
00215   if(ths->flags & PRECOMPUTE_WEIGHT)
00216     Y(cp_w_complex)(ths->mv->f, ths->w, ths->r_iter, ths->mv->M_total);
00217   else
00218     Y(cp_complex)(ths->mv->f, ths->r_iter, ths->mv->M_total);
00219 
00220   CSWAP(ths->z_hat_iter,ths->mv->f_hat);
00221   ths->mv->mv_adjoint(ths->mv);
00222   CSWAP(ths->z_hat_iter,ths->mv->f_hat);
00223 
00224   if(ths->flags & PRECOMPUTE_DAMP)
00225     ths->dot_z_hat_iter = Y(dot_w_complex)(ths->z_hat_iter, ths->w_hat,
00226                ths->mv->N_total);
00227   else
00228     ths->dot_z_hat_iter = Y(dot_complex)(ths->z_hat_iter, ths->mv->N_total);
00229 } /* void solver_loop_one_step_steepest_descent */
00230 
00232 static void solver_loop_one_step_cgnr_complex(X(plan_complex) *ths)
00233 {
00234   if(ths->flags & PRECOMPUTE_DAMP)
00235     Y(cp_w_complex)(ths->mv->f_hat, ths->w_hat, ths->p_hat_iter,
00236           ths->mv->N_total);
00237   else
00238     Y(cp_complex)(ths->mv->f_hat, ths->p_hat_iter, ths->mv->N_total);
00239 
00240   CSWAP(ths->v_iter,ths->mv->f);
00241   ths->mv->mv_trafo(ths->mv);
00242   CSWAP(ths->v_iter,ths->mv->f);
00243 
00244   if(ths->flags & PRECOMPUTE_WEIGHT)
00245     ths->dot_v_iter = Y(dot_w_complex)(ths->v_iter,ths->w,ths->mv->M_total);
00246   else
00247     ths->dot_v_iter = Y(dot_complex)(ths->v_iter, ths->mv->M_total);
00248 
00249   /*-----------------*/
00250   ths->alpha_iter = ths->dot_z_hat_iter / ths->dot_v_iter;
00251 
00252   /*-----------------*/
00253   if(ths->flags & PRECOMPUTE_DAMP)
00254     Y(upd_xpawy_complex)(ths->f_hat_iter, ths->alpha_iter, ths->w_hat,
00255          ths->p_hat_iter, ths->mv->N_total);
00256   else
00257     Y(upd_xpay_complex)(ths->f_hat_iter, ths->alpha_iter, ths->p_hat_iter,
00258         ths->mv->N_total);
00259 
00260   /*-----------------*/
00261   Y(upd_xpay_complex)(ths->r_iter, -ths->alpha_iter, ths->v_iter,
00262       ths->mv->M_total);
00263 
00264   if(ths->flags & PRECOMPUTE_WEIGHT)
00265     ths->dot_r_iter = Y(dot_w_complex)(ths->r_iter,ths->w,ths->mv->M_total);
00266   else
00267     ths->dot_r_iter = Y(dot_complex)(ths->r_iter, ths->mv->M_total);
00268 
00269   /*-----------------*/
00270   if(ths->flags & PRECOMPUTE_WEIGHT)
00271     Y(cp_w_complex)(ths->mv->f, ths->w, ths->r_iter, ths->mv->M_total);
00272   else
00273     Y(cp_complex)(ths->mv->f, ths->r_iter, ths->mv->M_total);
00274 
00275   CSWAP(ths->z_hat_iter,ths->mv->f_hat);
00276   ths->mv->mv_adjoint(ths->mv);
00277   CSWAP(ths->z_hat_iter,ths->mv->f_hat);
00278 
00279   ths->dot_z_hat_iter_old = ths->dot_z_hat_iter;
00280   if(ths->flags & PRECOMPUTE_DAMP)
00281     ths->dot_z_hat_iter = Y(dot_w_complex)(ths->z_hat_iter, ths->w_hat,
00282                ths->mv->N_total);
00283   else
00284     ths->dot_z_hat_iter = Y(dot_complex)(ths->z_hat_iter, ths->mv->N_total);
00285 
00286   /*-----------------*/
00287   ths->beta_iter = ths->dot_z_hat_iter / ths->dot_z_hat_iter_old;
00288 
00289   /*-----------------*/
00290   Y(upd_axpy_complex)(ths->p_hat_iter, ths->beta_iter, ths->z_hat_iter,
00291       ths->mv->N_total);
00292 } /* void solver_loop_one_step_cgnr */
00293 
00295 static void solver_loop_one_step_cgne_complex(X(plan_complex) *ths)
00296 {
00297   ths->alpha_iter = ths->dot_r_iter / ths->dot_p_hat_iter;
00298 
00299   /*-----------------*/
00300   if(ths->flags & PRECOMPUTE_DAMP)
00301     Y(upd_xpawy_complex)(ths->f_hat_iter, ths->alpha_iter, ths->w_hat,
00302          ths->p_hat_iter, ths->mv->N_total);
00303   else
00304     Y(upd_xpay_complex)(ths->f_hat_iter, ths->alpha_iter, ths->p_hat_iter,
00305                           ths->mv->N_total);
00306 
00307   /*-----------------*/
00308   if(ths->flags & PRECOMPUTE_DAMP)
00309     Y(cp_w_complex)(ths->mv->f_hat, ths->w_hat, ths->p_hat_iter,
00310           ths->mv->N_total);
00311   else
00312     Y(cp_complex)(ths->mv->f_hat, ths->p_hat_iter, ths->mv->N_total);
00313 
00314   ths->mv->mv_trafo(ths->mv);
00315 
00316   Y(upd_xpay_complex)(ths->r_iter, -ths->alpha_iter, ths->mv->f,
00317       ths->mv->M_total);
00318 
00319   ths->dot_r_iter_old = ths->dot_r_iter;
00320   if(ths->flags & PRECOMPUTE_WEIGHT)
00321     ths->dot_r_iter = Y(dot_w_complex)(ths->r_iter,ths->w,ths->mv->M_total);
00322   else
00323     ths->dot_r_iter = Y(dot_complex)(ths->r_iter, ths->mv->M_total);
00324 
00325   /*-----------------*/
00326   ths->beta_iter = ths->dot_r_iter / ths->dot_r_iter_old;
00327 
00328   /*-----------------*/
00329   if(ths->flags & PRECOMPUTE_WEIGHT)
00330     Y(cp_w_complex)(ths->mv->f, ths->w, ths->r_iter, ths->mv->M_total);
00331   else
00332     Y(cp_complex)(ths->mv->f, ths->r_iter, ths->mv->M_total);
00333 
00334   ths->mv->mv_adjoint(ths->mv);
00335 
00336   Y(upd_axpy_complex)(ths->p_hat_iter, ths->beta_iter, ths->mv->f_hat,
00337       ths->mv->N_total);
00338 
00339   if(ths->flags & PRECOMPUTE_DAMP)
00340     ths->dot_p_hat_iter = Y(dot_w_complex)(ths->p_hat_iter, ths->w_hat,
00341                ths->mv->N_total);
00342   else
00343     ths->dot_p_hat_iter = Y(dot_complex)(ths->p_hat_iter, ths->mv->N_total);
00344 } /* void solver_loop_one_step_cgne */
00345 
00347 void X(loop_one_step_complex)(X(plan_complex) *ths)
00348 {
00349   if(ths->flags & LANDWEBER)
00350     solver_loop_one_step_landweber_complex(ths);
00351 
00352   if(ths->flags & STEEPEST_DESCENT)
00353     solver_loop_one_step_steepest_descent_complex(ths);
00354 
00355   if(ths->flags & CGNR)
00356     solver_loop_one_step_cgnr_complex(ths);
00357 
00358   if(ths->flags & CGNE)
00359     solver_loop_one_step_cgne_complex(ths);
00360 } /* void solver_loop_one_step */
00361 
00363 void X(finalize_complex)(X(plan_complex) *ths)
00364 {
00365   if(ths->flags & PRECOMPUTE_WEIGHT)
00366     Y(free)(ths->w);
00367 
00368   if(ths->flags & PRECOMPUTE_DAMP)
00369     Y(free)(ths->w_hat);
00370 
00371   if(ths->flags & CGNR)
00372     {
00373       Y(free)(ths->v_iter);
00374       Y(free)(ths->z_hat_iter);
00375     }
00376 
00377   if(ths->flags & STEEPEST_DESCENT)
00378     Y(free)(ths->v_iter);
00379 
00380   Y(free)(ths->p_hat_iter);
00381   Y(free)(ths->f_hat_iter);
00382 
00383   Y(free)(ths->r_iter);
00384   Y(free)(ths->y);
00385 } 
00388 /****************************************************************************/
00389 /****************************************************************************/
00390 /****************************************************************************/
00391 
00392 void X(init_advanced_double)(X(plan_double)* ths, Y(mv_plan_double) *mv, unsigned flags)
00393 {
00394   ths->mv = mv;
00395   ths->flags = flags;
00396 
00397   ths->y          = (R*)Y(malloc)((size_t)(ths->mv->M_total) * sizeof(R));
00398   ths->r_iter     = (R*)Y(malloc)((size_t)(ths->mv->M_total) * sizeof(R));
00399   ths->f_hat_iter = (R*)Y(malloc)((size_t)(ths->mv->N_total) * sizeof(R));
00400   ths->p_hat_iter = (R*)Y(malloc)((size_t)(ths->mv->N_total) * sizeof(R));
00401 
00402   if(ths->flags & LANDWEBER)
00403     ths->z_hat_iter = ths->p_hat_iter;
00404 
00405   if(ths->flags & STEEPEST_DESCENT)
00406     {
00407       ths->z_hat_iter = ths->p_hat_iter;
00408       ths->v_iter     = (R*)Y(malloc)((size_t)(ths->mv->M_total) * sizeof(R));
00409     }
00410 
00411   if(ths->flags & CGNR)
00412     {
00413       ths->z_hat_iter = (R*)Y(malloc)((size_t)(ths->mv->N_total) * sizeof(R));
00414       ths->v_iter     = (R*)Y(malloc)((size_t)(ths->mv->M_total) * sizeof(R));
00415     }
00416 
00417   if(ths->flags & CGNE)
00418     ths->z_hat_iter = ths->p_hat_iter;
00419 
00420   if(ths->flags & PRECOMPUTE_WEIGHT)
00421     ths->w = (R*) Y(malloc)((size_t)(ths->mv->M_total) * sizeof(R));
00422 
00423   if(ths->flags & PRECOMPUTE_DAMP)
00424     ths->w_hat = (R*) Y(malloc)((size_t)(ths->mv->N_total) * sizeof(R));
00425 }
00426 
00427 void X(init_double)(X(plan_double)* ths, Y(mv_plan_double) *mv)
00428 {
00429   X(init_advanced_double)(ths, mv, CGNR);
00430 }
00431 
00432 void X(before_loop_double)(X(plan_double)* ths)
00433 {
00434   Y(cp_double)(ths->mv->f_hat, ths->f_hat_iter, ths->mv->N_total);
00435 
00436   RSWAP(ths->r_iter, ths->mv->f);
00437   ths->mv->mv_trafo(ths->mv);
00438   RSWAP(ths->r_iter, ths->mv->f);
00439 
00440   Y(upd_axpy_double)(ths->r_iter, K(-1.0), ths->y, ths->mv->M_total);
00441 
00442   if((!(ths->flags & LANDWEBER)) || (ths->flags & NORMS_FOR_LANDWEBER))
00443     {
00444       if(ths->flags & PRECOMPUTE_WEIGHT)
00445   ths->dot_r_iter = Y(dot_w_double)(ths->r_iter, ths->w,
00446                ths->mv->M_total);
00447       else
00448   ths->dot_r_iter = Y(dot_double)(ths->r_iter, ths->mv->M_total);
00449     }
00450 
00451   /*-----------------*/
00452   if(ths->flags & PRECOMPUTE_WEIGHT)
00453     Y(cp_w_double)(ths->mv->f, ths->w, ths->r_iter, ths->mv->M_total);
00454   else
00455     Y(cp_double)(ths->mv->f, ths->r_iter, ths->mv->M_total);
00456 
00457   RSWAP(ths->z_hat_iter, ths->mv->f_hat);
00458   ths->mv->mv_adjoint(ths->mv);
00459   RSWAP(ths->z_hat_iter, ths->mv->f_hat);
00460 
00461   if((!(ths->flags & LANDWEBER)) || (ths->flags & NORMS_FOR_LANDWEBER))
00462     {
00463       if(ths->flags & PRECOMPUTE_DAMP)
00464   ths->dot_z_hat_iter = Y(dot_w_double)(ths->z_hat_iter, ths->w_hat,
00465              ths->mv->N_total);
00466       else
00467   ths->dot_z_hat_iter = Y(dot_double)(ths->z_hat_iter,
00468                  ths->mv->N_total);
00469     }
00470 
00471   if(ths->flags & CGNE)
00472     ths->dot_p_hat_iter = ths->dot_z_hat_iter;
00473 
00474   if(ths->flags & CGNR)
00475     Y(cp_double)(ths->p_hat_iter, ths->z_hat_iter, ths->mv->N_total);
00476 } /* void solver_before_loop */
00477 
00479 static void solver_loop_one_step_landweber_double(X(plan_double)* ths)
00480 {
00481   if(ths->flags & PRECOMPUTE_DAMP)
00482     Y(upd_xpawy_double)(ths->f_hat_iter, ths->alpha_iter, ths->w_hat,
00483          ths->z_hat_iter, ths->mv->N_total);
00484   else
00485     Y(upd_xpay_double)(ths->f_hat_iter, ths->alpha_iter, ths->z_hat_iter,
00486         ths->mv->N_total);
00487 
00488   /*-----------------*/
00489   Y(cp_double)(ths->mv->f_hat, ths->f_hat_iter, ths->mv->N_total);
00490 
00491   RSWAP(ths->r_iter,ths->mv->f);
00492   ths->mv->mv_trafo(ths->mv);
00493   RSWAP(ths->r_iter,ths->mv->f);
00494 
00495   Y(upd_axpy_double)(ths->r_iter, K(-1.0), ths->y, ths->mv->M_total);
00496 
00497   if(ths->flags & NORMS_FOR_LANDWEBER)
00498     {
00499       if(ths->flags & PRECOMPUTE_WEIGHT)
00500   ths->dot_r_iter = Y(dot_w_double)(ths->r_iter,ths->w,
00501                ths->mv->M_total);
00502       else
00503   ths->dot_r_iter = Y(dot_double)(ths->r_iter, ths->mv->M_total);
00504     }
00505 
00506   /*-----------------*/
00507   if(ths->flags & PRECOMPUTE_WEIGHT)
00508     Y(cp_w_double)(ths->mv->f, ths->w, ths->r_iter, ths->mv->M_total);
00509   else
00510     Y(cp_double)(ths->mv->f, ths->r_iter, ths->mv->M_total);
00511 
00512   RSWAP(ths->z_hat_iter,ths->mv->f_hat);
00513   ths->mv->mv_adjoint(ths->mv);
00514   RSWAP(ths->z_hat_iter,ths->mv->f_hat);
00515 
00516   if(ths->flags & NORMS_FOR_LANDWEBER)
00517     {
00518       if(ths->flags & PRECOMPUTE_DAMP)
00519   ths->dot_z_hat_iter = Y(dot_w_double)(ths->z_hat_iter, ths->w_hat,
00520              ths->mv->N_total);
00521       else
00522   ths->dot_z_hat_iter = Y(dot_double)(ths->z_hat_iter,
00523                  ths->mv->N_total);
00524     }
00525 } /* void solver_loop_one_step_landweber */
00526 
00528 static void solver_loop_one_step_steepest_descent_double(X(plan_double) *ths)
00529 {
00530   if(ths->flags & PRECOMPUTE_DAMP)
00531     Y(cp_w_double)(ths->mv->f_hat, ths->w_hat, ths->z_hat_iter,
00532           ths->mv->N_total);
00533   else
00534     Y(cp_double)(ths->mv->f_hat, ths->z_hat_iter, ths->mv->N_total);
00535 
00536   RSWAP(ths->v_iter,ths->mv->f);
00537   ths->mv->mv_trafo(ths->mv);
00538   RSWAP(ths->v_iter,ths->mv->f);
00539 
00540   if(ths->flags & PRECOMPUTE_WEIGHT)
00541     ths->dot_v_iter = Y(dot_w_double)(ths->v_iter,ths->w,ths->mv->M_total);
00542   else
00543     ths->dot_v_iter = Y(dot_double)(ths->v_iter, ths->mv->M_total);
00544 
00545   /*-----------------*/
00546   ths->alpha_iter = ths->dot_z_hat_iter / ths->dot_v_iter;
00547 
00548   /*-----------------*/
00549   if(ths->flags & PRECOMPUTE_DAMP)
00550     Y(upd_xpawy_double)(ths->f_hat_iter, ths->alpha_iter, ths->w_hat,
00551          ths->z_hat_iter, ths->mv->N_total);
00552   else
00553     Y(upd_xpay_double)(ths->f_hat_iter, ths->alpha_iter, ths->z_hat_iter,
00554         ths->mv->N_total);
00555 
00556   /*-----------------*/
00557   Y(upd_xpay_double)(ths->r_iter, -ths->alpha_iter, ths->v_iter,
00558       ths->mv->M_total);
00559 
00560   if(ths->flags & PRECOMPUTE_WEIGHT)
00561     ths->dot_r_iter = Y(dot_w_double)(ths->r_iter,ths->w,ths->mv->M_total);
00562   else
00563     ths->dot_r_iter = Y(dot_double)(ths->r_iter, ths->mv->M_total);
00564 
00565   /*-----------------*/
00566   if(ths->flags & PRECOMPUTE_WEIGHT)
00567     Y(cp_w_double)(ths->mv->f, ths->w, ths->r_iter, ths->mv->M_total);
00568   else
00569     Y(cp_double)(ths->mv->f, ths->r_iter, ths->mv->M_total);
00570 
00571   RSWAP(ths->z_hat_iter,ths->mv->f_hat);
00572   ths->mv->mv_adjoint(ths->mv);
00573   RSWAP(ths->z_hat_iter,ths->mv->f_hat);
00574 
00575   if(ths->flags & PRECOMPUTE_DAMP)
00576     ths->dot_z_hat_iter = Y(dot_w_double)(ths->z_hat_iter, ths->w_hat,
00577                ths->mv->N_total);
00578   else
00579     ths->dot_z_hat_iter = Y(dot_double)(ths->z_hat_iter, ths->mv->N_total);
00580 } /* void solver_loop_one_step_steepest_descent */
00581 
00583 static void solver_loop_one_step_cgnr_double(X(plan_double) *ths)
00584 {
00585   if(ths->flags & PRECOMPUTE_DAMP)
00586     Y(cp_w_double)(ths->mv->f_hat, ths->w_hat, ths->p_hat_iter,
00587           ths->mv->N_total);
00588   else
00589     Y(cp_double)(ths->mv->f_hat, ths->p_hat_iter, ths->mv->N_total);
00590 
00591   RSWAP(ths->v_iter,ths->mv->f);
00592   ths->mv->mv_trafo(ths->mv);
00593   RSWAP(ths->v_iter,ths->mv->f);
00594 
00595   if(ths->flags & PRECOMPUTE_WEIGHT)
00596     ths->dot_v_iter = Y(dot_w_double)(ths->v_iter,ths->w,ths->mv->M_total);
00597   else
00598     ths->dot_v_iter = Y(dot_double)(ths->v_iter, ths->mv->M_total);
00599 
00600   /*-----------------*/
00601   ths->alpha_iter = ths->dot_z_hat_iter / ths->dot_v_iter;
00602 
00603   /*-----------------*/
00604   if(ths->flags & PRECOMPUTE_DAMP)
00605     Y(upd_xpawy_double)(ths->f_hat_iter, ths->alpha_iter, ths->w_hat,
00606          ths->p_hat_iter, ths->mv->N_total);
00607   else
00608     Y(upd_xpay_double)(ths->f_hat_iter, ths->alpha_iter, ths->p_hat_iter,
00609         ths->mv->N_total);
00610 
00611   /*-----------------*/
00612   Y(upd_xpay_double)(ths->r_iter, -ths->alpha_iter, ths->v_iter,
00613       ths->mv->M_total);
00614 
00615   if(ths->flags & PRECOMPUTE_WEIGHT)
00616     ths->dot_r_iter = Y(dot_w_double)(ths->r_iter,ths->w,ths->mv->M_total);
00617   else
00618     ths->dot_r_iter = Y(dot_double)(ths->r_iter, ths->mv->M_total);
00619 
00620   /*-----------------*/
00621   if(ths->flags & PRECOMPUTE_WEIGHT)
00622     Y(cp_w_double)(ths->mv->f, ths->w, ths->r_iter, ths->mv->M_total);
00623   else
00624     Y(cp_double)(ths->mv->f, ths->r_iter, ths->mv->M_total);
00625 
00626   RSWAP(ths->z_hat_iter,ths->mv->f_hat);
00627   ths->mv->mv_adjoint(ths->mv);
00628   RSWAP(ths->z_hat_iter,ths->mv->f_hat);
00629 
00630   ths->dot_z_hat_iter_old = ths->dot_z_hat_iter;
00631   if(ths->flags & PRECOMPUTE_DAMP)
00632     ths->dot_z_hat_iter = Y(dot_w_double)(ths->z_hat_iter, ths->w_hat,
00633                ths->mv->N_total);
00634   else
00635     ths->dot_z_hat_iter = Y(dot_double)(ths->z_hat_iter, ths->mv->N_total);
00636 
00637   /*-----------------*/
00638   ths->beta_iter = ths->dot_z_hat_iter / ths->dot_z_hat_iter_old;
00639 
00640   /*-----------------*/
00641   Y(upd_axpy_double)(ths->p_hat_iter, ths->beta_iter, ths->z_hat_iter,
00642       ths->mv->N_total);
00643 } /* void solver_loop_one_step_cgnr */
00644 
00646 static void solver_loop_one_step_cgne_double(X(plan_double) *ths)
00647 {
00648   ths->alpha_iter = ths->dot_r_iter / ths->dot_p_hat_iter;
00649 
00650   /*-----------------*/
00651   if(ths->flags & PRECOMPUTE_DAMP)
00652     Y(upd_xpawy_double)(ths->f_hat_iter, ths->alpha_iter, ths->w_hat,
00653          ths->p_hat_iter, ths->mv->N_total);
00654   else
00655     Y(upd_xpay_double)(ths->f_hat_iter, ths->alpha_iter, ths->p_hat_iter,
00656                           ths->mv->N_total);
00657 
00658   /*-----------------*/
00659   if(ths->flags & PRECOMPUTE_DAMP)
00660     Y(cp_w_double)(ths->mv->f_hat, ths->w_hat, ths->p_hat_iter,
00661           ths->mv->N_total);
00662   else
00663     Y(cp_double)(ths->mv->f_hat, ths->p_hat_iter, ths->mv->N_total);
00664 
00665   ths->mv->mv_trafo(ths->mv);
00666 
00667   Y(upd_xpay_double)(ths->r_iter, -ths->alpha_iter, ths->mv->f,
00668       ths->mv->M_total);
00669 
00670   ths->dot_r_iter_old = ths->dot_r_iter;
00671   if(ths->flags & PRECOMPUTE_WEIGHT)
00672     ths->dot_r_iter = Y(dot_w_double)(ths->r_iter,ths->w,ths->mv->M_total);
00673   else
00674     ths->dot_r_iter = Y(dot_double)(ths->r_iter, ths->mv->M_total);
00675 
00676   /*-----------------*/
00677   ths->beta_iter = ths->dot_r_iter / ths->dot_r_iter_old;
00678 
00679   /*-----------------*/
00680   if(ths->flags & PRECOMPUTE_WEIGHT)
00681     Y(cp_w_double)(ths->mv->f, ths->w, ths->r_iter, ths->mv->M_total);
00682   else
00683     Y(cp_double)(ths->mv->f, ths->r_iter, ths->mv->M_total);
00684 
00685   ths->mv->mv_adjoint(ths->mv);
00686 
00687   Y(upd_axpy_double)(ths->p_hat_iter, ths->beta_iter, ths->mv->f_hat,
00688       ths->mv->N_total);
00689 
00690   if(ths->flags & PRECOMPUTE_DAMP)
00691     ths->dot_p_hat_iter = Y(dot_w_double)(ths->p_hat_iter, ths->w_hat,
00692                ths->mv->N_total);
00693   else
00694     ths->dot_p_hat_iter = Y(dot_double)(ths->p_hat_iter, ths->mv->N_total);
00695 } /* void solver_loop_one_step_cgne */
00696 
00698 void X(loop_one_step_double)(X(plan_double) *ths)
00699 {
00700   if(ths->flags & LANDWEBER)
00701     solver_loop_one_step_landweber_double(ths);
00702 
00703   if(ths->flags & STEEPEST_DESCENT)
00704     solver_loop_one_step_steepest_descent_double(ths);
00705 
00706   if(ths->flags & CGNR)
00707     solver_loop_one_step_cgnr_double(ths);
00708 
00709   if(ths->flags & CGNE)
00710     solver_loop_one_step_cgne_double(ths);
00711 } /* void solver_loop_one_step */
00712 
00714 void X(finalize_double)(X(plan_double) *ths)
00715 {
00716   if(ths->flags & PRECOMPUTE_WEIGHT)
00717     Y(free)(ths->w);
00718 
00719   if(ths->flags & PRECOMPUTE_DAMP)
00720     Y(free)(ths->w_hat);
00721 
00722   if(ths->flags & CGNR)
00723     {
00724       Y(free)(ths->v_iter);
00725       Y(free)(ths->z_hat_iter);
00726     }
00727 
00728   if(ths->flags & STEEPEST_DESCENT)
00729     Y(free)(ths->v_iter);
00730 
00731   Y(free)(ths->p_hat_iter);
00732   Y(free)(ths->f_hat_iter);
00733 
00734   Y(free)(ths->r_iter);
00735   Y(free)(ths->y);
00736 }