Commit 5348ed7f authored by Davis King's avatar Davis King

- Made the vector class inherit from matrix

  - Added code to make sure the vector class does the
    appropriate type promotion when vector objects
    with different types are used together.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402736
parent 8c9d6c12
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <functional> #include <functional>
#include <iostream> #include <iostream>
#include "../matrix/matrix.h" #include "../matrix/matrix.h"
#include <limits>
namespace dlib namespace dlib
{ {
...@@ -20,6 +21,37 @@ namespace dlib ...@@ -20,6 +21,37 @@ namespace dlib
> >
class vector; class vector;
// ----------------------------------------------------------------------------------------
template <typename T, typename U, typename enabled = void>
struct promote;
template <typename T, typename U, typename enabled = void>
struct largest_type
{
typedef T type;
};
template <typename T, typename U>
struct largest_type<T,U, typename enable_if_c<(sizeof(T) < sizeof(U))>::type>
{
typedef U type;
};
template <typename T, typename U>
struct promote<T,U, typename enable_if_c<std::numeric_limits<T>::is_integer == std::numeric_limits<U>::is_integer>::type>
{
// If both T and U are both either integeral or non-integral then just
// use the biggest one
typedef typename largest_type<T,U>::type type;
};
template <typename T, typename U>
struct promote<T,U, typename enable_if_c<std::numeric_limits<T>::is_integer != std::numeric_limits<U>::is_integer>::type>
{
typedef double type;
};
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T, typename U, typename enabled = void> template <typename T, typename U, typename enabled = void>
...@@ -52,8 +84,10 @@ namespace dlib ...@@ -52,8 +84,10 @@ namespace dlib
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
dest.x() = static_cast<T>(m(0)); T x = static_cast<T>(m(0));
dest.y() = static_cast<T>(m(1)); T y = static_cast<T>(m(1));
dest.x() = x;
dest.y() = y;
} }
template <typename EXP> template <typename EXP>
...@@ -62,9 +96,13 @@ namespace dlib ...@@ -62,9 +96,13 @@ namespace dlib
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
dest.x() = static_cast<T>(m(0)); T x = static_cast<T>(m(0));
dest.y() = static_cast<T>(m(1)); T y = static_cast<T>(m(1));
dest.z() = static_cast<T>(m(2)); T z = static_cast<T>(m(2));
dest.x() = x;
dest.y() = y;
dest.z() = z;
} }
}; };
...@@ -122,18 +160,18 @@ namespace dlib ...@@ -122,18 +160,18 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T> template <typename T>
class vector<T,3> class vector<T,3> : public matrix<T,3,1>
{ {
/*! /*!
INITIAL VALUE INITIAL VALUE
- x_value == 0 - x() == 0
- y_value == 0 - y() == 0
- z_value == 0 - z() == 0
CONVENTION CONVENTION
- x_value == x() - (*this)(0) == x()
- y_value == y() - (*this)(1) == y()
- z_value == z() - (*this)(2) == z()
!*/ !*/
...@@ -243,9 +281,9 @@ namespace dlib ...@@ -243,9 +281,9 @@ namespace dlib
// --------------------------------------- // ---------------------------------------
template <typename U> template <typename U, long N>
vector& operator = ( vector& operator = (
const vector<U,3>& item const vector<U,N>& item
) )
{ {
vector_assign_helper<T,U>::assign(*this, item); vector_assign_helper<T,U>::assign(*this, item);
...@@ -266,19 +304,19 @@ namespace dlib ...@@ -266,19 +304,19 @@ namespace dlib
// --------------------------------------- // ---------------------------------------
T length( double length(
) const ) const
{ {
return (T)std::sqrt((double)(x()*x() + y()*y() + z()*z())); return std::sqrt((double)(x()*x() + y()*y() + z()*z()));
} }
// --------------------------------------- // ---------------------------------------
vector normalize ( vector<double,3> normalize (
) const ) const
{ {
T tmp = (T)std::sqrt((double)(x()*x() + y()*y() + z()*z())); const double tmp = std::sqrt((double)(x()*x() + y()*y() + z()*z()));
return vector ( x()/tmp, return vector<double,3> ( x()/tmp,
y()/tmp, y()/tmp,
z()/tmp z()/tmp
); );
...@@ -289,7 +327,7 @@ namespace dlib ...@@ -289,7 +327,7 @@ namespace dlib
T& x ( T& x (
) )
{ {
return x_value; return (*this)(0);
} }
// --------------------------------------- // ---------------------------------------
...@@ -297,7 +335,7 @@ namespace dlib ...@@ -297,7 +335,7 @@ namespace dlib
T& y ( T& y (
) )
{ {
return y_value; return (*this)(1);
} }
// --------------------------------------- // ---------------------------------------
...@@ -305,7 +343,7 @@ namespace dlib ...@@ -305,7 +343,7 @@ namespace dlib
T& z ( T& z (
) )
{ {
return z_value; return (*this)(2);
} }
// --------------------------------------- // ---------------------------------------
...@@ -313,7 +351,7 @@ namespace dlib ...@@ -313,7 +351,7 @@ namespace dlib
const T& x ( const T& x (
) const ) const
{ {
return x_value; return (*this)(0);
} }
// --------------------------------------- // ---------------------------------------
...@@ -321,7 +359,7 @@ namespace dlib ...@@ -321,7 +359,7 @@ namespace dlib
const T& y ( const T& y (
) const ) const
{ {
return y_value; return (*this)(1);
} }
// --------------------------------------- // ---------------------------------------
...@@ -329,7 +367,7 @@ namespace dlib ...@@ -329,7 +367,7 @@ namespace dlib
const T& z ( const T& z (
) const ) const
{ {
return z_value; return (*this)(2);
} }
// --------------------------------------- // ---------------------------------------
...@@ -343,11 +381,24 @@ namespace dlib ...@@ -343,11 +381,24 @@ namespace dlib
// --------------------------------------- // ---------------------------------------
vector cross ( template <typename U, long N>
const vector& rhs typename promote<T,U>::type dot (
const vector<U,N>& rhs
) const
{
return x()*rhs.x() + y()*rhs.y() + z()*rhs.z();
}
// ---------------------------------------
template <typename U, long N>
vector<typename promote<T,U>::type,3> cross (
const vector<U,N>& rhs
) const ) const
{ {
return vector ( typedef vector<typename promote<T,U>::type,3> ret_type;
return ret_type (
y()*rhs.z() - z()*rhs.y(), y()*rhs.z() - z()*rhs.y(),
z()*rhs.x() - x()*rhs.z(), z()*rhs.x() - x()*rhs.z(),
x()*rhs.y() - y()*rhs.x() x()*rhs.y() - y()*rhs.x()
...@@ -404,6 +455,17 @@ namespace dlib ...@@ -404,6 +455,17 @@ namespace dlib
// --------------------------------------- // ---------------------------------------
template <typename U, long N>
vector<typename promote<T,U>::type,3> operator + (
const vector<U,N>& rhs
) const
{
typedef vector<typename promote<T,U>::type,3> ret_type;
return ret_type(x()+rhs.x(), y()+rhs.y(), z()+rhs.z());
}
// ---------------------------------------
vector operator + ( vector operator + (
const vector& rhs const vector& rhs
) const ) const
...@@ -413,6 +475,17 @@ namespace dlib ...@@ -413,6 +475,17 @@ namespace dlib
// --------------------------------------- // ---------------------------------------
template <typename U, long N>
vector<typename promote<T,U>::type,3> operator - (
const vector<U,N>& rhs
) const
{
typedef vector<typename promote<T,U>::type,3> ret_type;
return ret_type(x()-rhs.x(), y()-rhs.y(), z()-rhs.z());
}
// ---------------------------------------
vector operator - ( vector operator - (
const vector& rhs const vector& rhs
) const ) const
...@@ -422,11 +495,13 @@ namespace dlib ...@@ -422,11 +495,13 @@ namespace dlib
// --------------------------------------- // ---------------------------------------
vector operator / ( template <typename U>
const T& val vector<typename promote<T,U>::type,3> operator / (
const U& val
) const ) const
{ {
return vector(x()/val, y()/val, z()/val); typedef vector<typename promote<T,U>::type,3> ret_type;
return ret_type(x()/val, y()/val, z()/val);
} }
// --------------------------------------- // ---------------------------------------
...@@ -451,49 +526,32 @@ namespace dlib ...@@ -451,49 +526,32 @@ namespace dlib
// --------------------------------------- // ---------------------------------------
template <long NRm, long NC, typename MM, typename l>
operator matrix<T,NRm, NC, MM,l> (
) const
{
matrix<T,NRm, NC, MM,l> m(3,1);
m(0) = x();
m(1) = y();
m(2) = z();
return m;
}
// ---------------------------------------
void swap ( void swap (
vector& item vector& item
) )
{ {
dlib::exchange(x_value, item.x_value); dlib::exchange(x(), item.x());
dlib::exchange(y_value, item.y_value); dlib::exchange(y(), item.y());
dlib::exchange(z_value, item.z_value); dlib::exchange(z(), item.z());
} }
// --------------------------------------- // ---------------------------------------
private:
T x_value;
T y_value;
T z_value;
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T> template <typename T>
class vector<T,2> class vector<T,2> : public matrix<T,2,1>
{ {
/*! /*!
INITIAL VALUE INITIAL VALUE
- x_value == 0 - x() == 0
- y_value == 0 - y() == 0
CONVENTION CONVENTION
- x_value == x() - (*this)(0) == x()
- y_value == y() - (*this)(1) == y()
- z() == 0 - z() == 0
!*/ !*/
...@@ -597,9 +655,9 @@ namespace dlib ...@@ -597,9 +655,9 @@ namespace dlib
// --------------------------------------- // ---------------------------------------
template <typename U> template <typename U, long N>
vector& operator = ( vector& operator = (
const vector<U,2>& item const vector<U,N>& item
) )
{ {
vector_assign_helper<T,U>::assign(*this, item); vector_assign_helper<T,U>::assign(*this, item);
...@@ -619,19 +677,19 @@ namespace dlib ...@@ -619,19 +677,19 @@ namespace dlib
// --------------------------------------- // ---------------------------------------
T length( double length(
) const ) const
{ {
return (T)std::sqrt((double)(x()*x() + y()*y())); return std::sqrt((double)(x()*x() + y()*y()));
} }
// --------------------------------------- // ---------------------------------------
vector normalize ( vector<double,2> normalize (
) const ) const
{ {
T tmp = (T)std::sqrt((double)(x()*x() + y()*y())); const double tmp = std::sqrt((double)(x()*x() + y()*y()));
return vector ( x()/tmp, return vector<double,2> ( x()/tmp,
y()/tmp y()/tmp
); );
} }
...@@ -641,7 +699,7 @@ namespace dlib ...@@ -641,7 +699,7 @@ namespace dlib
T& x ( T& x (
) )
{ {
return x_value; return (*this)(0);
} }
// --------------------------------------- // ---------------------------------------
...@@ -649,7 +707,7 @@ namespace dlib ...@@ -649,7 +707,7 @@ namespace dlib
T& y ( T& y (
) )
{ {
return y_value; return (*this)(1);
} }
// --------------------------------------- // ---------------------------------------
...@@ -657,7 +715,7 @@ namespace dlib ...@@ -657,7 +715,7 @@ namespace dlib
const T& x ( const T& x (
) const ) const
{ {
return x_value; return (*this)(0);
} }
// --------------------------------------- // ---------------------------------------
...@@ -665,7 +723,7 @@ namespace dlib ...@@ -665,7 +723,7 @@ namespace dlib
const T& y ( const T& y (
) const ) const
{ {
return y_value; return (*this)(1);
} }
// --------------------------------------- // ---------------------------------------
...@@ -687,6 +745,16 @@ namespace dlib ...@@ -687,6 +745,16 @@ namespace dlib
// --------------------------------------- // ---------------------------------------
template <typename U, long N>
typename promote<T,U>::type dot (
const vector<U,N>& rhs
) const
{
return x()*rhs.x() + y()*rhs.y() + z()*rhs.z();
}
// ---------------------------------------
vector& operator += ( vector& operator += (
const vector& rhs const vector& rhs
) )
...@@ -740,6 +808,17 @@ namespace dlib ...@@ -740,6 +808,17 @@ namespace dlib
// --------------------------------------- // ---------------------------------------
template <typename U, long N>
vector<typename promote<T,U>::type,N> operator + (
const vector<U,N>& rhs
) const
{
typedef vector<typename promote<T,U>::type,N> ret_type;
return ret_type(*this) + ret_type(rhs);
}
// ---------------------------------------
vector operator - ( vector operator - (
const vector& rhs const vector& rhs
) const ) const
...@@ -749,11 +828,24 @@ namespace dlib ...@@ -749,11 +828,24 @@ namespace dlib
// --------------------------------------- // ---------------------------------------
vector operator / ( template <typename U, long N>
const T& val vector<typename promote<T,U>::type,N> operator - (
const vector<U,N>& rhs
) const
{
typedef vector<typename promote<T,U>::type,N> ret_type;
return ret_type(*this) - ret_type(rhs);
}
// ---------------------------------------
template <typename U>
vector<typename promote<T,U>::type,2> operator / (
const U& val
) const ) const
{ {
return vector(x()/val, y()/val); typedef vector<typename promote<T,U>::type,2> ret_type;
return ret_type(x()/val, y()/val);
} }
// --------------------------------------- // ---------------------------------------
...@@ -796,33 +888,23 @@ namespace dlib ...@@ -796,33 +888,23 @@ namespace dlib
// --------------------------------------- // ---------------------------------------
template <long NRm, long NC, typename MM, typename l>
operator matrix<T,NRm, NC, MM,l> (
) const
{
matrix<T,NRm, NC, MM,l> m(2,1);
m(0) = x();
m(1) = y();
return m;
}
// ---------------------------------------
void swap ( void swap (
vector& item vector& item
) )
{ {
dlib::exchange(x_value, item.x_value); dlib::exchange(x(), item.x());
dlib::exchange(y_value, item.y_value); dlib::exchange(y(), item.y());
} }
// --------------------------------------- // ---------------------------------------
vector<T,3> cross ( template <typename U, long N>
const vector<T,3>& rhs vector<typename promote<T,U>::type,3> cross (
const vector<U,N>& rhs
) const ) const
{ {
return vector<T,3> ( typedef vector<typename promote<T,U>::type,3> ret_type;
return ret_type (
y()*rhs.z(), y()*rhs.z(),
- x()*rhs.z(), - x()*rhs.z(),
x()*rhs.y() - y()*rhs.x() x()*rhs.y() - y()*rhs.x()
...@@ -831,17 +913,15 @@ namespace dlib ...@@ -831,17 +913,15 @@ namespace dlib
// --------------------------------------- // ---------------------------------------
private:
T x_value;
T y_value;
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T, typename U> template <typename T, typename U>
inline const vector<T,2> operator* ( inline typename disable_if<is_matrix<U>, const vector<T,2> >::type operator* (
const vector<T,2>& v, const vector<T,2>& v,
const U& s const U& s
) )
...@@ -852,7 +932,7 @@ namespace dlib ...@@ -852,7 +932,7 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T, typename U> template <typename T, typename U>
inline const vector<T,2> operator* ( inline typename disable_if<is_matrix<U>, const vector<T,2> >::type operator* (
const U& s, const U& s,
const vector<T,2>& v const vector<T,2>& v
) )
...@@ -863,7 +943,7 @@ namespace dlib ...@@ -863,7 +943,7 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T, typename U> template <typename T, typename U>
inline const vector<T,3> operator* ( inline typename disable_if<is_matrix<U>, const vector<T,3> >::type operator* (
const vector<T,3>& v, const vector<T,3>& v,
const U& s const U& s
) )
...@@ -874,7 +954,7 @@ namespace dlib ...@@ -874,7 +954,7 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T, typename U> template <typename T, typename U>
inline const vector<T,3> operator* ( inline typename disable_if<is_matrix<U>, const vector<T,3> >::type operator* (
const U& s, const U& s,
const vector<T,3>& v const vector<T,3>& v
) )
......
...@@ -14,7 +14,7 @@ namespace dlib ...@@ -14,7 +14,7 @@ namespace dlib
typename T, typename T,
long NR = 3 long NR = 3
> >
class vector class vector : public matrix<T,NR,1>
{ {
/*! /*!
REQUIREMENTS ON T REQUIREMENTS ON T
...@@ -129,21 +129,6 @@ namespace dlib ...@@ -129,21 +129,6 @@ namespace dlib
- #z() == 0 - #z() == 0
!*/ !*/
operator matrix<T> (
) const;
/*!
ensures
- provides automatic conversions from a vector object to a column
matrix
- returns a matrix object m such that:
- m.nr() == NR
- m.nc() == 1
- m(0) == x()
- m(1) == y()
- if (NR == 3) then
- m(2) == z()
!*/
~vector ( ~vector (
); );
/*! /*!
......
...@@ -186,6 +186,22 @@ namespace ...@@ -186,6 +186,22 @@ namespace
DLIB_CASSERT(vl2.cross(vl3).length() == 12,""); DLIB_CASSERT(vl2.cross(vl3).length() == 12,"");
DLIB_CASSERT(vl3.cross(vl2).length() == 12,""); DLIB_CASSERT(vl3.cross(vl2).length() == 12,"");
matrix<double> m(3,3);
m = 1,2,3,
4,5,6,
7,8,9;
vd3.x() = 2;
vd3.y() = 3;
vd3.z() = 4;
vd3 = m*vd3;
DLIB_CASSERT(vd3.x() == 1*2 + 2*3 + 3*4,vd3.x() << " == " << (1*2 + 2*3 + 3*4));
DLIB_CASSERT(vd3.y() == 4*2 + 5*3 + 6*4,"");
DLIB_CASSERT(vd3.z() == 7*2 + 8*3 + 9*4,"");
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment