Enumerations | Functions

TRTK::Diffusion Namespace Reference

This namespace contains various functions regarding diffusion processes. More...

Enumerations

enum  BorderInterpolation {
  CONTINUED, CIRCULAR, INTERPOLATED, REFLECTED,
  ZERO
}
 

Interpolation method for border values.

More...
enum  Error { INVALID_ARGUMENT, UNKNOWN_ERROR }
 

Error Codes.

More...

Functions

template<class T >
void print (const std::vector< T > &data)
template<class T >
const std::vector< T > firstDerivative (const std::vector< T > &signal, const BorderInterpolation interpolation=CONTINUED)
 Computes the 1st derivative of a 1-dimensional signal.
template<class T >
const std::vector< T > secondDerivative (const std::vector< T > &signal, const BorderInterpolation interpolation=CONTINUED)
 Computes the 2nd derivative of a 1-dimensional signal.
template<class T >
const std::vector< T > linearDiffusion (const std::vector< T > &signal, T time, T step_size=0.25, BorderInterpolation interpolation_method=CONTINUED)
 1-dimensional linear diffusion.
template<class T >
const std::vector< T > nonlinearIsotropicDiffusion (const std::vector< T > &signal, T time, T step_size=0.25, T alpha=0.0, BorderInterpolation interpolation_method=CONTINUED)
 1-dimensional nonlinear isotropic diffusion.
template<class T >
const std::vector< T > nonlinearIsotropicDiffusion (const std::vector< T > &signal, T(*diffusivity)(T), T time, T step_size=0.25, BorderInterpolation interpolation_method=CONTINUED)
 1-dimensional nonlinear isotropic diffusion.

Detailed Description

This namespace contains various functions regarding diffusion processes.


Enumeration Type Documentation

Interpolation method for border values.

Enumerator:
CONTINUED 

Values outside the bounds of the data are the same as the nearest valid border values.

CIRCULAR 

Values outside the bounds of the data are computed by implicitly assuming the data is periodic.

INTERPOLATED 

Values outside the bounds of the data are linearly extrapolated from the nearest valid border values.

REFLECTED 

Values outside the bounds of the data are computed by reflecting the data.

ZERO 

Values outside the bounds of the data are assumed to be zero.

Definition at line 59 of file Diffusion.hpp.

Error Codes.

Enumerator:
INVALID_ARGUMENT 

An invalid argument was assigned.

UNKNOWN_ERROR 

An unknown error occurred.

Definition at line 71 of file Diffusion.hpp.


Function Documentation

template<class T >
const std::vector<T> TRTK::Diffusion::firstDerivative ( const std::vector< T > &  signal,
const BorderInterpolation  interpolation = CONTINUED 
)

Computes the 1st derivative of a 1-dimensional signal.

Template Parameters:
Tscalar type (must be a floating point type)
Parameters:
[in]signalinput signal
[in]interpolationinterpolation method for the border values

The derivative is computed by convolving signal with the kernel [0.5 0 -0.5].

Returns:
Derivative of the input signal.
Exceptions:
ErrorObjIf an unknown interpolation method is assigned, an error object is thrown and its error code is set to INVALID_ARGUMENT.

Here ist an example:

 #include <iostream>
 #include <vector>

 #include <TRTK/Diffusion.hpp>

 using namespace TRTK;
 using namespace TRTK::Diffusion;

 void print(const std::vector<double> & data)
 {
     for (unsigned i = 0; i < data.size(); ++i)
     {
         std::cout.precision(2);
         std::cout.width(8);
         std::cout << std::fixed << data[i];
     }
     std::cout << std::endl;
 }

 int main()
 {
     std::vector<double> signal;

     for (unsigned i = 0; i < 10; ++i)
     {
         signal.push_back(0.5 * i);
     }

     print(firstDerivative(signal, CONTINUED));
     print(firstDerivative(signal, INTERPOLATED));
     print(firstDerivative(signal, REFLECTED));
     print(firstDerivative(signal, ZERO));

     signal.clear();

     for (unsigned i = 0; i < 10; ++i)
     {
         signal.push_back(i * i + 3);
     }

     std::cout << std::endl;
     print(firstDerivative(signal, CONTINUED));
     print(firstDerivative(signal, INTERPOLATED));
     print(firstDerivative(signal, REFLECTED));
     print(firstDerivative(signal, ZERO));

     return 0;
 }

Output:

 0.25    0.50    0.50    0.50    0.50    0.50    0.50    0.50    0.50    0.25
 0.50    0.50    0.50    0.50    0.50    0.50    0.50    0.50    0.50    0.50
 0.25    0.50    0.50    0.50    0.50    0.50    0.50    0.50    0.50    0.25
 0.25    0.50    0.50    0.50    0.50    0.50    0.50    0.50    0.50   -2.00

 0.50    2.00    4.00    6.00    8.00   10.00   12.00   14.00   16.00    8.50
 1.00    2.00    4.00    6.00    8.00   10.00   12.00   14.00   16.00   17.00
 0.50    2.00    4.00    6.00    8.00   10.00   12.00   14.00   16.00    8.50
 2.00    2.00    4.00    6.00    8.00   10.00   12.00   14.00   16.00  -33.50
Author:
Christoph Haenisch
Version:
0.1.1
Date:
last changed on 2011-11-17

Definition at line 178 of file Diffusion.hpp.

template<class T >
const std::vector<T> TRTK::Diffusion::linearDiffusion ( const std::vector< T > &  signal,
time,
step_size = 0.25,
BorderInterpolation  interpolation_method = CONTINUED 
)

1-dimensional linear diffusion.

Parameters:
[in]signalinput signal \( f(x, t = 0) \)
[in]timediffusion time \( t_{end} \)
[in]step_sizeshould be less than 0.25 to guarantee stability
[in]interpolation_methodinterpolation method used for the differentiation
Returns:
Returns the diffused signal \( f(x, t = t_{end}) \).

This function computes the diffusion of a given signal \( f(x, t = 0) \) by solving the following diffusion equation:

\[ \frac{d}{dt} f(x, t) = \frac{d^2}{dx^2} f(x, t) \]

Note, that the above diffusion is equivalent to a convolution with a Gaussian kernel with variance \( \sigma = \sqrt{2t_{end}} \).

Here is an example:

 #include <iostream>
 #include <vector>

 #include <TRTK/Diffusion.hpp>

 using namespace TRTK;
 using namespace TRTK::Diffusion;

 template <typename T, int sz>
 char (&array(T(&)[sz]))[sz];

 void print(const std::vector<double> & data)
 {
     for (unsigned i = 0; i < data.size(); ++i)
     {
         std::cout.precision(2);
         std::cout.width(8);
         std::cout << std::fixed << data[i];
     }
     std::cout << std::endl;
 }

 int main()
 {
     double data[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                      1.0, 1.0, 1.0, 1.0, 1.0, 1.0};

     std::vector<double> signal =
             std::vector<double>(data, data + sizeof array(data));

     for (double time = 0; time <= 1; time += 0.25)
     {
         print(linearDiffusion(signal, time, 0.25));
     }

     std::cout << std::endl;
     print(linearDiffusion(signal, 2.0, 0.25, CONTINUED));
     print(linearDiffusion(signal, 2.0, 0.25, INTERPOLATED));
     print(linearDiffusion(signal, 2.0, 0.25, REFLECTED));
     print(linearDiffusion(signal, 2.0, 0.25, ZERO));

     std::cout << std::endl;
     print(linearDiffusion(signal, 1000.0, 0.25, CONTINUED));
     print(linearDiffusion(signal, 1000.0, 0.25, ZERO));

     return 0;
 }

