Commit 71051985 authored by Davis King's avatar Davis King

code cleanup

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403987
parent 73c7a654
// Copyright (C) 2007 Davis E. King (davis@dlib.net) // Copyright (C) 2010 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license. // License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_SYMMETRIC_MATRIX_CAcHE_H__ #ifndef DLIB_SYMMETRIC_MATRIX_CAcHE_H__
#define DLIB_SYMMETRIC_MATRIX_CAcHE_H__ #define DLIB_SYMMETRIC_MATRIX_CAcHE_H__
//#include "svm_abstract.h" #include "symmetric_matrix_cache_abstract.h"
#include <cmath>
#include <limits>
#include <sstream>
#include <vector> #include <vector>
#include "dlib/matrix.h" #include "../matrix.h"
#include "dlib/algs.h" #include "../algs.h"
#include "dlib/array.h" #include "../array.h"
namespace dlib namespace dlib
{ {
...@@ -198,24 +195,36 @@ namespace dlib ...@@ -198,24 +195,36 @@ namespace dlib
INITIAL VALUE INITIAL VALUE
- for all valid x: - for all valid x:
- lookup(x) == -1 - lookup(x) == -1
- rlookup(x) == -1
- diag_cache == the diagonal of the original matrix
- is_initialized == false
- max_size_megabytes == the max_size_megabytes from symmetric_matrix_cache()
CONVENTION CONVENTION
- if (lookup(c) != -1) then - diag_cache == the diagonal of the original matrix
- cache(lookup(c),*) == the cached column c of the matrix - lookup.size() == diag_cache.size()
- rlookup(lookup(c)) == c
- if (is_initialized) then
- if (lookup[c] != -1) then
- cache[lookup[c]] == the cached column c of the matrix
- rlookup[lookup[c]] == c
- if (rlookup[x] != -1) then
- lookup[rlookup[x]] == x
- cache[x] == the cached column rlookup[x] of the matrix
- if (rlookup(x) != -1) then - next == the next element in the cache table to use to cache something
- lookup(rlookup(x)) == x - references[i] == the number of outstanding references to cache element cache[i]
- cache(x,*) == the cached column rlookup(x) of the matrix
- next == the next row in the cache table to use to cache something - diag_reference_count == the number of outstanding references to diag_cache.
(this isn't really needed. It's just here so that we can reuse the matrix
expression from colm() to implement diag())
!*/ !*/
mutable typename array<matrix<type,0,1,typename M::mem_manager_type> >::expand_1a cache; mutable typename array<matrix<type,0,1,typename M::mem_manager_type> >::expand_1a cache;
mutable typename array<long>::expand_1a references; mutable typename array<long>::expand_1a references;
mutable matrix<type,0,1,typename M::mem_manager_type> diag_cache; matrix<type,0,1,typename M::mem_manager_type> diag_cache;
mutable std::vector<long> lookup; mutable std::vector<long> lookup;
mutable std::vector<long> rlookup; mutable std::vector<long> rlookup;
mutable long next; mutable long next;
...@@ -235,7 +244,10 @@ namespace dlib ...@@ -235,7 +244,10 @@ namespace dlib
long max_size_megabytes long max_size_megabytes
) )
{ {
DLIB_ASSERT(m.size() > 0 && m.nr() == m.nc() && max_size_megabytes > 0, // Don't check that m is symmetric since doing so would be extremely onerous for the
// kinds of matrices intended for use with the symmetric_matrix_cache. Check everything
// else though.
DLIB_ASSERT(m.size() > 0 && m.nr() == m.nc() && max_size_megabytes >= 0,
"\tconst matrix_exp symmetric_matrix_cache(const matrix_exp& m, max_size_megabytes)" "\tconst matrix_exp symmetric_matrix_cache(const matrix_exp& m, max_size_megabytes)"
<< "\n\t You have given invalid arguments to this function" << "\n\t You have given invalid arguments to this function"
<< "\n\t m.nr(): " << m.nr() << "\n\t m.nr(): " << m.nr()
...@@ -344,6 +356,86 @@ namespace dlib ...@@ -344,6 +356,86 @@ namespace dlib
m.ref().op.diag_ref_count())); m.ref().op.diag_ref_count()));
} }
// ----------------------------------------------------------------------------------------
template <typename M, typename cache_element_type>
struct op_rowm_symm_cache
{
typedef cache_element_type type;
op_rowm_symm_cache(
const M& m_,
const type* data_,
long* ref_count_
) :
m(m_),
data(data_),
ref_count(ref_count_)
{
*ref_count += 1;
}
op_rowm_symm_cache (
const op_rowm_symm_cache& item
) :
m(item.m),
data(item.data),
ref_count(item.ref_count)
{
*ref_count += 1;
}
~op_rowm_symm_cache(
)
{
*ref_count -= 1;
}
const M& m;
const type* const data;
long* const ref_count;
const static long cost = M::cost;
const static long NR = 1;
const static long NC = M::NC;
typedef const type& const_ret_type;
typedef typename M::mem_manager_type mem_manager_type;
typedef typename M::layout_type layout_type;
inline const_ret_type apply ( long , long c) const { return data[c]; }
long nr () const { return 1; }
long nc () const { return m.nc(); }
template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
};
template <
typename EXP,
typename cache_element_type
>
inline const matrix_op<op_rowm_symm_cache<EXP,cache_element_type> > rowm (
const matrix_exp<matrix_op<op_symm_cache<EXP,cache_element_type> > >& m,
long row
)
{
DLIB_ASSERT(row >= 0 && row < m.nr(),
"\tconst matrix_exp rowm(const matrix_exp& m, row)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\trow: " << row
);
std::pair<const cache_element_type*,long*> p = m.ref().op.col(row);
typedef op_rowm_symm_cache<EXP,cache_element_type> op;
return matrix_op<op>(op(m.ref().op.m,
p.first,
p.second));
}
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP> template <typename EXP>
...@@ -352,6 +444,12 @@ namespace dlib ...@@ -352,6 +444,12 @@ namespace dlib
typedef matrix_op<op_colm<EXP> > type; typedef matrix_op<op_colm<EXP> > type;
}; };
template <typename EXP>
struct rowm_exp
{
typedef matrix_op<op_rowm<EXP> > type;
};
template <typename EXP> template <typename EXP>
struct diag_exp struct diag_exp
{ {
...@@ -366,6 +464,12 @@ namespace dlib ...@@ -366,6 +464,12 @@ namespace dlib
typedef matrix_op<op_colm_symm_cache<EXP, cache_element_type> > type; typedef matrix_op<op_colm_symm_cache<EXP, cache_element_type> > type;
}; };
template <typename EXP, typename cache_element_type>
struct rowm_exp<matrix_op<op_symm_cache<EXP, cache_element_type> > >
{
typedef matrix_op<op_rowm_symm_cache<EXP, cache_element_type> > type;
};
template <typename EXP, typename cache_element_type> template <typename EXP, typename cache_element_type>
struct diag_exp<matrix_op<op_symm_cache<EXP, cache_element_type> > > struct diag_exp<matrix_op<op_symm_cache<EXP, cache_element_type> > >
{ {
......
// Copyright (C) 2010 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#define DLIB_SYMMETRIC_MATRIX_CAcHE_ABSTRACT_H__
#ifndef DLIB_SYMMETRIC_MATRIX_CAcHE_ABSTRACT_H__
#include "matrix_abstract.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
template <
typename cache_element_type
>
const matrix_exp symmetric_matrix_cache (
const matrix_exp& m,
long max_size_megabytes
);
/*!
requires
- m.size() > 0
- m.nr() == m.nc()
- m must be a symmetric matrix (i.e. m == trans(m))
- max_size_megabytes >= 0
ensures
- This method creates a matrix expression which internally caches the elements
of m so that they can be accessed quickly. It is useful if m is some kind of
complex matrix expression which is both very large and expensive to evaluate.
An example would be a kernel_matrix() expression with an expensive kernel and
a large number of samples. Such an expression would result in a huge matrix,
probably too big to store in memory. The symmetric_matrix_cache() then makes
it easy to store just the parts of a matrix expression in memory which are
accessed most often. The specific details are defined below.
- returns a matrix M such that
- M == m
(i.e. M represents the same matrix as m)
- M will cache elements of m and hold them internally so they can be quickly
accessed. In particular, M will attempt to allocate no more than
max_size_megabytes megabytes of memory for the purposes of caching
elements of m. When an element of the matrix is accessed it is either
retrieved from the cache, or if this is not possible, then an entire
column of m is loaded into a part of the cache which hasn't been used
recently and the needed element returned.
- diag(m) is always loaded into the cache and is stored separately from
the cached columns. That means accesses to the diagonal elements of m
are always fast.
- M will store the cached elements of m as cache_element_type objects.
Typically, cache_element_type will be float or double.
- To avoid repeated cache lookups, the following operations are optimized for
use with the symmetric_matrix_cache():
- diag(M), rowm(M,row_idx), colm(M,col_idx)
These methods will perform only one cache lookup operation for an
entire row/column/diagonal worth of data.
!*/
// ----------------------------------------------------------------------------------------
template <typename EXP>
struct colm_exp
{
typedef matrix_op<op_colm<EXP> > type;
};
template <typename EXP>
struct rowm_exp
{
typedef matrix_op<op_rowm<EXP> > type;
};
template <typename EXP>
struct diag_exp
{
typedef matrix_op<op_diag<EXP> > type;
};
// ----------------------------------------------------------------------------------------
template <typename EXP, typename cache_element_type>
struct colm_exp<matrix_op<op_symm_cache<EXP, cache_element_type> > >
{
typedef matrix_op<op_colm_symm_cache<EXP, cache_element_type> > type;
};
template <typename EXP, typename cache_element_type>
struct rowm_exp<matrix_op<op_symm_cache<EXP, cache_element_type> > >
{
typedef matrix_op<op_rowm_symm_cache<EXP, cache_element_type> > type;
};
template <typename EXP, typename cache_element_type>
struct diag_exp<matrix_op<op_symm_cache<EXP, cache_element_type> > >
{
typedef matrix_op<op_colm_symm_cache<EXP, cache_element_type> > type;
};
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_SYMMETRIC_MATRIX_CAcHE_ABSTRACT_H__
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