#ifndef __COCO_VTV_H
#define __COCO_VTV_H
#include <map>
#include <vector>
#include <assert.h>
#include <gsl/gsl_matrix.h>
#include "../cuda/cuda_interface.h"
#include "../defs.h"
#include "../modules.h"
using namespace std;
namespace coco {
/*** CORE PDE METHODS ***/
struct coco_vtv_workspace;
// Helper structure to set all parameters
struct coco_vtv_data
{
// Field size
size_t _W;
size_t _H;
size_t _N;
// Number of channels
size_t _nchannels;
// Smoothness parameter
double _lambda;
// Step sizes (primal/dual)
double _tau;
double _sigma;
// Step sizes (fista)
double _alpha;
// Lipschitz constant
double _L;
// Uniform convexity constant
double _gamma;
// Regularizer
// 0: TV_S
// 1: TV_F
// 2: TV_J
size_t _regularizer;
// Data term regularizer
// 1: L^1 - norm
// 2: L^2 - norm
// Works only together with Arrow-Hurwicz or Chambolle-Pock,
// and with general inverse problem
size_t _data_term_p;
// Number of bytes per image double layer
size_t _nfbytes;
// Workspace data
coco_vtv_workspace* _workspace;
};
// Alloc PDE data with sensible defaults
coco_vtv_data* coco_vtv_alloc( size_t nchannels,
vector<gsl_matrix*> F );
// Free up PDE data
bool coco_vtv_free( coco_vtv_data *data );
// Initialize workspace with current solution
bool coco_vtv_initialize( coco_vtv_data *data,
vector<gsl_matrix*> &U );
// Get current solution
bool coco_vtv_get_solution( coco_vtv_data *data,
vector<gsl_matrix*> &U );
// Get dual variable XI (vector of dimension 2)
bool coco_vtv_get_dual_xi( coco_vtv_data *data,
vector<gsl_matrix*> &XI,
size_t channel=0 );
// Get dual variable ETA (vector of dimension equal to channel number)
bool coco_vtv_get_dual_eta( coco_vtv_data *data,
vector<gsl_matrix*> &ETA );
/*****************************************************************************
TV_x ROF
*****************************************************************************/
// Compute primal energy
double coco_vtv_rof_primal_energy( coco_vtv_data *data );
// *** MTV-ROF base algorithms ***
// Perform one iteration of Bermudez-Morena scheme
bool coco_vtv_rof_iteration_bermudez_morena( coco_vtv_data *data );
// Perform one iteration of Arrow-Hurwicz scheme
bool coco_vtv_rof_iteration_arrow_hurwicz( coco_vtv_data *data );
// Perform one iteration of Algorithm 1, Chambolle-Pock
bool coco_vtv_rof_iteration_chambolle_pock_1( coco_vtv_data *data );
// Perform one iteration of Algorithm 2, Chambolle-Pock
bool coco_vtv_rof_iteration_chambolle_pock_2( coco_vtv_data *data );
// Perform one iteration of FISTA
bool coco_vtv_rof_iteration_fista( coco_vtv_data *data );
/*****************************************************************************
TV_x Deblurring
*****************************************************************************/
// Init kernel
bool coco_vtv_set_separable_kernel( coco_vtv_data *data, gsl_vector *kernel );
bool coco_vtv_set_kernel( coco_vtv_data *data, gsl_matrix *kernel );
// Compute primal energy
double coco_vtv_deblurring_primal_energy( coco_vtv_data *data );
// Perform one primal step (several iterations of gradient descent for the prox operator)
bool coco_vtv_deblurring_primal_step( coco_vtv_data *data );
// Perform one primal step (several iterations of gradient descent for the prox operator)
bool coco_vtv_deblurring_dual_step( coco_vtv_data *data );
// Single primal descent step (using functional gradient only)
bool coco_vtv_deblurring_primal_descent_step( coco_vtv_data *data );
// Perform one iteration of Algorithm 1, Chambolle-Pock
bool coco_vtv_deblurring_iteration_chambolle_pock_1( coco_vtv_data *data );
// Perform one iteration of Algorithm 2, Chambolle-Pock
bool coco_vtv_deblurring_iteration_chambolle_pock_2( coco_vtv_data *data );
// Perform one iteration of Arrow-Hurwicz
bool coco_vtv_deblurring_iteration_arrow_hurwicz( coco_vtv_data *data );
// Perform one single shrinkage step (ISTA)
bool coco_vtv_deblurring_ista_step( coco_vtv_data *data );
// Perform one full iteration of FISTA
bool coco_vtv_deblurring_iteration_fista( coco_vtv_data *data );
/*****************************************************************************
TV_x Inpainting
*****************************************************************************/
// Init inpainting stencil
bool coco_vtv_set_stencil( coco_vtv_data *data, gsl_matrix *stencil );
// Compute primal energy
double coco_vtv_inpainting_primal_energy( coco_vtv_data *data );
// Perform one single shrinkage step (ISTA)
bool coco_vtv_inpainting_ista_step( coco_vtv_data *data );
// Perform one full iteration of FISTA
bool coco_vtv_inpainting_iteration_fista( coco_vtv_data *data );
}
#endif