Output:

  0.00    0.00    0.00    0.00    0.00    0.00    1.00    1.00    1.00    1.00    1.00    1.00
  0.00    0.00    0.00    0.00    0.00    0.25    0.75    1.00    1.00    1.00    1.00    1.00
  0.00    0.00    0.00    0.00    0.06    0.31    0.69    0.94    1.00    1.00    1.00    1.00
  0.00    0.00    0.00    0.02    0.11    0.34    0.66    0.89    0.98    1.00    1.00    1.00
  0.00    0.00    0.00    0.04    0.14    0.36    0.64    0.86    0.96    1.00    1.00    1.00

  0.00    0.01    0.04    0.11    0.23    0.40    0.60    0.77    0.89    0.96    0.99    1.00
  0.00    0.01    0.04    0.11    0.23    0.40    0.60    0.77    0.89    0.96    0.99    1.00
  0.00    0.01    0.04    0.11    0.23    0.40    0.60    0.77    0.89    0.96    0.99    1.00
  0.00    0.01    0.04    0.11    0.23    0.40    0.60    0.76    0.85    0.82    0.66    0.37

  0.50    0.50    0.50    0.50    0.50    0.50    0.50    0.50    0.50    0.50    0.50    0.50
  0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00
Note:
An interpolation method of "INTERPOLATED" might invalidate the minimum-maximum principle of this diffusion equation.
References:
Perona and Malik, "Scale-space and edge detection using anisotropic diffusion", Pattern Analysis and Machine Intelligence, 1990
References:
Brox et al., "Nonlinear Structure Tensors", Image and Vision Computing, 2006
Author:
Christoph Haenisch
Version:
0.1.0
Date:
last changed on 2011-06-22

Definition at line 576 of file Diffusion.hpp.

template<class T >
const std::vector<T> TRTK::Diffusion::nonlinearIsotropicDiffusion ( const std::vector< T > &  signal,
time,
step_size = 0.25,
alpha = 0.0,
BorderInterpolation  interpolation_method = CONTINUED 
)

1-dimensional nonlinear isotropic diffusion.

Parameters:
[in]signalinput signal \( f(x, t = 0) \)
[in]timediffusion time \( t_{end} \)
[in]step_sizeshould be less than 0.25 to guarantee stability
[in]alphasteers the diffusion process; should between 0 and 1.5
[in]interpolation_methodinterpolation method used for the differentiation
Returns:
Returns the diffused signal \( f(x, t = t_{end}) \).

This function computes the diffusion of a given signal \( f(x, t = 0) \) by solving the following diffusion equation:

\[ \frac{d}{dt} f(x, t) = \frac{d}{dx} \left[ \frac{1}{| \frac{d}{dx} f(x, t) |^\alpha} \cdot \frac{d}{dx} f(x, t) \right] \]

Note, if \( \alpha = 0 \), the above diffusion is a linear diffusion which is equivalent to a convolution with a Gaussian kernel with variance \( \sigma = \sqrt{2t_{end}} \), and if \( \alpha = 1 \), the diffusion is equivalent to the total variation (TV) flow.

Here is an example:

 #include <iostream>
 #include <vector>

 #include <TRTK/Diffusion.hpp>

 using namespace TRTK;
 using namespace TRTK::Diffusion;

 template <typename T, int sz>
 char (&array(T(&)[sz]))[sz];

 void print(const std::vector<double> & data)
 {
     for (unsigned i = 0; i < data.size(); ++i)
     {
         std::cout.precision(4);
         std::cout.width(8);
         std::cout << std::fixed << data[i];
     }
     std::cout << std::endl;
 }

 int main()
 {
     double data[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                      1.0, 1.0, 1.0, 1.0, 1.0, 1.0};

     std::vector<double> signal =
             std::vector<double>(data, data + sizeof array(data));

     for (double time = 0; time <= 1; time += 0.25)
     {
         print(nonlinearIsotropicDiffusion(signal, time, 0.25));
     }

     std::cout << std::endl;
     print(nonlinearIsotropicDiffusion(signal, 2.0, 0.25, 0.0, CONTINUED));
     print(nonlinearIsotropicDiffusion(signal, 2.0, 0.25, 0.0, INTERPOLATED));
     print(nonlinearIsotropicDiffusion(signal, 2.0, 0.25, 0.0, REFLECTED));
     print(nonlinearIsotropicDiffusion(signal, 2.0, 0.25, 0.0, ZERO));

     std::cout << std::endl;
     print(nonlinearIsotropicDiffusion(signal, 1000.0, 0.25, 0.0, CONTINUED));
     print(nonlinearIsotropicDiffusion(signal, 1000.0, 0.25, 0.0, ZERO));

     return 0;
 }

