STIR  6.3.0
GibbsRelativeDifferencePenalty.h
Go to the documentation of this file.
1 //
2 //
3 /*
4  Copyright (C) 2019 -2025, University College London
5  Copyright (C) 2025, University of Milano-Bicocca
6  This file is part of STIR.
7 
8  SPDX-License-Identifier: Apache-2.0
9 
10  See STIR/LICENSE.txt for details
11 */
25 #ifndef __stir_recon_buildblock_GibbsRelativeDifferencePenalty_H__
26 #define __stir_recon_buildblock_GibbsRelativeDifferencePenalty_H__
27 
30 #include <cmath>
31 #include "stir/cuda_utilities.h"
32 
33 #ifdef STIR_WITH_CUDA
35 #endif
36 
37 START_NAMESPACE_STIR
38 
61 template <typename elemT>
63 {
64 public:
65  float gamma;
66  float epsilon;
68  __host__ __device__ inline double value(const elemT val_center, const elemT val_neigh, int z, int y, int x) const
69  {
70  // Implemented formula:
71  // return 0.5 * (val_center -val_neigh)**2 / (val_center +val_neigh + gamma * |val_center - val_neigh| + epsilon);
72  const elemT diff = val_center - val_neigh;
73  const elemT add = val_center + val_neigh;
74  const elemT NUM = 0.5 * (diff * diff);
75  const elemT DEN = 1.0 / (add + gamma * fabs(diff) + epsilon);
76 
77  return NUM * DEN;
78  }
79 
81  __host__ __device__ inline double derivative_10(const elemT val_center, const elemT val_neigh, int z, int y, int x) const
82  {
83  // Implemented formula:
84  // return 0.5 * (val_center-val_neigh) * (val_center + 3*val_neigh + gamma * |val_center - val_neigh| + 2 * epsilon ) /
85  // ((val_center +val_neigh)+ gamma * |val_center - val_neigh| + epsilon)**2;
86  const elemT diff = val_center - val_neigh;
87  const elemT factor = val_center + val_neigh + gamma * fabs(diff) + epsilon;
88  const elemT NUM = 0.5 * diff * (factor + 2 * val_neigh + epsilon);
89  const elemT DEN = 1.0 / (factor * factor);
90 
91  return NUM * DEN;
92  }
93 
95  __host__ __device__ inline double derivative_20(const elemT val_center, const elemT val_neigh, int z, int y, int x) const
96  {
97  // Implemented formula:
98  // return (2*val_center + epsilon)**2 / (val_center + val_neigh + gamma * |val_center - val_neigh| + epsilon)**3;
99  const elemT NUM = 2 * val_neigh + epsilon;
100  const elemT DEN = 1.0 / (val_center + val_neigh + gamma * fabs(val_center - val_neigh) + epsilon);
101 
102  return NUM * NUM * DEN * DEN * DEN;
103  }
105  __host__ __device__ inline double derivative_11(const elemT val_center, const elemT val_neigh, int z, int y, int x) const
106  {
107  // Implemented formula:
108  // return -(2*val_center + epsilon)*(2*val_neigh + epsilon)/ (val_center + val_neigh + gamma * |val_center - val_neigh| +
109  // epsilon)**3;
110  const elemT NUM = -(2 * val_center + epsilon) * (2 * val_neigh + epsilon);
111  const elemT DEN = 1.0 / (val_center + val_neigh + gamma * fabs(val_center - val_neigh) + epsilon);
112 
113  return NUM * DEN * DEN * DEN;
114  }
115 
117  static inline bool is_convex() { return true; }
118 
121  {
122  parser.add_key("gamma value", &this->gamma);
123  parser.add_key("epsilon value", &this->epsilon);
124  }
125 
128  {
129  this->gamma = 2;
130  this->epsilon = 1e-7;
131  }
132 };
133 
149 template <typename elemT>
150 class GibbsRelativeDifferencePenalty : public RegisteredParsingObject<GibbsRelativeDifferencePenalty<elemT>,
151  GeneralisedPrior<DiscretisedDensity<3, elemT>>,
152  GibbsPenalty<elemT, RelativeDifferencePotential<elemT>>>
153 {
154 private:
158  base_type;
159 
160 public:
161  GibbsRelativeDifferencePenalty() { this->set_defaults(); }
162  GibbsRelativeDifferencePenalty(const bool only_2D, float penalisation_factor, float gamma_v, float epsilon_v)
163  : base_type(only_2D, penalisation_factor)
164  {
165  this->potential.gamma = gamma_v;
166  this->potential.epsilon = epsilon_v;
167  }
168 
169  static constexpr const char* registered_name = "Gibbs Relative Difference";
170  float get_gamma() const { return this->potential.gamma; }
171  float get_epsilon() const { return this->potential.epsilon; }
172  void set_gamma(float gamma_v) { this->potential.gamma = gamma_v; }
173  void set_epsilon(float epsilon_v) { this->potential.epsilon = epsilon_v; }
174 };
175 
176 #ifdef STIR_WITH_CUDA
177 
191 template <typename elemT>
192 class CudaGibbsRelativeDifferencePenalty
193  : public RegisteredParsingObject<CudaGibbsRelativeDifferencePenalty<elemT>,
194  GeneralisedPrior<DiscretisedDensity<3, elemT>>,
195  CudaGibbsPenalty<elemT, RelativeDifferencePotential<elemT>>>
196 {
197 private:
201  base_type;
202 
203 public:
204  CudaGibbsRelativeDifferencePenalty() { this->set_defaults(); }
205  CudaGibbsRelativeDifferencePenalty(const bool only_2D, float penalisation_factor, float gamma_v, float epsilon_v)
206  : base_type(only_2D, penalisation_factor)
207  {
208  this->potential.gamma = gamma_v;
209  this->potential.epsilon = epsilon_v;
210  }
211 
212  static constexpr const char* registered_name = "Cuda Gibbs Relative Difference";
213  float get_gamma() const { return this->potential.gamma; }
214  float get_epsilon() const { return this->potential.epsilon; }
215  void set_gamma(float gamma_v) { this->potential.gamma = gamma_v; }
216  void set_epsilon(float epsilon_v) { this->potential.epsilon = epsilon_v; }
217 };
218 #endif
219 
220 END_NAMESPACE_STIR
221 
222 #endif
void initialise_keymap(KeyParser &parser)
Method for setting up parsing additional parameters.
Definition: GibbsRelativeDifferencePenalty.h:120
A class to parse Interfile headers.
Definition: KeyParser.h:161
void add_key(const std::string &keyword, float *variable_ptr)
add a keyword. When parsing, parse its value as a float and put it in *variable_ptr ...
Definition: KeyParser.cxx:346
Implementation of the Relative Difference penalty potential.
Definition: GibbsRelativeDifferencePenalty.h:62
Multithreaded CPU Implementation of the Relative Difference penalty.
Definition: GibbsRelativeDifferencePenalty.h:150
A base class with CUDA-accelerated implementation of the GibbsPenalty class.
Definition: CudaGibbsPenalty.h:50
static bool is_convex()
method to indicate whether the the prior defined by this potential is convex
Definition: GibbsRelativeDifferencePenalty.h:117
void set_defaults()
Set default values for potential-specific parameters.
Definition: GibbsRelativeDifferencePenalty.h:127
Declaration of the stir::GibbsPenalty class.
A base class for &#39;generalised&#39; priors, i.e. priors for which at least a &#39;gradient&#39; is defined...
Definition: GeneralisedPrior.h:42
Parent class for all leaves in a RegisteredObject hierarchy that do parsing of parameter files...
Definition: RegisteredParsingObject.h:77
A base class for Gibbs type penalties in the GeneralisedPrior hierarchy.
Definition: GibbsPenalty.h:98
Declaration of the stir::CudaGibbsPenalty class.
some utilities for STIR and CUDA
Declaration of class stir::RegisteredParsingObject.