Templates -- Meow  1.1.2
不能,也不應該先編譯成obj-file的templates
Transformations.h
Go to the documentation of this file.
1 #ifndef math_Transformations_H__
2 #define math_Transformations_H__
3 
4 #include "Transformation.h"
5 #include "Matrix.h"
6 #include "utility.h"
7 #include "../Self.h"
8 
9 #include <cstdlib>
10 
11 namespace meow {
12 
49 template<class Scalar>
50 class BallProjection: public Transformation<Scalar> {
51 private:
52  struct Myself {
53  Scalar radius_;
54  size_t dimension_;
55 
56  Myself() {
57  }
58  ~Myself() {
59  }
60  Myself& copyFrom(Myself const& b) {
61  radius_ = b.radius_;
62  dimension_ = b.dimension_;
63  return *this;
64  }
65  };
66 
67  Self<Myself> const self;
68 public:
74  Transformation<Scalar>(b), self(false) {
75  copyFrom(b);
76  }
77 
82  BallProjection(size_t d): self(true),
83  Transformation<Scalar>(d, 1, d, 1, 1) {
84  self()->dimension_ = d;
85  radius(1);
86  }
87 
93  BallProjection(size_t d, Scalar const& r):
94  Transformation<Scalar>(d, 1, d, 1, 1), self(true) {
95  self()->dimension_ = d;
96  radius(r);
97  }
98 
106  copyFrom(b);
107  return *this;
108  }
109 
117  referenceFrom(b);
118  return *this;
119  }
120 
124  Scalar parameter(size_t i) const {
125  return radius();
126  }
127 
131  Scalar parameter(size_t i, Scalar const& s) {
132  return radius(s);
133  }
134 
138  Scalar radius() const {
139  return self->radius_;
140  }
141 
148  Scalar radius(Scalar const& r) {
149  self()->radius_ = r;
150  return radius();
151  }
152 
156  size_t dimension() const {
157  return self->dimension_;
158  }
159 
160 
177  Matrix<Scalar> ret(x);
178  for (size_t c = 0, C = ret.cols(); c < C; c++) {
179  Scalar sum(0);
180  for (size_t i = 0; i < self->dimension_; i++) {
181  sum = sum + squ(ret(i, c));
182  }
183  Scalar len(sqrt(double(sum)));
184  for (size_t i = 0; i < self->dimension_; i++) {
185  ret(i, c, ret(i, c) * radius() / len);
186  }
187  }
188  return ret;
189  }
190 
220  Scalar sum(0);
221  for(size_t i = 0, I = dimension(); i < I; ++i)
222  sum = sum + squ(x(i, 0));
223  Scalar len(sqrt(double(sum)));
224  Matrix<Scalar> ret(dimension(), dimension(), Scalar(0.0));
225  for(size_t i = 0, I = dimension(); i < I; ++i)
226  for(size_t j = 0; j < I; ++j)
227  if (i == j) {
228  ret(i, j, radius() * (squ(len) - squ(x(i, 0))) / cub(len));
229  }
230  else {
231  ret(i, j, radius() * (-x(i, 0) * x(j, 0) / cub(len)));
232  }
233  return ret;
234  }
235 
264  Matrix<Scalar> jacobian(Matrix<Scalar> const& x, size_t i) const {
265  Matrix<Scalar> ret(dimension(), 1, Scalar(0.0));
266  Scalar sum(0);
267  for(size_t i = 0, I = dimension(); i < I; i++) {
268  sum = sum + squ(x(i, 0));
269  }
270  return ret / Scalar(sqrt(double(sum)));
271  }
272 
277  return copyFrom(b);
278  }
279 
284  return transformate(v);
285  }
286 };
287 
288 
328 template<class Scalar>
329 class PhotoProjection: public Transformation<Scalar> {
330 private:
331  struct Myself {
332  Scalar focal_;
333  size_t dimension_;
334 
335  Myself() {
336  }
337  ~Myself() {
338  }
339  Myself& copyFrom(Myself const& b) {
340  focal_ = b.focal_;
341  dimension_ = b.dimension_;
342  return *this;
343  }
344  };
345 
346  Self<Myself> const& self;
347 public:
352  Transformation<Scalar>(dimension, 1, dimension, 1, 1), self(true) {
353  self()->dimension_ = dimension;
354  focal(1);
355  }
356 
360  PhotoProjection(size_t dimension, Scalar const& f):
361  Transformation<Scalar>(dimension, 1, dimension, 1, 1), self(true) {
362  self()->dimension_ = dimension;
363  focal(f);
364  }
365 
370  Transformation<Scalar>(p), self(false) {
371  self().copyFrom(p.self);
372  }
373 
381  self().copyFrom(b.self);
382  return *this;
383  }
384 
392  self().referenceFrom(b.self);
393  return *this;
394  }
395 
399  Scalar parameter(size_t i) const {
400  return focal();
401  }
402 
406  Scalar parameter(size_t i, Scalar const& s){
407  return focal(s);
408  }
409 
414  Scalar focal() const {
415  return self->focal_;
416  }
417 
424  Scalar focal(Scalar const& f){
425  self()->focal_ = f;
426  return focal();
427  }
428 
432  size_t dimension() const {
433  return self->dimension_;
434  }
435 
454  Matrix<Scalar> ret(x);
455  for (size_t c = 0, C = ret.cols(); c < C; c++) {
456  for (size_t i = 0, I = dimension(); i < I; ++i) {
457  ret(i, c, -ret(i, c) * focal() / ret(I - 1, c));
458  }
459  }
460  return ret;
461  }
462 
493  Matrix<Scalar> ret(dimension(), dimension(), Scalar(0.0));
494  for(ssize_t i = 0, I = (ssize_t)dimension() - 1; i < I; i++){
495  ret(i, i, -focal() / x(I, 0) );
496  ret(i, dimension() - 1, focal() / squ(x(I, 0)));
497  }
498  return ret;
499  }
500 
531  Matrix<Scalar> jacobian(Matrix<Scalar> const& x, size_t i) const{
532  Matrix<Scalar> ret(dimension(), 1, Scalar(0.0));
533  for(size_t i = 0, I = dimension(); i < I; ++i) {
534  ret(i, 0, -x(i, 0) / x(I - 1, 0));
535  }
536  return ret;
537  }
538 
543  return copyFrom(b);
544  }
545 
550  return transformate(v);
551  }
552 };
553 
554 }
555 
556 #endif // Transformations_H__