Output:

   0.0000  0.0000  0.0000  0.0000  0.0000  0.0000  1.0000  1.0000  1.0000  1.0000  1.0000  1.0000
   0.0000  0.0000  0.0000  0.0000  0.0625  0.0625  0.9375  0.9375  1.0000  1.0000  1.0000  1.0000
   0.0000  0.0000  0.0039  0.0039  0.1133  0.1133  0.8867  0.8867  0.9961  0.9961  1.0000  1.0000
   0.0002  0.0002  0.0105  0.0105  0.1548  0.1548  0.8452  0.8452  0.9895  0.9895  0.9998  0.9998
   0.0009  0.0009  0.0189  0.0189  0.1889  0.1889  0.8111  0.8111  0.9811  0.9811  0.9991  0.9991

   0.0085  0.0085  0.0595  0.0595  0.2772  0.2772  0.7228  0.7228  0.9405  0.9405  0.9915  0.9915
   0.0186  0.0100  0.0603  0.0596  0.2773  0.2772  0.7228  0.7227  0.9404  0.9397  0.9900  0.9814
   0.0085  0.0085  0.0595  0.0595  0.2772  0.2772  0.7228  0.7228  0.9405  0.9405  0.9915  0.9915
   0.0085  0.0078  0.0595  0.0595  0.2765  0.2772  0.7142  0.7228  0.8732  0.9405  0.6555  0.9915

   0.5000  0.5000  0.5000  0.5000  0.5000  0.5000  0.5000  0.5000  0.5000  0.5000  0.5000  0.5000
   0.0000  0.0000  0.0000  0.0000  0.0000  0.0000  0.0000  0.0000  0.0000  0.0000  0.0000  0.0000
Note:
An interpolation method of "INTERPOLATED" might invalidate the minimum-maximum principle of this diffusion equation.
References:
Perona and Malik, "Scale-space and edge detection using anisotropic diffusion", Pattern Analysis and Machine Intelligence, 1990
References:
Brox et al., "Nonlinear Structure Tensors", Image and Vision Computing, 2006
Author:
Christoph Haenisch
Version:
0.1.0
Date:
last changed on 2011-06-22

Definition at line 749 of file Diffusion.hpp.

template<class T >
const std::vector<T> TRTK::Diffusion::nonlinearIsotropicDiffusion ( const std::vector< T > &  signal,
T(*)(T)  diffusivity,
time,
step_size = 0.25,
BorderInterpolation  interpolation_method = CONTINUED 
)

1-dimensional nonlinear isotropic diffusion.

Parameters:
[in]signalinput signal \( f(x, t = 0) \)
[in]diffusivitydiffusivity \( D(x) \)
[in]timediffusion time \( t_{end} \)
[in]step_sizeshould be less than 0.25 to guarantee stability
[in]interpolation_methodinterpolation method used for the differentiation
Returns:
Returns the diffused signal \( f(x, t = t_{end}) \).

This function computes the diffusion of a given signal \( f(x, t = 0) \) by solving the following diffusion equation:

\[ \frac{d}{dt} f(x, t) = \frac{d}{dx} \left[ D \left( \frac{d}{dx} f(x, t) \right) \cdot \frac{d}{dx} f(x, t) \right] \]

Note, if \( D(x) = 1 \), the above diffusion is a linear diffusion which is equivalent to a convolution with a Gaussian kernel with the variance \( \sigma = \sqrt{2t_{end}} \).

