File: cubic_spline.h

package info (click to toggle)
mrtrix3 3.0.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 13,712 kB
  • sloc: cpp: 129,776; python: 9,494; sh: 593; makefile: 234; xml: 47
file content (160 lines) | stat: -rw-r--r-- 5,224 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/* Copyright (c) 2008-2022 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Covered Software is provided under this License on an "as is"
 * basis, without warranty of any kind, either expressed, implied, or
 * statutory, including, without limitation, warranties that the
 * Covered Software is free of defects, merchantable, fit for a
 * particular purpose or non-infringing.
 * See the Mozilla Public License v. 2.0 for more details.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#ifndef __math_cubic_spline_h__
#define __math_cubic_spline_h__
namespace MR
{
  namespace Math
  {
    enum SplineProcessingType
    {
      Value = 1,
      Derivative = 2,
      ValueAndDerivative = Value | Derivative
    };


    template <typename T> class CubicSpline
    { MEMALIGN(CubicSpline<T>)
      public:
        using BasisMatrix = Eigen::Matrix<T, 4, 4>;
        using WeightVector = Eigen::Matrix<T, 1, 4>;
        WeightVector weights, deriv_weights;

        void set (T position) {
          (this->*(_internal_set)) (position);
        }

        T coef (size_t i) const {
          return (weights[i]);
        }

      protected:
        static const BasisMatrix cubic_poly_derivative_operator;
        const BasisMatrix basis_matrix;
        const BasisMatrix deriv_basis_matrix;

        CubicSpline (SplineProcessingType processType, const BasisMatrix basis_matrix, const BasisMatrix deriv_basis_matrix) :
          basis_matrix (basis_matrix),
          deriv_basis_matrix (deriv_basis_matrix)
        {
          switch (processType) {
            case SplineProcessingType::Value:
              _internal_set = &CubicSpline::_set_value;
              break;
            // Could be used for partial derviative so we need to calculate both deriv and value weights
            case SplineProcessingType::Derivative:
            case SplineProcessingType::ValueAndDerivative:
              _internal_set = &CubicSpline::_set_value_deriv;
              break;
            default:
              break;
            }
        }

      private:

        CubicSpline () {}

        // Function pointer to the internal set function depening on processing type
        void (CubicSpline::*_internal_set) (T);

        inline void _set_value (T position) {
          const T p2 = Math::pow2(position);
          const auto vec = WeightVector (p2 * position, p2, position, 1.0);
          weights = (vec * basis_matrix);
        }

        inline void _set_value_deriv (T position) {
          const T p2 = Math::pow2(position);
          const auto vec = WeightVector (position * p2, p2, position, 1.0);
          weights = (vec * basis_matrix);
          deriv_weights = (vec * deriv_basis_matrix);
        }
    };


    // Hermite spline implementation
    template <typename T> class HermiteSpline :
    public CubicSpline<T> { MEMALIGN(HermiteSpline<T>)
      public:
        using BasisMatrix = typename CubicSpline<T>::BasisMatrix;
        static const BasisMatrix hermite_basis_mtrx;
        static const BasisMatrix hermite_derivative_basis_mtrx;

        HermiteSpline (SplineProcessingType processType)
          : CubicSpline<T> (processType, hermite_basis_mtrx, hermite_derivative_basis_mtrx) {}
    };


    // Uniform bspline implementation
    template <typename T> class UniformBSpline :
    public CubicSpline<T> { MEMALIGN(UniformBSpline<T>)
      public:
        using BasisMatrix = typename CubicSpline<T>::BasisMatrix;
        static const BasisMatrix uniform_bspline_basis_mtrx;
        static const BasisMatrix uniform_bspline_derivative_basis_mtrx;

        UniformBSpline (SplineProcessingType processType)
          : CubicSpline<T> (processType, uniform_bspline_basis_mtrx, uniform_bspline_derivative_basis_mtrx) {}
    };



    // Initialise our static const matrices
    template <typename T>
    const typename CubicSpline<T>::BasisMatrix
    CubicSpline<T>::cubic_poly_derivative_operator((BasisMatrix() <<
      0, 0, 0, 0,
      3, 0, 0, 0,
      0, 2, 0, 0,
      0, 0, 1, 0).finished());


    // Hermite spline
    template <typename T>
    const typename HermiteSpline<T>::BasisMatrix
    HermiteSpline<T>::hermite_basis_mtrx((BasisMatrix() <<
      -0.5,  1.5, -1.5,  0.5,
         1, -2.5,    2, -0.5,
      -0.5,    0,  0.5,    0,
         0,    1,    0,    0).finished());

    template <typename T>
    const typename HermiteSpline<T>::BasisMatrix
    HermiteSpline<T>::hermite_derivative_basis_mtrx(CubicSpline<T>::cubic_poly_derivative_operator * hermite_basis_mtrx);


    // Uniform b-spline
    template <typename T>
    const typename UniformBSpline<T>::BasisMatrix
    UniformBSpline<T>::uniform_bspline_basis_mtrx((1/6.0) * (BasisMatrix() <<
     -1,  3, -3,  1,
      3, -6,  3,  0,
     -3,  0,  3,  0,
      1,  4,  1,  0).finished());

    template <typename T>
    const typename UniformBSpline<T>::BasisMatrix
    UniformBSpline<T>::uniform_bspline_derivative_basis_mtrx(CubicSpline<T>::cubic_poly_derivative_operator * uniform_bspline_basis_mtrx);

  }
}


#endif