STIR  6.2.0
Public Member Functions | Static Public Attributes | Protected Member Functions | Protected Attributes | List of all members

A class in the GeneralisedPrior hierarchy. This implements a Relative Difference prior. More...

#include "stir/recon_buildblock/RelativeDifferencePrior.h"

Inheritance diagram for stir::RelativeDifferencePrior< elemT >:
Inheritance graph
[legend]

Public Member Functions

 RelativeDifferencePrior ()
 Default constructor.
 
 RelativeDifferencePrior (const bool only_2D, float penalization_factor, float gamma, float epsilon)
 Constructs it explicitly.
 
double compute_value (const DiscretisedDensity< 3, elemT > &current_image_estimate) override
 compute the value of the function
 
void compute_gradient (DiscretisedDensity< 3, elemT > &prior_gradient, const DiscretisedDensity< 3, elemT > &current_image_estimate) override
 compute gradient
 
void compute_Hessian (DiscretisedDensity< 3, elemT > &prior_Hessian_for_single_densel, const BasicCoordinate< 3, int > &coords, const DiscretisedDensity< 3, elemT > &current_image_estimate) const override
 
void add_multiplication_with_approximate_Hessian (DiscretisedDensity< 3, elemT > &output, const DiscretisedDensity< 3, elemT > &input) const override
 
void accumulate_Hessian_times_input (DiscretisedDensity< 3, elemT > &output, const DiscretisedDensity< 3, elemT > &current_estimate, const DiscretisedDensity< 3, elemT > &input) const override
 Compute the multiplication of the hessian of the prior multiplied by the input.
 
float get_gamma () const
 get the gamma value used in RDP
 
void set_gamma (float e)
 set the gamma value used in the RDP
 
float get_epsilon () const
 get the epsilon value used in RDP
 
void set_epsilon (float e)
 set the epsilon value used in the RDP
 
Array< 3, float > get_weights () const
 get penalty weights for the neigbourhood More...
 
void set_weights (const Array< 3, float > &)
 set penalty weights for the neigbourhood More...
 
shared_ptr< DiscretisedDensity< 3, elemT > > get_kappa_sptr () const
 get current kappa image More...
 
void set_kappa_sptr (const shared_ptr< DiscretisedDensity< 3, elemT >> &)
 set kappa image
 
virtual Succeeded set_up (shared_ptr< const DiscretisedDensity< 3, elemT >> const &target_sptr) override
 Has to be called before using this object.
 
bool is_convex () const override
 Indicates if the prior is a smooth convex function. More...
 
template<>
const char *const registered_name
 
- Public Member Functions inherited from stir::RegisteredParsingObject< RelativeDifferencePrior< elemT >, GeneralisedPrior< DiscretisedDensity< 3, elemT > >, GeneralisedPrior< DiscretisedDensity< 3, elemT > > >
std::string get_registered_name () const override
 Returns Derived::registered_name.
 
std::string parameter_info () override
 Returns a string with all parameters and their values, in a form suitable for parsing again.
 
- Public Member Functions inherited from stir::GeneralisedPrior< DiscretisedDensity< 3, elemT > >
virtual void compute_Hessian (DiscretisedDensity< 3, elemT > &prior_Hessian_for_single_densel, const BasicCoordinate< 3, int > &coords, const DiscretisedDensity< 3, elemT > &current_image_estimate) const
 This computes a single row of the Hessian. More...
 
virtual void add_multiplication_with_approximate_Hessian (DiscretisedDensity< 3, elemT > &output, const DiscretisedDensity< 3, elemT > &input) const
 This should compute the multiplication of the Hessian with a vector and add it to output. More...
 
virtual void accumulate_Hessian_times_input (DiscretisedDensity< 3, elemT > &output, const DiscretisedDensity< 3, elemT > &current_estimate, const DiscretisedDensity< 3, elemT > &input) const
 This should compute the multiplication of the Hessian with a vector and add it to output. More...
 