Here is an example:

 #include <iostream>
 #include <vector>

 #include <TRTK/Diffusion.hpp>

 using namespace TRTK;
 using namespace TRTK::Diffusion;

 template <typename T, int sz>
 char (&array(T(&)[sz]))[sz];

 void print(const std::vector<double> & data)
 {
     for (unsigned i = 0; i < data.size(); ++i)
     {
         std::cout.precision(4);
         std::cout.width(8);
         std::cout << std::fixed << data[i];
     }
     std::cout << std::endl;
 }

 double diffusivity(double value)
 {
     const double epsilon = 1e-14;
     return 1.0 / (std::abs(value) + epsilon);
 }

 int main()
 {
     double data[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};

     std::vector<double> signal = std::vector<double>(data, data + sizeof array(data));

     for (double time = 0; time <= 1; time += 0.25)
     {
         print(nonlinearIsotropicDiffusion(signal, diffusivity, time, 0.5));
     }

     return 0;
 }

Output:

   0.00    0.00    0.00    0.00    0.00    0.00    1.00    1.00    1.00    1.00    1.00    1.00
   0.00    0.00    0.00    0.00    0.12    0.12    0.88    0.88    1.00    1.00    1.00    1.00
   0.00    0.00    0.00    0.00    0.25    0.25    0.75    0.75    1.00    1.00    1.00    1.00
   0.00    0.00    0.19    0.19    0.19    0.19    0.81    0.81    0.81    0.81    1.00    1.00
   0.00    0.00    0.25    0.25    0.25    0.25    0.75    0.75    0.75    0.75    1.00    1.00
Note:
An interpolation method of "INTERPOLATED" might invalidate the minimum-maximum principle of this diffusion equation.
References:
Perona and Malik, "Scale-space and edge detection using anisotropic diffusion", Pattern Analysis and Machine Intelligence, 1990
References:
Brox et al., "Nonlinear Structure Tensors", Image and Vision Computing, 2006
Author:
Christoph Haenisch
Version:
0.1.0
Date:
last changed on 2011-06-22

Definition at line 924 of file Diffusion.hpp.

template<class T >
const std::vector<T> TRTK::Diffusion::secondDerivative ( const std::vector< T > &  signal,
const BorderInterpolation  interpolation = CONTINUED 
)

Computes the 2nd derivative of a 1-dimensional signal.

Template Parameters:
Tscalar type (must be a floating point type)
Parameters:
[in]signalinput signal
[in]interpolationinterpolation method for the border values

The derivative is computed by convolving signal with the kernel [1 -2 1].

Returns:
2nd derivative of the input signal.
Exceptions:
ErrorObjIf an unknown interpolation method is assigned, an error object is thrown and its error code is set to INVALID_ARGUMENT.

Here ist an example:

 #include <iostream>
 #include <vector>

 #include <TRTK/Diffusion.hpp>

 using namespace TRTK;
 using namespace TRTK::Diffusion;

 void print(const std::vector<double> & data)
 {
     for (unsigned i = 0; i < data.size(); ++i)
     {
         std::cout.precision(2);
         std::cout.width(8);
         std::cout << std::fixed << data[i];
     }
     std::cout << std::endl;
 }

 int main()
 {
     std::vector<double> signal;

     for (unsigned i = 0; i < 10; ++i)
     {
         signal.push_back(i * i + 3);
     }

     print(secondDerivative(signal, CONTINUED));
     print(secondDerivative(signal, INTERPOLATED));
     print(secondDerivative(signal, REFLECTED));
     print(secondDerivative(signal, ZERO));

     return 0;
 }

Output:

   1.00    2.00    2.00    2.00    2.00    2.00    2.00    2.00    2.00  -17.00
   0.00    2.00    2.00    2.00    2.00    2.00    2.00    2.00    2.00    0.00
   1.00    2.00    2.00    2.00    2.00    2.00    2.00    2.00    2.00  -17.00
  -2.00    2.00    2.00    2.00    2.00    2.00    2.00    2.00    2.00 -101.00
Author:
Christoph Haenisch
Version:
0.1.0
Date:
last changed on 2011-06-22

Definition at line 360 of file Diffusion.hpp.

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines