TooN
objects.h
1 // -*- c++ -*-
2 
3 // Copyright (C) 2005,2009 Tom Drummond (twd20@cam.ac.uk),
4 // Ed Rosten (er258@cam.ac.uk), Gerhard Reitmayr (gr281@cam.ac.uk)
5 
6 //All rights reserved.
7 //
8 //Redistribution and use in source and binary forms, with or without
9 //modification, are permitted provided that the following conditions
10 //are met:
11 //1. Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //2. Redistributions in binary form must reproduce the above copyright
14 // notice, this list of conditions and the following disclaimer in the
15 // documentation and/or other materials provided with the distribution.
16 //
17 //THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
18 //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 //IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 //ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
21 //LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 //CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 //SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 //INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 //CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 //POSSIBILITY OF SUCH DAMAGE.
28 
29 namespace TooN {
30 
31 namespace Internal{
32  // dummy structs that are used in 0-ary operators
33  struct Zero;
34  struct SizedZero;
35  struct RCZero;
36  template<class P> struct Identity;
37  template<class P> struct SizedIdentity;
38 
39  template<int S, class P, class B, class Ps> class ScalarsVector;
40  template<int R, int C, class P, class B, class Ps> class ScalarsMatrix;
41  template<int R, int C, class P, class B, class Ps> class AddIdentity;
42  template<class P> class Scalars;
43  template<class P> class SizedScalars;
44  template<class P> class RCScalars;
45 
49  struct One{
50 
51  One(){}
52  template<class C> operator C() const
54  {
55  return 1;
56  }
57  };
58  template<class Rhs> Rhs operator*(One, const Rhs& v){return v;}
59  template<class Lhs> Lhs operator*(const Lhs& v, One){return v;}
60  template<class Rhs> Rhs operator+(One, const Rhs& v){return 1+v;}
61  template<class Lhs> Lhs operator+(const Lhs& v, One){return v+1;}
62  template<class Rhs> Rhs operator-(One, const Rhs& v){return 1-v;}
63  template<class Lhs> Lhs operator-(const Lhs& v, One){return v-1;}
64 
66  inline int operator-(const One&)
67  {
68  return -1;
69  }
70 
75  template<class C> struct NegType
76  {
77  typedef C Type;
78  };
79 
84  template<> struct NegType<One>
85  {
88  typedef int Type;
89  };
90 }
91 
96 template<class Rhs> struct Field<Internal::One, Rhs>
97 {
100  static const int is = Field<Rhs,Rhs>::is;
101 };
102 
107 template<class Lhs> struct Field<Lhs, Internal::One>
108 {
111  static const int is = Field<Lhs,Lhs>::is;
112 };
113 
115 // Zero
117 
118 
119 
120 template<> struct Operator<Internal::SizedZero>;
121 template<> struct Operator<Internal::RCZero>;
122 
123 
127 template<> struct Operator<Internal::Zero> {
130  template<int Size, class Precision, class Base>
131  void eval(Vector<Size, Precision, Base>& v) const {
132  for(int i=0; i < v.size(); i++) {
133  v[i]= 0;
134  }
135  }
136 
137  template<int R, int C, class P, class B>
138  void eval(Matrix<R,C,P,B>& m) const {
139  for(int r=0; r<m.num_rows(); r++){
140  for(int c=0; c<m.num_cols(); c++){
141  m(r,c)=0;
142  }
143  }
144  }
146 
147  template<int R, int C, class P, class B>
148  bool notequal(Matrix<R,C,P,B>& m) const {
149  for(int r=0; r<m.num_rows(); r++)
150  for(int c=0; c<m.num_cols(); c++)
151  if(m[r][c] != 0)
152  return 1;
153 
154  return 0;
155  }
156 
157 
158  template<int S, class P, class B>
159  bool notequal(Vector<S,P,B>& v) const {
160  for(int i=0; i<v.size(); i++)
161  if(v[i] != 0)
162  return 1;
163  return 0;
164  }
165 
167  Operator<Internal::SizedZero> operator()(int s);
169  Operator<Internal::RCZero> operator()(int r, int c);
170 
171 };
172 
176 template<> struct Operator<Internal::RCZero> : public Operator<Internal::Zero> {
177 
180  Operator(int r, int c) : my_rows(r), my_cols(c) {}
181 
182  const int my_rows;
183  const int my_cols;
184 
185  int num_rows() const {return my_rows;}
186  int num_cols() const {return my_cols;}
188 };
189 
193 template<> struct Operator<Internal::SizedZero> : public Operator<Internal::Zero> {
194 
197  Operator(int s) : my_size(s) {}
198 
199  const int my_size;
200 
201  int size() const {return my_size;}
202  int num_rows() const {return my_size;}
203  int num_cols() const {return my_size;}
205 };
206 
209 }
210 
212  return Operator<Internal::RCZero>(r,c);
213 }
214 
215 
217 // Identity
219 
223 template<int R, int C, class P, class B, class Precision> struct Operator<Internal::AddIdentity<R,C,P,B,Precision> >
224 {
225  const Precision s;
227  bool invert_m;
228 
231  Operator(Precision s_, const Matrix<R,C,P,B>& m_, bool b)
232  :s(s_),m(m_),invert_m(b){}
234 
237  template<int R1, int C1, class P1, class B1>
238  void eval(Matrix<R1,C1,P1,B1>& mm) const{
239  for(int r=0; r < m.num_rows(); r++)
240  for(int c=0; c < m.num_cols(); c++)
241  if(invert_m)
242  mm[r][c] = -m[r][c];
243  else
244  mm[r][c] = m[r][c];
245 
246  for(int i=0; i < m.num_rows(); i++)
247  mm[i][i] += (P)s;
248  }
250 
253  int num_rows() const
254  {
255  return m.num_rows();
256  }
257  int num_cols() const
258  {
259  return m.num_cols();
260  }
262 };
263 
267 template<class Pr> struct Operator<Internal::Identity<Pr> > {
268 
271 
272  typedef Pr Precision;
273  template<class Pout, class Pmult> Operator<Internal::Identity<Pout> > scale_me(const Pmult& m) const
274  {
275  return Operator<Internal::Identity<Pout> >(val*m);
276  }
278 
280  const Precision val;
281 
284  Operator(const Precision& v)
285  :val(v)
286  {}
287 
288  Operator()
289  {}
291 
294  template<int R, int C, class P, class B>
295  void eval(Matrix<R,C,P,B>& m) const {
296  SizeMismatch<R, C>::test(m.num_rows(), m.num_cols());
297 
298  for(int r=0; r<m.num_rows(); r++){
299  for(int c=0; c<m.num_cols(); c++){
300  m(r,c)=0;
301  }
302  }
303 
304  for(int r=0; r < m.num_rows(); r++) {
305  m(r,r) = (P)val;
306  }
307  }
308 
309  template<int Rows, int Cols, typename P, typename B>
310  void plusequals(Matrix<Rows, Cols, P, B>& m) const
311  {
312  SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
313  for(int i=0; i < m.num_rows(); i++)
314  m[i][i] += (P)val;
315  }
316 
317  template <int Rows, int Cols, typename P1, typename B1>
319  {
320  SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
322  }
323 
324  template <int Rows, int Cols, typename P1, typename B1>
326  {
327  SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
329  }
330 
331  template <int Rows, int Cols, typename P1, typename B1>
333  {
334  SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
336  }
338 
343  }
345 };
346 
350 template<class Precision> struct Operator<Internal::SizedIdentity<Precision> >
351  : public Operator<Internal::Identity<Precision> > {
352 
354 
357  Operator(int s, const Precision& v)
358  :Operator<Internal::Identity<Precision> > (v), my_size(s)
359  {}
361 
364  const int my_size;
365  int num_rows() const {return my_size;}
366  int num_cols() const {return my_size;}
368 
371  template<class Pout, class Pmult> Operator<Internal::SizedIdentity<Pout> > scale_me(const Pmult& m) const
372  {
373  return Operator<Internal::SizedIdentity<Pout> >(my_size, val*m);
374  }
376 };
378 //
379 // Addition of scalars to vectors and matrices
380 //
381 
382 
386 template<int S, class P, class B, class Precision> struct Operator<Internal::ScalarsVector<S,P,B,Precision> >
387 {
388  const Precision s;
389  const Vector<S,P,B>& v;
390  const bool invert_v;
391 
394  Operator(Precision s_, const Vector<S,P,B>& v_, bool inv)
395  :s(s_),v(v_),invert_v(inv){}
397 
400  template<int S1, class P1, class B1>
401  void eval(Vector<S1,P1,B1>& vv) const{
402  for(int i=0; i < v.size(); i++)
403  if(invert_v)
404  vv[i] = s - v[i];
405  else
406  vv[i] = s + v[i];
407  }
409 
412  int size() const
413  {
414  return v.size();
415  }
417 };
418 
422 template<int R, int C, class P, class B, class Precision> struct Operator<Internal::ScalarsMatrix<R,C,P,B,Precision> >
423 {
424  const Precision s;
426  const bool invert_m;
427  Operator(Precision s_, const Matrix<R,C,P,B>& m_, bool inv)
430  :s(s_),m(m_),invert_m(inv){}
431  template<int R1, int C1, class P1, class B1>
432  void eval(Matrix<R1,C1,P1,B1>& mm) const{
433  for(int r=0; r < m.num_rows(); r++)
434  for(int c=0; c < m.num_cols(); c++)
435  if(invert_m)
436  mm[r][c] = s - m[r][c];
437  else
438  mm[r][c] = s + m[r][c];
439  }
441 
444  int num_rows() const
445  {
446  return m.num_rows();
447  }
448  int num_cols() const
449  {
450  return m.num_cols();
451  }
453 };
454 
459 template<class P> struct Operator<Internal::Scalars<P> >
460 {
463  typedef P Precision;
465 
466  const Precision s;
467 
470  Operator(Precision s_)
471  :s(s_){}
472 
473  Operator()
474  {}
476 
478  //
479  // All applications for vector
480  //
483 
484  template <int Size, typename P1, typename B1>
485  void eval(Vector<Size, P1, B1>& v) const
486  {
487  for(int i=0; i < v.size(); i++)
488  v[i] = (P1)s;
489  }
490 
491  template <int Size, typename P1, typename B1>
492  void plusequals(Vector<Size, P1, B1>& v) const
493  {
494  for(int i=0; i < v.size(); i++)
495  v[i] += (P1)s;
496  }
497 
498  template <int Size, typename P1, typename B1>
499  void minusequals(Vector<Size, P1, B1>& v) const
500  {
501  for(int i=0; i < v.size(); ++i)
502  v[i] -= (P1)s;
503  }
504 
505  template <int Size, typename P1, typename B1>
507  {
509  }
510 
511  template <int Size, typename P1, typename B1>
513  {
515  }
516 
517  template <int Size, typename P1, typename B1>
519  {
521  }
522 
524  //
525  // All applications for matrix
526  //
527 
528  template <int Rows, int Cols, typename P1, typename B1>
529  void eval(Matrix<Rows,Cols, P1, B1>& m) const
530  {
531  for(int r=0; r < m.num_rows(); r++)
532  for(int c=0; c < m.num_cols(); c++)
533  m[r][c] = s;
534  }
535 
536  template <int Rows, int Cols, typename P1, typename B1>
537  void plusequals(Matrix<Rows,Cols, P1, B1>& m) const
538  {
539  for(int r=0; r < m.num_rows(); r++)
540  for(int c=0; c < m.num_cols(); c++)
541  m[r][c] += (P1)s;
542  }
543 
544  template <int Rows, int Cols, typename P1, typename B1>
545  void minusequals(Matrix<Rows,Cols, P1, B1>& m) const
546  {
547  for(int r=0; r < m.num_rows(); r++)
548  for(int c=0; c < m.num_cols(); c++)
549  m[r][c] -= (P1)s;
550  }
551 
552  template <int Rows, int Cols, typename P1, typename B1>
554  {
556  }
557 
558 
559  template <int Rows, int Cols, typename P1, typename B1>
561  {
563  }
564 
565  template <int Rows, int Cols, typename P1, typename B1>
567  {
569  }
572  //
573  // Create sized versions for initialization
574  //
575 
578 
579  Operator<Internal::SizedScalars<Precision> > operator()(int size) const
580  {
582  }
583 
584  Operator<Internal::RCScalars<Precision> > operator()(int r, int c) const
585  {
587  }
589 
592  template<class Pout, class Pmult> Operator<Internal::Scalars<Pout> > scale_me(const Pmult& m) const
593  {
594  return Operator<Internal::Scalars<Pout> >(s*m);
595  }
597 };
598 
602 template<class P> struct Operator<Internal::SizedScalars<P> >: public Operator<Internal::Scalars<P> >
603 {
607  const int my_size;
608  int size() const {
609  return my_size;
610  }
611  int num_rows() const {
612  return my_size;
613  }
614  int num_cols() const {
615  return my_size;
616  }
618 
621  Operator(P s, int sz)
622  :Operator<Internal::Scalars<P> >(s),my_size(sz){}
624 
627  template<class Pout, class Pmult> Operator<Internal::SizedScalars<Pout> > scale_me(const Pmult& m) const
628  {
629  return Operator<Internal::SizedScalars<Pout> >(s*m, my_size);
630  }
632 
633 private:
634  void operator()(int);
635  void operator()(int,int);
636 };
637 
638 
642 template<class P> struct Operator<Internal::RCScalars<P> >: public Operator<Internal::Scalars<P> >
643 {
645 
648  const int my_rows, my_cols;
649  int num_rows() const {
650  return my_rows;
651  }
652  int num_cols() const {
653  return my_cols;
654  }
655 
656  Operator(P s, int r, int c)
657  :Operator<Internal::Scalars<P> >(s),my_rows(r),my_cols(c)
658  {}
659 
660  template<class Pout, class Pmult> Operator<Internal::RCScalars<Pout> > scale_me(const Pmult& m) const
661  {
662  return Operator<Internal::RCScalars<Pout> >(s*m, my_rows, my_cols);
663  }
664 
666 private:
667  void operator()(int);
668  void operator()(int,int);
669 };
670 
671 
673 //
674 // How to scale scalable operators
675 //
676 
677 template<template<class> class Op, class Pl, class Pr>
679 operator*(const Pl& l, const Operator<Op<Pr> >& r)
680 {
681  return r.template scale_me<typename Internal::MultiplyType<Pl, Pr>::type, Pl>(l);
682 }
683 
684 template<template<class> class Op, class Pl, class Pr>
686 operator*(const Operator<Op<Pl> >& l, const Pr& r)
687 {
688  return l.template scale_me<typename Internal::MultiplyType<Pl, Pr>::type>(r);
689 }
690 
691 template<template<class> class Op, class Pl, class Pr>
693 operator/(const Operator<Op<Pl> >& l, const Pr& r)
694 {
695  return l.template scale_me<typename Internal::MultiplyType<Pl, Pr>::type, Pl>(static_cast<typename Internal::DivideType<Pl,Pr>::type>(1)/r);
696 }
697 
698 
699 template<class Op>
700 Operator<Op> operator-(const Operator<Op>& o)
701 {
702  return o.template scale_me<typename Operator<Op>::Precision>(-1);
703 }
704 
705 //Special case for negating One
706 template<template<class>class Op>
707 Operator<Op<DefaultPrecision> > operator-(const Operator<Op<Internal::One> >& o)
708 {
709  return o.template scale_me<DefaultPrecision>(-1);
710 }
711 
732 
733 
745 static Operator<Internal::Zero> Zeros;
746 
767 
768 }
769 
const Precision val
}
Definition: objects.h:280
const Precision s
Scalar to add.
Definition: objects.h:424
Definition: objects.h:42
const bool invert_m
Whether to use + or - m.
Definition: objects.h:426
const Precision s
Scalar to add.
Definition: objects.h:388
const bool invert_v
Whether to use + or - v.
Definition: objects.h:390
const Vector< S, P, B > & v
Vector to be added to.
Definition: objects.h:389
Pretty generic SFINAE introspection generator.
Definition: vec_test.cc:21
A vector.
Definition: vector.hh:126
int Type
One really repersents 1.
Definition: objects.h:88
One()
This constructor does nothing.
Definition: objects.h:51
Definition: objects.h:49
Matrix< 2 > inv(const Matrix< 2 > &m)
Invert a matrix.
Definition: helpers.h:65
const Precision s
Scale of the identity matrix.
Definition: objects.h:225
Definition: objects.h:40
Definition: objects.h:43
Definition: objects.h:176
Definition: operators.hh:119
Determine if two classes are in the same field.
Definition: operators.hh:39
Definition: objects.h:41
Definition: objects.h:36
Definition: objects.h:37
C Type
The type of -C.
Definition: objects.h:77
Definition: objects.h:39
Definition: operators.hh:87
Definition: objects.h:75
Definition: objects.h:44
const Matrix< R, C, P, B > & m
matrix to which the identity should be added
Definition: objects.h:226
const Precision s
Value of the scalar being represented.
Definition: objects.h:466
Definition: size_mismatch.hh:103
bool invert_m
Whether the identity should be added to + or - m.
Definition: objects.h:227
Definition: objects.h:127
const Matrix< R, C, P, B > & m
Vector to be added to.
Definition: objects.h:425
Definition: objects.h:193