float get_penalisation_factor () const
 
void set_penalisation_factor (float new_penalisation_factor)
 
virtual Succeeded set_up (shared_ptr< const DiscretisedDensity< 3, elemT > > const &target_sptr)
 Has to be called before using this object.
 
- Public Member Functions inherited from stir::ParsingObject
 ParsingObject (const ParsingObject &)
 
ParsingObjectoperator= (const ParsingObject &)
 
void ask_parameters ()
 
bool parse (std::istream &f)
 
bool parse (const char *const filename)
 

Static Public Attributes

static const char *const registered_name
 Name which will be used when parsing a GeneralisedPrior object.
 

Protected Member Functions

void check (DiscretisedDensity< 3, elemT > const &current_image_estimate) const override
 Check that the prior is ready to be used.
 
void set_defaults () override
 Set defaults before parsing.
 
void initialise_keymap () override
 Initialise all keywords.
 
bool post_processing () override
 This will be called at the end of the parsing. More...
 
double value (const elemT x_j, const elemT x_k) const
 The value and partial derivatives of the Relative Difference Prior. More...
 
elemT derivative_10 (const elemT x, const elemT y) const
 
elemT derivative_20 (const elemT x_j, const elemT x_k) const
 
elemT derivative_11 (const elemT x_j, const elemT x_k) const
 
- Protected Member Functions inherited from stir::GeneralisedPrior< DiscretisedDensity< 3, elemT > >
void set_defaults () override
 sets value for penalisation factor More...
 
void initialise_keymap () override
 sets key for penalisation factor More...
 
virtual void check (DiscretisedDensity< 3, elemT > const &current_estimate) const
 Check that the prior is ready to be used.
 
- Protected Member Functions inherited from stir::ParsingObject
virtual void set_key_values ()
 This will be called before parsing or parameter_info is called. More...
 

Protected Attributes

float gamma
 Create variable gamma for Relative Difference Penalty.
 
float epsilon
 Create variable epsilon for Relative Difference Penalty.
 
bool only_2D
 can be set during parsing to restrict the weights to the 2D case
 
std::string gradient_filename_prefix
 filename prefix for outputing the gradient whenever compute_gradient() is called. More...
 
Array< 3, float > weights
 penalty weights More...
 
std::string kappa_filename
 Filename for the $\kappa$ image that will be read by post_processing()
 
shared_ptr< DiscretisedDensity< 3, elemT > > kappa_ptr
 
- Protected Attributes inherited from stir::GeneralisedPrior< DiscretisedDensity< 3, elemT > >
float penalisation_factor
 
bool _already_set_up
 
- Protected Attributes inherited from stir::ParsingObject
KeyParser parser
 

Additional Inherited Members

- Static Public Member Functions inherited from stir::RegisteredParsingObject< RelativeDifferencePrior< elemT >, GeneralisedPrior< DiscretisedDensity< 3, elemT > >, GeneralisedPrior< DiscretisedDensity< 3, elemT > > >
static GeneralisedPrior< DiscretisedDensity< 3, elemT > > * read_from_stream (std::istream *)
 Construct a new object (of type Derived) by parsing the istream. More...
 
- Static Public Member Functions inherited from stir::RegisteredObject< GeneralisedPrior< DiscretisedDensity< 3, elemT > > >
static GeneralisedPrior< DiscretisedDensity< 3, elemT > > * read_registered_object (std::istream *in, const std::string &registered_name)
 Construct a new object (of a type derived from Root, its actual type determined by the registered_name parameter) by parsing the istream. More...
 
static GeneralisedPrior< DiscretisedDensity< 3, elemT > > * ask_type_and_parameters ()
 ask the user for the type, and then calls read_registered_object(0, type) More...
 
static void list_registered_names (std::ostream &stream)
 List all possible registered names to the stream. More...
 
