Commit 3d559009 authored by Davis King's avatar Davis King

- Added the randm(), linspace(), logspace() and cartesian_product()

    functions
  - Added an overload of pow() for pow(scalar, matrix)
  - Changed the range() function so that it returns row vectors
    instead of column vectors.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402896
parent 983b200b
......@@ -1445,8 +1445,8 @@ namespace dlib
typedef T type;
typedef memory_manager<char>::kernel_1a mem_manager_type;
typedef row_major_layout layout_type;
const static long NR = 0;
const static long NC = 1;
const static long NR = 1;
const static long NC = 0;
const static long cost = 1;
};
......@@ -1465,7 +1465,7 @@ namespace dlib
const matrix_range_exp& item
) :
matrix_exp<matrix_range_exp>(*this),
nr_(item.nr_),
nc_(item.nc_),
start(item.start),
inc(item.inc)
{}
......@@ -1481,7 +1481,7 @@ namespace dlib
inc = 1;
else
inc = -1;
nr_ = std::abs(end_ - start_) + 1;
nc_ = std::abs(end_ - start_) + 1;
}
matrix_range_exp (
T start_,
......@@ -1491,21 +1491,43 @@ namespace dlib
matrix_exp<matrix_range_exp>(*this)
{
start = start_;
nr_ = std::abs(end_ - start_)/inc_ + 1;
nc_ = std::abs(end_ - start_)/inc_ + 1;
if (start_ <= end_)
inc = inc_;
else
inc = -inc_;
}
matrix_range_exp (
T start_,
T end_,
long num,
bool
) :
matrix_exp<matrix_range_exp>(*this)
{
start = start_;
nc_ = num;
if (num > 1)
{
inc = (end_-start_)/(num-1);
}
else
{
inc = 0;
start = end_;
}
}
T operator() (
long r,
long
) const { return start + r*inc; }
long,
long c
) const { return start + c*inc; }
T operator() (
long r
) const { return start + r*inc; }
long c
) const { return start + c*inc; }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool aliases (
......@@ -1518,12 +1540,99 @@ namespace dlib
) const { return false; }
long nr (
) const { return nr_; }
) const { return NR; }
long nc (
) const { return NC; }
) const { return nc_; }
long nc_;
T start;
T inc;
};
// ----------------------------------------------------------------------------------------
template <typename T>
class matrix_log_range_exp;
template <typename T>
struct matrix_traits<matrix_log_range_exp<T> >
{
typedef T type;
typedef memory_manager<char>::kernel_1a mem_manager_type;
typedef row_major_layout layout_type;
const static long NR = 1;
const static long NC = 0;
const static long cost = 1;
};
template <typename T>
class matrix_log_range_exp : public matrix_exp<matrix_log_range_exp<T> >
{
public:
typedef typename matrix_traits<matrix_log_range_exp>::type type;
typedef typename matrix_traits<matrix_log_range_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_log_range_exp>::NR;
const static long NC = matrix_traits<matrix_log_range_exp>::NC;
const static long cost = matrix_traits<matrix_log_range_exp>::cost;
typedef typename matrix_traits<matrix_log_range_exp>::layout_type layout_type;
matrix_log_range_exp (
const matrix_log_range_exp& item
) :
matrix_exp<matrix_log_range_exp>(*this),
nc_(item.nc_),
start(item.start),
inc(item.inc)
{}
matrix_log_range_exp (
T start_,
T end_,
long num
) :
matrix_exp<matrix_log_range_exp>(*this)
{
start = start_;
nc_ = num;
if (num > 1)
{
inc = (end_-start_)/(num-1);
}
else
{
inc = 0;
start = end_;
}
}
T operator() (
long,
long c
) const { return std::pow(10,start + c*inc); }
T operator() (
long c
) const { return std::pow(10,start + c*inc); }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
long nr (
) const { return NR; }
long nc (
) const { return nc_; }
long nr_;
long nc_;
T start;
T inc;
};
......
......@@ -219,6 +219,39 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan,7)
return matrix_scalar_binary_exp<EXP,typename EXP::type,op_pow>(m.ref(),s);
}
// ----------------------------------------------------------------------------------------
struct op_pow2
{
template <typename EXP>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
{
const static long cost = EXP::cost+7;
typedef typename EXP::type type;
template <typename M, typename S>
static type apply ( const M& m, const S& s, long r, long c)
{ return static_cast<type>(std::pow(s,m(r,c))); }
};
};
template <
typename EXP,
typename S
>
const matrix_scalar_binary_exp<EXP,typename EXP::type,op_pow2> pow (
const S& s,
const matrix_exp<EXP>& m
)
{
// you can only round matrices that contain floats, doubles or long doubles.
COMPILE_TIME_ASSERT((
is_same_type<typename EXP::type,float>::value == true ||
is_same_type<typename EXP::type,double>::value == true ||
is_same_type<typename EXP::type,long double>::value == true
));
return matrix_scalar_binary_exp<EXP,typename EXP::type,op_pow2>(m.ref(),s);
}
// ----------------------------------------------------------------------------------------
struct op_reciprocal
......
......@@ -86,6 +86,24 @@ namespace dlib
R(r,c) == pow(m(r,c),e)
!*/
// ----------------------------------------------------------------------------------------
template <typename T>
const matrix_exp pow (
const T& b,
const matrix_exp& m
);
/*!
requires
- matrix_exp::type == float, double, or long double
ensures
- returns a matrix R such that:
- R::type == the same type that was in m
- R has the same dimensions as m
- for all valid r and c:
R(r,c) == pow(b, m(r,c))
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp squared (
......
......@@ -32,8 +32,8 @@ namespace dlib
ensures
- returns a matrix R such that:
- R::type == long
- R.nr() == abs(end - start)/inc + 1
- R.nc() == 1
- R.nr() == 1
- R.nc() == abs(end - start)/inc + 1
- if (start <= end) then
- R(i) == start + i*inc
- else
......@@ -55,8 +55,8 @@ namespace dlib
ensures
- returns a matrix R such that:
- R::type == long
- R.nr() == abs(end - start)/inc + 1
- R.nc() == 1
- R.nr() == 1
- R.nc() == abs(end - start)/inc + 1
- if (start <= end) then
- R(i) == start + i*inc
- else
......
......@@ -1934,6 +1934,148 @@ namespace dlib
return exp(m.ref(),s);
}
// ----------------------------------------------------------------------------------------
template <typename rand_gen>
inline const matrix<double> randm(
long nr,
long nc,
rand_gen& rnd
)
{
DLIB_ASSERT(nr >= 0 && nc >= 0,
"\tconst matrix randm(nr, nc, rnd)"
<< "\n\tInvalid inputs to this function"
<< "\n\tnr: " << nr
<< "\n\tnc: " << nc
);
matrix<double> m(nr,nc);
for (long r = 0; r < m.nr(); ++r)
{
for (long c = 0; c < m.nc(); ++c)
{
m(r,c) = rnd.get_random_double();
}
}
return m;
}
// ----------------------------------------------------------------------------------------
inline const matrix<double> randm(
long nr,
long nc
)
{
DLIB_ASSERT(nr >= 0 && nc >= 0,
"\tconst matrix randm(nr, nc)"
<< "\n\tInvalid inputs to this function"
<< "\n\tnr: " << nr
<< "\n\tnc: " << nc
);
matrix<double> m(nr,nc);
// make a double that contains RAND_MAX + the smallest number that still
// makes the resulting double slightly bigger than static_cast<double>(RAND_MAX)
double max_val = RAND_MAX;
max_val += std::numeric_limits<double>::epsilon()*RAND_MAX;
for (long r = 0; r < m.nr(); ++r)
{
for (long c = 0; c < m.nc(); ++c)
{
m(r,c) = std::rand()/max_val;
}
}
return m;
}
// ----------------------------------------------------------------------------------------
inline const matrix_range_exp<double> linspace (
double start,
double end,
long num
)
{
DLIB_ASSERT(num >= 0,
"\tconst matrix_exp linspace(start, end, num)"
<< "\n\tInvalid inputs to this function"
<< "\n\tstart: " << start
<< "\n\tend: " << end
<< "\n\tnum: " << num
);
return matrix_range_exp<double>(start,end,num,false);
}
// ----------------------------------------------------------------------------------------
inline const matrix_log_range_exp<double> logspace (
double start,
double end,
long num
)
{
DLIB_ASSERT(num >= 0,
"\tconst matrix_exp logspace(start, end, num)"
<< "\n\tInvalid inputs to this function"
<< "\n\tstart: " << start
<< "\n\tend: " << end
<< "\n\tnum: " << num
);
return matrix_log_range_exp<double>(start,end,num);
}
// ----------------------------------------------------------------------------------------
struct op_cart_prod
{
template <typename EXP1, typename EXP2>
struct op : has_destructive_aliasing
{
const static long cost = EXP1::cost+EXP2::cost+1;
typedef typename EXP1::type type;
typedef typename EXP1::mem_manager_type mem_manager_type;
const static long NR = EXP1::NR+EXP2::NR;
const static long NC = EXP1::NC*EXP2::NC;
template <typename M1, typename M2>
static type apply ( const M1& m1, const M2& m2 , long r, long c)
{
if (r < m1.nr())
return m1(r, c/m2.nc());
else
return m2(r-m1.nr(), c%m2.nc());
}
template <typename M1, typename M2>
static long nr (const M1& m1, const M2& m2) { return m1.nr() + m2.nr(); }
template <typename M1, typename M2>
static long nc (const M1& m1, const M2& m2) { return m1.nc() * m2.nc(); }
};
};
template <
typename EXP1,
typename EXP2
>
const matrix_binary_exp<EXP1,EXP2,op_cart_prod> cartesian_product (
const matrix_exp<EXP1>& a,
const matrix_exp<EXP2>& b
)
{
COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
typedef matrix_binary_exp<EXP1,EXP2,op_cart_prod> exp;
return exp(a.ref(),b.ref());
}
// ----------------------------------------------------------------------------------------
}
......
......@@ -208,6 +208,49 @@ namespace dlib
- returns an N by N identity matrix with elements of type T.
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp linspace (
double start,
double end,
long num
);
/*!
requires
- num >= 0
ensures
- returns a matrix M such that:
- M::type == double
- M.nr() == 1
- M.nc() == num
- M == a row vector with num linearly spaced values beginning with start
and stopping with end.
- M(num-1) == end
- if (num > 1) then
- M(0) == start
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp logspace (
double start,
double end,
long num
);
/*!
requires
- num >= 0
ensures
- returns a matrix M such that:
- M::type == double
- M.nr() == 1
- M.nc() == num
- M == a row vector with num logarithmically spaced values beginning with
10^start and stopping with 10^end.
(i.e. M == pow(10, linspace(start, end, num)))
- M(num-1) == 10^end
!*/
// ----------------------------------------------------------------------------------------
template <
......@@ -493,13 +536,41 @@ namespace dlib
ensures
- returns a matrix R such that:
- R::type == the same type that was in a and b.
- R.nr() == a.nr()*b.nr()
- R.nc() == a.nc()*b.nc()
- R.nr() == a.nr() * b.nr()
- R.nc() == a.nc() * b.nc()
- for all valid r and c:
R(r,c) == a(r/b.nr(), c/b.nc()) * b(r%b.nr(), c%b.nc())
- I.e. R is the tensor product of matrix a with matrix b
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp cartesian_product (
const matrix_exp& A,
const matrix_exp& B
);
/*!
requires
- A and B both contain the same type of element
ensures
- Think of A and B as sets of column vectors. Then this function
returns a matrix that contains a set of column vectors that is
the Cartesian product of the sets A and B. That is, the resulting
matrix contains every possible combination of vectors from both A and
B.
- returns a matrix R such that:
- R::type == the same type that was in A and B.
- R.nr() == A.nr() + B.nr()
- R.nc() == A.nc() * B.nc()
- Each column of R is the concatenation of a column vector
from A with a column vector from B.
- for all valid r and c:
- if (r < A.nr()) then
- R(r,c) == A(r, c/B.nc())
- else
- R(r,c) == B(r-A.nr(), c%B.nc())
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp scale_columns (
......@@ -732,6 +803,49 @@ namespace dlib
- the returned matrix will have m(0).nr() rows and columns.
!*/
// ----------------------------------------------------------------------------------------
template <typename rand_gen>
const matrix<double> randm(
long nr,
long nc,
rand_gen& rnd
);
/*!
requires
- nr >= 0
- nc >= 0
- rand_gen == an object that implements the rand/rand_float_abstract.h interface
ensures
- generates a random matrix using the given rnd random number generator
- returns a matrix M such that
- M::type == double
- M.nr() == nr
- M.nc() == nc
- for all valid i, j:
- M(i,j) == a random number such that 0 <= M(i,j) < 1
!*/
// ----------------------------------------------------------------------------------------
inline const matrix<double> randm(
long nr,
long nc
);
/*!
requires
- nr >= 0
- nc >= 0
ensures
- generates a random matrix using std::rand()
- returns a matrix M such that
- M::type == double
- M.nr() == nr
- M.nc() == nc
- for all valid i, j:
- M(i,j) == a random number such that 0 <= M(i,j) < 1
!*/
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// Pixel and Image Utilities
......
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