aboutsummaryrefslogtreecommitdiffstats
path: root/meowpp/math/Transformation.h
blob: 0d9ee0581e8da68b8b0bdacc319e429662ce1bfc (plain) (blame)
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#ifndef   math_Transformation_H__
#define   math_Transformation_H__

#include "Matrix.h"
#include "../Self.h"

#include <cstdlib>

namespace meow {

/*!
 * @brief A base class for implementing kinds of transformations.
 *
 * We define that the input and output form of our transformations all be
 * \b matrix . Some advance methods such as calculating jacobian matrix
 * will order that the input form must be a vector.
 * @author cat_leopard
 */
template<class Scalar>
class Transformation {
private:
  struct Myself {
    size_t  inputRows_;
    size_t  inputCols_;
    size_t outputRows_;
    size_t outputCols_;
    size_t      psize_;
    
    Myself& copyFrom(Myself const& b) {
      inputRows_  = b. inputRows_;
      inputCols_  = b. inputCols_;
      outputRows_ = b.outputRows_;
      outputCols_ = b.outputCols_;
      psize_      = b.psize_;
      return *this;
    }
  };
  
  Self<Myself> const self;
protected:
  /*!
   * Construct and setup
   * @param [in] inputRows  number of rows    of the input  matrix.
   * @param [in] inputCols  number of columns of the input  matrix.
   * @param [in] outputRows number of rows    of the output matrix.
   * @param [in] outputCols number of columns of the output matrix.
   * @param [in] psize      number of parameters
   */
  Transformation(size_t  inputRows, size_t  inputCols,
                 size_t outputRows, size_t outputCols,
                 size_t psize): self(true) {
    self()-> inputRows_ =  inputRows;
    self()-> inputCols_ =  inputCols;
    self()->outputRows_ = outputRows;
    self()->outputCols_ = outputCols;
    self()->psize_      = psize;
  }
  
  /*!
   * Construct and copy setings from another transformation class.
   * @param [in] b Specify where to copy the informations.
   */
  Transformation(Transformation const& b): self(false) {
    copyFrom(b);
  }
  
  /*!
   * @brief Copy from the specified one
   *
   * @param [in] b The specified one
   * @return \c *this
   */
  Transformation& copyFrom(Transformation const& b) {
    self().copyFrom(b.self);
    return *this;
  }
  
  /*!
   * @brief Ceference from the specified one
   *
   * @param [in] b The specified one
   * @return \c *this
   */
  Transformation& referenceFrom(Transformation const& b) {
    self().referenceFrom(b.self);
    return *this;
  }
public:
  /*!
   * Destructor
   */
  virtual ~Transformation() {
  }

  /*!
   * @brief Return the number of rows of the input matrix.
   *
   * @return Number of rows.
   */
  size_t inputRows() const {
    return self->inputRows_;
  }

  /*!
   * @brief Return the number of columns of the input matrix.
   *
   * @return Number of columns.
   */
  size_t inputCols() const {
    return self->inputCols_;
  }

  /*!
   * @brief Return the number of rows of the output matrix.
   *
   * @return Number of rows.
   */
  size_t outputRows() const {
    return self->outputRows_;
  }

  /*!
   * @brief Return the number of columns of the output matrix.
   *
   * @return Number of columns.
   */
  size_t outputCols() const {
    return self->outputCols_;
  }
  
  /*!
   * @brief Return the number of parameters.
   *
   * @return Number of parameters.
   */
  size_t parameterSize() const {
    return self->psize_;
  }

  /*!
   * @brief Get the \a i -th parameter.
   *
   * @param [in] i The index of the specified parameter.
   * @note It's a pure virtual method.
   */
  virtual Scalar parameter(size_t i) const = 0;

  /*!
   * @brief Setup the \a i -th parameter.
   *
   * @param [in] i The index of the specified parameter.
   * @param [in] s The new value to the specified parameter.
   * @note It's a pure virtual method.
   */
  virtual Scalar parameter(size_t i, Scalar const& s) = 0;

  /*!
   * @brief Do transformate.
   *
   * @param [in] x The input matrix.
   * @note It's a pure virtual method.
   */
  virtual Matrix<Scalar> transformate(Matrix<Scalar> const& x) const = 0;

  /*!
   * @brief Calculate the jacobian matrix (derivate by the input matrix)
   *        of the transformation.
   *
   * Consider the case of a non-differentiable
   * transformation might be implemented, we return an empty matrix
   * now instead of making it be a pure virtual method.
   * @param [in] x The input matrix.
   * @return       An empty matrix.
   */
  virtual Matrix<Scalar> jacobian(Matrix<Scalar> const& x) const {
    return Matrix<Scalar>();
  }

  /*!
   * @brief Calculate the jacobian matrix (derivate by the \a i -th parameter)
   *        of the transformation.
   *
   * Consider the case of a non-differentiable transformation might be
   * implemented, we return an empty matrix now instead of making it be
   * a pure virtual method.
   * @param [in] x The input matrix.
   * @param [in] i The index of the specified parameter.
   * @return       An empty matrix.
   */
  virtual Matrix<Scalar> jacobian(Matrix<Scalar> const& x, size_t i) const {
    return Matrix<Scalar>();
  }

  /*!
   * @brief Return whether this transformation is inversable or not
   *
   * @return \c false
   */
  virtual bool inversable() const { return false; }

  /*!
   * @brief Do the inverse transformation
   *
   * @param [in] x The input matirx
   * @return       An empty matrix
   */
  virtual Matrix<Scalar> transformateInv(Matrix<Scalar> const& x) const {
    return Matrix<Scalar>();
  }

  /*!
   * @brief Return the jacobian matrix of the inverse transformation
   *
   * @param [in] x The input matirx
   * @return       An empty matrix
   */
  virtual Matrix<Scalar> jacobianInv(Matrix<Scalar> const& x) const {
    return Matrix<Scalar>();
  }

  /*!
   * @brief Return the jacobian matrix of the inverse transformation
   *
   * @param [in] x The input matirx
   * @param [in] i The index of the specified parameter.
   * @return       An empty matrix
   */
  virtual Matrix<Scalar> jacobianInv(Matrix<Scalar> const& x, size_t i) const {
    return Matrix<Scalar>();
  }
};

}

#endif // math_Transformation_H__