- Protected Types inherited from stir::RegisteredObject< GeneralisedPrior< DiscretisedDensity< 3, elemT > > >
typedef GeneralisedPrior< DiscretisedDensity< 3, elemT > > *(* RootFactory) (std::istream *)
 The type of a root factory is a function, taking an istream* as argument, and returning a Root*.
 
typedef FactoryRegistry< std::string, RootFactory, interfile_lessRegistryType
 The type of the registry.
 
- Static Protected Member Functions inherited from stir::RegisteredObject< GeneralisedPrior< DiscretisedDensity< 3, elemT > > >
static RegistryTyperegistry ()
 Static function returning the registry. More...
 

Detailed Description

template<typename elemT>
class stir::RelativeDifferencePrior< elemT >

A class in the GeneralisedPrior hierarchy. This implements a Relative Difference prior.

The value of the prior is computed as follows:

\[ f= \sum_{r,dr} \frac{w_{dr}}{2} \frac{(\lambda_r - \lambda_{r+dr})^2}{(\lambda_r+ \lambda_{r+dr} + \gamma |\lambda_r - \lambda_{r+dr}| + \epsilon)} * \kappa_r * \kappa_{r+dr} \]

where $\lambda$ is the image and $r$ and $dr$ are indices and the sum is over the neighbourhood where the weights $w_{dr}$ are non-zero. $\gamma$ is a smoothing scalar term and the $\epsilon$ is a small non-negative value included to prevent division by zero. Please note that the RDP is only well defined for non-negative voxel values. For more details, see: J. Nuyts, D. Beque, P. Dupont, and L. Mortelmans, "A Concave Prior Penalizing Relative Differences for Maximum-a-Posteriori Reconstruction in Emission Tomography," vol. 49, no. 1, pp. 56-60, 2002.

If $ \epsilon=0 $, we attempt to resolve 0/0 at $ \lambda_r = \lambda_{r+dr}=0 $ by using the limit. Note that the Hessian explodes to infinity when both voxel values approach 0, and we currently return INFINITY. Also, as the RDP is not differentiable at this point, we have chosen to return 0 for the gradient (such that a zero background is not modified).

Warning
the default value for $ \epsilon $ is zero, which can be problematic for gradient-based algorithms.

The $\kappa$ image can be used to have spatially-varying penalties such as in Jeff Fessler's papers. It should have identical dimensions to the image for which the penalty is computed. If $\kappa$ is not set, this class will effectively use 1 for all $\kappa$'s.

By default, a 3x3 or 3x3x3 neighbourhood is used where the weights are set to x-voxel_size divided by the Euclidean distance between the points.

The prior computation excludes voxel-pairs where one voxel is outside the volume. This is effectively the same as extending the volume by replicating the edges (which is different from zero boundary conditions).

Parsing
These are the keywords that can be used in addition to the ones in GeneralPrior.
  Relative Difference Prior Parameters:=
  ; next defaults to 0, set to 1 for 2D inverse Euclidean weights, 0 for 3D
  only 2D:= 0
  ; next can be used to set weights explicitly. Needs to be a 3D array (of floats).
  ' value of only_2D is ignored
  ; following example uses 2D 'nearest neighbour' penalty
  ; weights:={{{0,1,0},{1,0,1},{0,1,0}}}
  ; gamma value :=
  ; epsilon value :=
  ; see class documentation for more info
  ; use next parameter to specify an image with penalisation factors (a la Fessler)
  ; kappa filename:=
  ; use next parameter to get gradient images at every subiteration
  ; see class documentation
  gradient filename prefix:=
  END Relative Difference Prior Parameters:=

Member Function Documentation

◆ get_weights()

template<typename elemT >
Array< 3, float > stir::RelativeDifferencePrior< elemT >::get_weights ( ) const

get penalty weights for the neigbourhood

get penalty weights for the neighbourhood

References stir::RelativeDifferencePrior< elemT >::weights.

Referenced by stir::RelativeDifferencePriorTests< RDP >::run_tests().

◆ set_weights()

template<typename elemT >
void stir::RelativeDifferencePrior< elemT >::set_weights ( const Array< 3, float > &  w)

set penalty weights for the neigbourhood

set penalty weights for the neighbourhood

References stir::RelativeDifferencePrior< elemT >::weights.

Referenced by stir::RelativeDifferencePriorTests< RDP >::run_tests().

◆ get_kappa_sptr()

template<typename elemT >
shared_ptr< DiscretisedDensity< 3, elemT > > stir::RelativeDifferencePrior< elemT >::get_kappa_sptr ( ) const

get current kappa image

Warning
As this function returns a shared_ptr, this is dangerous. You should not modify the image by manipulating the image refered to by this pointer. Unpredictable results will occur.
As this function returns a shared_ptr, this is dangerous. You should not modify the image by manipulating the image referred to by this pointer. Unpredictable results will occur.

Referenced by stir::RelativeDifferencePriorTests< RDP >::run_tests().

◆ is_convex()

template<typename elemT >
bool stir::RelativeDifferencePrior< elemT >::is_convex ( ) const
overridevirtual

Indicates if the prior is a smooth convex function.

If true, the prior is expected to have 0th, 1st and 2nd order behaviour implemented.

Implements stir::GeneralisedPrior< DiscretisedDensity< 3, elemT > >.

◆ post_processing()

template<typename elemT >
bool stir::RelativeDifferencePrior< elemT >::post_processing ( )
overrideprotectedvirtual

This will be called at the end of the parsing.

Returns
false if everything OK, true if not

Reimplemented from stir::ParsingObject.

References stir::read_from_file(), and stir::warning().

◆ value()

template<typename elemT >
double stir::RelativeDifferencePrior< elemT >::value ( const elemT  x_j,
const elemT  x_k 
) const
protected

The value and partial derivatives of the Relative Difference Prior.

value refers to its value derivative_10 refers to the derivative w.r.t. x_j only derivative_20 refers to the second derivative w.r.t. x_j only (i.e. diagonal elements of the Hessian) derivative_11 refers to the second derivative w.r.t. x_j and x_k (i.e. off-diagonal elements of the Hessian)

See J. Nuyts, et al., 2002, Equation 7 etc, but here an epsilon is added.

In the instance x_j, x_k and epsilon equal 0.0, these functions get ill-defined due to 0/0 computations. We currently return 0 for the value, 0 for derivative_10, and INFINITY for the second order derivatives. These follow by taking the limit, i.e. by assuming continuity. Note however that when epsilon=0, derivative_10(x,0) limits to $ 1/(1+\gamma) $, while derivative_10(x,x) limits to $ 0 $.

Parameters
x_jis the target voxel.
x_kis the voxel in the neighbourhood.
Returns
the second order partial derivatives of the Relative Difference Prior

References stir::RelativeDifferencePrior< elemT >::gamma, and stir::square().

Referenced by stir::RelativeDifferencePrior< elemT >::compute_value().

Member Data Documentation

◆ gradient_filename_prefix

template<typename elemT>
std::string stir::RelativeDifferencePrior< elemT >::gradient_filename_prefix
protected

filename prefix for outputing the gradient whenever compute_gradient() is called.

An internal counter is used to keep track of the number of times the gradient is computed. The filename will be constructed by concatenating gradient_filename_prefix and the counter.

Referenced by stir::RelativeDifferencePrior< elemT >::compute_gradient().

◆ weights

template<typename elemT>
Array<3, float> stir::RelativeDifferencePrior< elemT >::weights
mutableprotected

penalty weights

Todo:
This member is mutable at present because some const functions initialise it. That initialisation should be moved to a new set_up() function.

Referenced by stir::RelativeDifferencePrior< elemT >::get_weights(), stir::RelativeDifferencePrior< elemT >::set_kappa_sptr(), and stir::RelativeDifferencePrior< elemT >::set_weights().


The documentation for this class was generated from the following files: