summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/conditioning_class
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/conditioning_class')
-rw-r--r--ml/dlib/dlib/conditioning_class/conditioning_class_kernel_1.h333
-rw-r--r--ml/dlib/dlib/conditioning_class/conditioning_class_kernel_2.h500
-rw-r--r--ml/dlib/dlib/conditioning_class/conditioning_class_kernel_3.h438
-rw-r--r--ml/dlib/dlib/conditioning_class/conditioning_class_kernel_4.h533
-rw-r--r--ml/dlib/dlib/conditioning_class/conditioning_class_kernel_abstract.h228
-rw-r--r--ml/dlib/dlib/conditioning_class/conditioning_class_kernel_c.h162
6 files changed, 2194 insertions, 0 deletions
diff --git a/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_1.h b/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_1.h
new file mode 100644
index 000000000..d26d80244
--- /dev/null
+++ b/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_1.h
@@ -0,0 +1,333 @@
+// Copyright (C) 2003 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#ifndef DLIB_CONDITIONING_CLASS_KERNEl_1_
+#define DLIB_CONDITIONING_CLASS_KERNEl_1_
+
+#include "conditioning_class_kernel_abstract.h"
+#include "../assert.h"
+#include "../algs.h"
+
+namespace dlib
+{
+
+ template <
+ unsigned long alphabet_size
+ >
+ class conditioning_class_kernel_1
+ {
+ /*!
+ INITIAL VALUE
+ total == 1
+ counts == pointer to an array of alphabet_size unsigned shorts
+ for all i except i == alphabet_size-1: counts[i] == 0
+ counts[alphabet_size-1] == 1
+
+ CONVENTION
+ counts == pointer to an array of alphabet_size unsigned shorts
+ get_total() == total
+ get_count(symbol) == counts[symbol]
+
+ LOW_COUNT(symbol) == sum of counts[0] though counts[symbol-1]
+ or 0 if symbol == 0
+
+ get_memory_usage() == global_state.memory_usage
+ !*/
+
+ public:
+
+ class global_state_type
+ {
+ public:
+ global_state_type () : memory_usage(0) {}
+ private:
+ unsigned long memory_usage;
+
+ friend class conditioning_class_kernel_1<alphabet_size>;
+ };
+
+ conditioning_class_kernel_1 (
+ global_state_type& global_state_
+ );
+
+ ~conditioning_class_kernel_1 (
+ );
+
+ void clear(
+ );
+
+ bool increment_count (
+ unsigned long symbol,
+ unsigned short amount = 1
+ );
+
+ unsigned long get_count (
+ unsigned long symbol
+ ) const;
+
+ unsigned long get_total (
+ ) const;
+
+ unsigned long get_range (
+ unsigned long symbol,
+ unsigned long& low_count,
+ unsigned long& high_count,
+ unsigned long& total_count
+ ) const;
+
+ void get_symbol (
+ unsigned long target,
+ unsigned long& symbol,
+ unsigned long& low_count,
+ unsigned long& high_count
+ ) const;
+
+ unsigned long get_memory_usage (
+ ) const;
+
+ global_state_type& get_global_state (
+ );
+
+ static unsigned long get_alphabet_size (
+ );
+
+
+ private:
+
+ // restricted functions
+ conditioning_class_kernel_1(conditioning_class_kernel_1<alphabet_size>&); // copy constructor
+ conditioning_class_kernel_1& operator=(conditioning_class_kernel_1<alphabet_size>&); // assignment operator
+
+ // data members
+ unsigned short total;
+ unsigned short* counts;
+ global_state_type& global_state;
+
+ };
+
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+ // member function definitions
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ conditioning_class_kernel_1<alphabet_size>::
+ conditioning_class_kernel_1 (
+ global_state_type& global_state_
+ ) :
+ total(1),
+ counts(new unsigned short[alphabet_size]),
+ global_state(global_state_)
+ {
+ COMPILE_TIME_ASSERT( 1 < alphabet_size && alphabet_size < 65536 );
+
+ unsigned short* start = counts;
+ unsigned short* end = counts+alphabet_size-1;
+ while (start != end)
+ {
+ *start = 0;
+ ++start;
+ }
+ *start = 1;
+
+ // update memory usage
+ global_state.memory_usage += sizeof(unsigned short)*alphabet_size +
+ sizeof(conditioning_class_kernel_1);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ conditioning_class_kernel_1<alphabet_size>::
+ ~conditioning_class_kernel_1 (
+ )
+ {
+ delete [] counts;
+ // update memory usage
+ global_state.memory_usage -= sizeof(unsigned short)*alphabet_size +
+ sizeof(conditioning_class_kernel_1);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ void conditioning_class_kernel_1<alphabet_size>::
+ clear(
+ )
+ {
+ total = 1;
+ unsigned short* start = counts;
+ unsigned short* end = counts+alphabet_size-1;
+ while (start != end)
+ {
+ *start = 0;
+ ++start;
+ }
+ *start = 1;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ unsigned long conditioning_class_kernel_1<alphabet_size>::
+ get_memory_usage(
+ ) const
+ {
+ return global_state.memory_usage;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ typename conditioning_class_kernel_1<alphabet_size>::global_state_type& conditioning_class_kernel_1<alphabet_size>::
+ get_global_state(
+ )
+ {
+ return global_state;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ bool conditioning_class_kernel_1<alphabet_size>::
+ increment_count (
+ unsigned long symbol,
+ unsigned short amount
+ )
+ {
+ // if we are going over a total of 65535 then scale down all counts by 2
+ if (static_cast<unsigned long>(total)+static_cast<unsigned long>(amount) >= 65536)
+ {
+ total = 0;
+ unsigned short* start = counts;
+ unsigned short* end = counts+alphabet_size;
+ while (start != end)
+ {
+ *start >>= 1;
+ total += *start;
+ ++start;
+ }
+ // make sure it is at least one
+ if (counts[alphabet_size-1]==0)
+ {
+ ++total;
+ counts[alphabet_size-1] = 1;
+ }
+ }
+ counts[symbol] += amount;
+ total += amount;
+ return true;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ unsigned long conditioning_class_kernel_1<alphabet_size>::
+ get_count (
+ unsigned long symbol
+ ) const
+ {
+ return counts[symbol];
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ unsigned long conditioning_class_kernel_1<alphabet_size>::
+ get_alphabet_size (
+ )
+ {
+ return alphabet_size;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ unsigned long conditioning_class_kernel_1<alphabet_size>::
+ get_total (
+ ) const
+ {
+ return total;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ unsigned long conditioning_class_kernel_1<alphabet_size>::
+ get_range (
+ unsigned long symbol,
+ unsigned long& low_count,
+ unsigned long& high_count,
+ unsigned long& total_count
+ ) const
+ {
+ if (counts[symbol] == 0)
+ return 0;
+
+ total_count = total;
+
+ const unsigned short* start = counts;
+ const unsigned short* end = counts+symbol;
+ unsigned short high_count_temp = *start;
+ while (start != end)
+ {
+ ++start;
+ high_count_temp += *start;
+ }
+ low_count = high_count_temp - *start;
+ high_count = high_count_temp;
+ return *start;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ void conditioning_class_kernel_1<alphabet_size>::
+ get_symbol (
+ unsigned long target,
+ unsigned long& symbol,
+ unsigned long& low_count,
+ unsigned long& high_count
+ ) const
+ {
+ unsigned long high_count_temp = *counts;
+ const unsigned short* start = counts;
+ while (target >= high_count_temp)
+ {
+ ++start;
+ high_count_temp += *start;
+ }
+
+ low_count = high_count_temp - *start;
+ high_count = high_count_temp;
+ symbol = static_cast<unsigned long>(start-counts);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+}
+
+#endif // DLIB_CONDITIONING_CLASS_KERNEl_1_
+
diff --git a/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_2.h b/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_2.h
new file mode 100644
index 000000000..c9b38c8e3
--- /dev/null
+++ b/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_2.h
@@ -0,0 +1,500 @@
+// Copyright (C) 2003 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#ifndef DLIB_CONDITIONING_CLASS_KERNEl_2_
+#define DLIB_CONDITIONING_CLASS_KERNEl_2_
+
+#include "conditioning_class_kernel_abstract.h"
+#include "../assert.h"
+#include "../algs.h"
+
+namespace dlib
+{
+
+ template <
+ unsigned long alphabet_size
+ >
+ class conditioning_class_kernel_2
+ {
+ /*!
+ INITIAL VALUE
+ total == 1
+ symbols == pointer to array of alphabet_size data structs
+ for all i except i == alphabet_size-1: symbols[i].count == 0
+ symbols[i].left_count == 0
+
+ symbols[alphabet_size-1].count == 1
+ symbols[alpahbet_size-1].left_count == 0
+
+ CONVENTION
+ symbols == pointer to array of alphabet_size data structs
+ get_total() == total
+ get_count(symbol) == symbols[symbol].count
+
+ symbols is organized as a tree with symbols[0] as the root.
+
+ the left subchild of symbols[i] is symbols[i*2+1] and
+ the right subchild is symbols[i*2+2].
+ the partent of symbols[i] == symbols[(i-1)/2]
+
+ symbols[i].left_count == the sum of the counts of all the
+ symbols to the left of symbols[i]
+
+ get_memory_usage() == global_state.memory_usage
+ !*/
+
+ public:
+
+ class global_state_type
+ {
+ public:
+ global_state_type () : memory_usage(0) {}
+ private:
+ unsigned long memory_usage;
+
+ friend class conditioning_class_kernel_2<alphabet_size>;
+ };
+
+ conditioning_class_kernel_2 (
+ global_state_type& global_state_
+ );
+
+ ~conditioning_class_kernel_2 (
+ );
+
+ void clear(
+ );
+
+ bool increment_count (
+ unsigned long symbol,
+ unsigned short amount = 1
+ );
+
+ unsigned long get_count (
+ unsigned long symbol
+ ) const;
+
+ inline unsigned long get_total (
+ ) const;
+
+ unsigned long get_range (
+ unsigned long symbol,
+ unsigned long& low_count,
+ unsigned long& high_count,
+ unsigned long& total_count
+ ) const;
+
+ void get_symbol (
+ unsigned long target,
+ unsigned long& symbol,
+ unsigned long& low_count,
+ unsigned long& high_count
+ ) const;
+
+ unsigned long get_memory_usage (
+ ) const;
+
+ global_state_type& get_global_state (
+ );
+
+ static unsigned long get_alphabet_size (
+ );
+
+ private:
+
+ // restricted functions
+ conditioning_class_kernel_2(conditioning_class_kernel_2<alphabet_size>&); // copy constructor
+ conditioning_class_kernel_2& operator=(conditioning_class_kernel_2<alphabet_size>&); // assignment operator
+
+ // data members
+ unsigned short total;
+ struct data
+ {
+ unsigned short count;
+ unsigned short left_count;
+ };
+
+ data* symbols;
+ global_state_type& global_state;
+
+ };
+
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+ // member function definitions
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ conditioning_class_kernel_2<alphabet_size>::
+ conditioning_class_kernel_2 (
+ global_state_type& global_state_
+ ) :
+ total(1),
+ symbols(new data[alphabet_size]),
+ global_state(global_state_)
+ {
+ COMPILE_TIME_ASSERT( 1 < alphabet_size && alphabet_size < 65536 );
+
+ data* start = symbols;
+ data* end = symbols + alphabet_size-1;
+
+ while (start != end)
+ {
+ start->count = 0;
+ start->left_count = 0;
+ ++start;
+ }
+
+ start->count = 1;
+ start->left_count = 0;
+
+
+ // update the left_counts for the symbol alphabet_size-1
+ unsigned short temp;
+ unsigned long symbol = alphabet_size-1;
+ while (symbol != 0)
+ {
+ // temp will be 1 if symbol is odd, 0 if it is even
+ temp = static_cast<unsigned short>(symbol&0x1);
+
+ // set symbol to its parent
+ symbol = (symbol-1)>>1;
+
+ // note that all left subchidren are odd and also that
+ // if symbol was a left subchild then we want to increment
+ // its parents left_count
+ if (temp)
+ ++symbols[symbol].left_count;
+ }
+
+ global_state.memory_usage += sizeof(data)*alphabet_size +
+ sizeof(conditioning_class_kernel_2);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ conditioning_class_kernel_2<alphabet_size>::
+ ~conditioning_class_kernel_2 (
+ )
+ {
+ delete [] symbols;
+ global_state.memory_usage -= sizeof(data)*alphabet_size +
+ sizeof(conditioning_class_kernel_2);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ void conditioning_class_kernel_2<alphabet_size>::
+ clear(
+ )
+ {
+ data* start = symbols;
+ data* end = symbols + alphabet_size-1;
+
+ total = 1;
+
+ while (start != end)
+ {
+ start->count = 0;
+ start->left_count = 0;
+ ++start;
+ }
+
+ start->count = 1;
+ start->left_count = 0;
+
+ // update the left_counts
+ unsigned short temp;
+ unsigned long symbol = alphabet_size-1;
+ while (symbol != 0)
+ {
+ // temp will be 1 if symbol is odd, 0 if it is even
+ temp = static_cast<unsigned short>(symbol&0x1);
+
+ // set symbol to its parent
+ symbol = (symbol-1)>>1;
+
+ // note that all left subchidren are odd and also that
+ // if symbol was a left subchild then we want to increment
+ // its parents left_count
+ symbols[symbol].left_count += temp;
+ }
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ unsigned long conditioning_class_kernel_2<alphabet_size>::
+ get_memory_usage(
+ ) const
+ {
+ return global_state.memory_usage;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ typename conditioning_class_kernel_2<alphabet_size>::global_state_type& conditioning_class_kernel_2<alphabet_size>::
+ get_global_state(
+ )
+ {
+ return global_state;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ bool conditioning_class_kernel_2<alphabet_size>::
+ increment_count (
+ unsigned long symbol,
+ unsigned short amount
+ )
+ {
+ // if we need to renormalize then do so
+ if (static_cast<unsigned long>(total)+static_cast<unsigned long>(amount) >= 65536)
+ {
+ unsigned long s;
+ unsigned short temp;
+ for (unsigned short i = 0; i < alphabet_size-1; ++i)
+ {
+ s = i;
+
+ // divide the count for this symbol by 2
+ symbols[i].count >>= 1;
+
+ symbols[i].left_count = 0;
+
+ // bubble this change up though the tree
+ while (s != 0)
+ {
+ // temp will be 1 if symbol is odd, 0 if it is even
+ temp = static_cast<unsigned short>(s&0x1);
+
+ // set s to its parent
+ s = (s-1)>>1;
+
+ // note that all left subchidren are odd and also that
+ // if s was a left subchild then we want to increment
+ // its parents left_count
+ if (temp)
+ symbols[s].left_count += symbols[i].count;
+ }
+ }
+
+ // update symbols alphabet_size-1
+ {
+ s = alphabet_size-1;
+
+ // divide alphabet_size-1 symbol by 2 if it's > 1
+ if (symbols[alphabet_size-1].count > 1)
+ symbols[alphabet_size-1].count >>= 1;
+
+ // bubble this change up though the tree
+ while (s != 0)
+ {
+ // temp will be 1 if symbol is odd, 0 if it is even
+ temp = static_cast<unsigned short>(s&0x1);
+
+ // set s to its parent
+ s = (s-1)>>1;
+
+ // note that all left subchidren are odd and also that
+ // if s was a left subchild then we want to increment
+ // its parents left_count
+ if (temp)
+ symbols[s].left_count += symbols[alphabet_size-1].count;
+ }
+ }
+
+
+
+
+
+
+ // calculate the new total
+ total = 0;
+ unsigned long m = 0;
+ while (m < alphabet_size)
+ {
+ total += symbols[m].count + symbols[m].left_count;
+ m = (m<<1) + 2;
+ }
+
+ }
+
+
+
+
+ // increment the count for the specified symbol
+ symbols[symbol].count += amount;;
+ total += amount;
+
+
+ unsigned short temp;
+ while (symbol != 0)
+ {
+ // temp will be 1 if symbol is odd, 0 if it is even
+ temp = static_cast<unsigned short>(symbol&0x1);
+
+ // set symbol to its parent
+ symbol = (symbol-1)>>1;
+
+ // note that all left subchidren are odd and also that
+ // if symbol was a left subchild then we want to increment
+ // its parents left_count
+ if (temp)
+ symbols[symbol].left_count += amount;
+ }
+
+ return true;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ unsigned long conditioning_class_kernel_2<alphabet_size>::
+ get_count (
+ unsigned long symbol
+ ) const
+ {
+ return symbols[symbol].count;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ unsigned long conditioning_class_kernel_2<alphabet_size>::
+ get_alphabet_size (
+ )
+ {
+ return alphabet_size;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ unsigned long conditioning_class_kernel_2<alphabet_size>::
+ get_total (
+ ) const
+ {
+ return total;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ unsigned long conditioning_class_kernel_2<alphabet_size>::
+ get_range (
+ unsigned long symbol,
+ unsigned long& low_count,
+ unsigned long& high_count,
+ unsigned long& total_count
+ ) const
+ {
+ if (symbols[symbol].count == 0)
+ return 0;
+
+ unsigned long current = symbol;
+ total_count = total;
+ unsigned long high_count_temp = 0;
+ bool came_from_right = true;
+ while (true)
+ {
+ if (came_from_right)
+ {
+ high_count_temp += symbols[current].count + symbols[current].left_count;
+ }
+
+ // note that if current is even then it is a right child
+ came_from_right = !(current&0x1);
+
+ if (current == 0)
+ break;
+
+ // set current to its parent
+ current = (current-1)>>1 ;
+ }
+
+
+ low_count = high_count_temp - symbols[symbol].count;
+ high_count = high_count_temp;
+
+ return symbols[symbol].count;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ void conditioning_class_kernel_2<alphabet_size>::
+ get_symbol (
+ unsigned long target,
+ unsigned long& symbol,
+ unsigned long& low_count,
+ unsigned long& high_count
+ ) const
+ {
+ unsigned long current = 0;
+ unsigned long low_count_temp = 0;
+
+ while (true)
+ {
+ if (static_cast<unsigned short>(target) < symbols[current].left_count)
+ {
+ // we should go left
+ current = (current<<1) + 1;
+ }
+ else
+ {
+ target -= symbols[current].left_count;
+ low_count_temp += symbols[current].left_count;
+ if (static_cast<unsigned short>(target) < symbols[current].count)
+ {
+ // we have found our target
+ symbol = current;
+ high_count = low_count_temp + symbols[current].count;
+ low_count = low_count_temp;
+ break;
+ }
+ else
+ {
+ // go right
+ target -= symbols[current].count;
+ low_count_temp += symbols[current].count;
+ current = (current<<1) + 2;
+ }
+ }
+
+ }
+
+ }
+
+// ----------------------------------------------------------------------------------------
+
+}
+
+#endif // DLIB_CONDITIONING_CLASS_KERNEl_1_
+
diff --git a/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_3.h b/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_3.h
new file mode 100644
index 000000000..b6de48555
--- /dev/null
+++ b/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_3.h
@@ -0,0 +1,438 @@
+// Copyright (C) 2004 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#ifndef DLIB_CONDITIONING_CLASS_KERNEl_3_
+#define DLIB_CONDITIONING_CLASS_KERNEl_3_
+
+#include "conditioning_class_kernel_abstract.h"
+#include "../assert.h"
+#include "../algs.h"
+
+
+namespace dlib
+{
+
+ template <
+ unsigned long alphabet_size
+ >
+ class conditioning_class_kernel_3
+ {
+ /*!
+ INITIAL VALUE
+ total == 1
+ counts == pointer to an array of alphabet_size data structs
+ for all i except i == 0: counts[i].count == 0
+ counts[0].count == 1
+ counts[0].symbol == alphabet_size-1
+ for all i except i == alphabet_size-1: counts[i].present == false
+ counts[alphabet_size-1].present == true
+
+ CONVENTION
+ counts == pointer to an array of alphabet_size data structs
+ get_total() == total
+ get_count(symbol) == counts[x].count where
+ counts[x].symbol == symbol
+
+
+ LOW_COUNT(symbol) == sum of counts[0].count though counts[x-1].count
+ where counts[x].symbol == symbol
+ if (counts[0].symbol == symbol) LOW_COUNT(symbol)==0
+
+
+ if (counts[i].count == 0) then
+ counts[i].symbol == undefined value
+
+ if (symbol has a nonzero count) then
+ counts[symbol].present == true
+
+ get_memory_usage() == global_state.memory_usage
+ !*/
+
+ public:
+
+ class global_state_type
+ {
+ public:
+ global_state_type () : memory_usage(0) {}
+ private:
+ unsigned long memory_usage;
+
+ friend class conditioning_class_kernel_3<alphabet_size>;
+ };
+
+ conditioning_class_kernel_3 (
+ global_state_type& global_state_
+ );
+
+ ~conditioning_class_kernel_3 (
+ );
+
+ void clear(
+ );
+
+ bool increment_count (
+ unsigned long symbol,
+ unsigned short amount = 1
+ );
+
+ unsigned long get_count (
+ unsigned long symbol
+ ) const;
+
+ unsigned long get_total (
+ ) const;
+
+ unsigned long get_range (
+ unsigned long symbol,
+ unsigned long& low_count,
+ unsigned long& high_count,
+ unsigned long& total_count
+ ) const;
+
+ void get_symbol (
+ unsigned long target,
+ unsigned long& symbol,
+ unsigned long& low_count,
+ unsigned long& high_count
+ ) const;
+
+ unsigned long get_memory_usage (
+ ) const;
+
+ global_state_type& get_global_state (
+ );
+
+ static unsigned long get_alphabet_size (
+ );
+
+ private:
+
+ // restricted functions
+ conditioning_class_kernel_3(conditioning_class_kernel_3<alphabet_size>&); // copy constructor
+ conditioning_class_kernel_3& operator=(conditioning_class_kernel_3<alphabet_size>&); // assignment operator
+
+ struct data
+ {
+ unsigned short count;
+ unsigned short symbol;
+ bool present;
+ };
+
+ // data members
+ unsigned short total;
+ data* counts;
+ global_state_type& global_state;
+
+ };
+
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+ // member function definitions
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ conditioning_class_kernel_3<alphabet_size>::
+ conditioning_class_kernel_3 (
+ global_state_type& global_state_
+ ) :
+ total(1),
+ counts(new data[alphabet_size]),
+ global_state(global_state_)
+ {
+ COMPILE_TIME_ASSERT( 1 < alphabet_size && alphabet_size < 65536 );
+
+ data* start = counts;
+ data* end = counts+alphabet_size;
+ start->count = 1;
+ start->symbol = alphabet_size-1;
+ start->present = false;
+ ++start;
+ while (start != end)
+ {
+ start->count = 0;
+ start->present = false;
+ ++start;
+ }
+ counts[alphabet_size-1].present = true;
+
+ // update memory usage
+ global_state.memory_usage += sizeof(data)*alphabet_size +
+ sizeof(conditioning_class_kernel_3);
+
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ conditioning_class_kernel_3<alphabet_size>::
+ ~conditioning_class_kernel_3 (
+ )
+ {
+ delete [] counts;
+ // update memory usage
+ global_state.memory_usage -= sizeof(data)*alphabet_size +
+ sizeof(conditioning_class_kernel_3);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ void conditioning_class_kernel_3<alphabet_size>::
+ clear(
+ )
+ {
+ total = 1;
+ data* start = counts;
+ data* end = counts+alphabet_size;
+ start->count = 1;
+ start->symbol = alphabet_size-1;
+ start->present = false;
+ ++start;
+ while (start != end)
+ {
+ start->count = 0;
+ start->present = false;
+ ++start;
+ }
+ counts[alphabet_size-1].present = true;
+
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ typename conditioning_class_kernel_3<alphabet_size>::global_state_type& conditioning_class_kernel_3<alphabet_size>::
+ get_global_state(
+ )
+ {
+ return global_state;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ unsigned long conditioning_class_kernel_3<alphabet_size>::
+ get_memory_usage(
+ ) const
+ {
+ return global_state.memory_usage;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ bool conditioning_class_kernel_3<alphabet_size>::
+ increment_count (
+ unsigned long symbol,
+ unsigned short amount
+ )
+ {
+ // if we are going over a total of 65535 then scale down all counts by 2
+ if (static_cast<unsigned long>(total)+static_cast<unsigned long>(amount) >= 65536)
+ {
+ total = 0;
+ data* start = counts;
+ data* end = counts+alphabet_size;
+
+ while (start != end)
+ {
+ if (start->count == 1)
+ {
+ if (start->symbol == alphabet_size-1)
+ {
+ // this symbol must never be zero so we will leave its count at 1
+ ++total;
+ }
+ else
+ {
+ start->count = 0;
+ counts[start->symbol].present = false;
+ }
+ }
+ else
+ {
+ start->count >>= 1;
+ total += start->count;
+ }
+
+ ++start;
+ }
+ }
+
+
+ data* start = counts;
+ data* swap_spot = counts;
+
+ if (counts[symbol].present)
+ {
+ while (true)
+ {
+ if (start->symbol == symbol && start->count!=0)
+ {
+ unsigned short temp = start->count + amount;
+
+ start->symbol = swap_spot->symbol;
+ start->count = swap_spot->count;
+
+ swap_spot->symbol = static_cast<unsigned short>(symbol);
+ swap_spot->count = temp;
+ break;
+ }
+
+ if ( (start->count) < (swap_spot->count))
+ {
+ swap_spot = start;
+ }
+
+
+ ++start;
+ }
+ }
+ else
+ {
+ counts[symbol].present = true;
+ while (true)
+ {
+ if (start->count == 0)
+ {
+ start->symbol = swap_spot->symbol;
+ start->count = swap_spot->count;
+
+ swap_spot->symbol = static_cast<unsigned short>(symbol);
+ swap_spot->count = amount;
+ break;
+ }
+
+ if ((start->count) < (swap_spot->count))
+ {
+ swap_spot = start;
+ }
+
+ ++start;
+ }
+ }
+
+ total += amount;
+
+ return true;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ unsigned long conditioning_class_kernel_3<alphabet_size>::
+ get_count (
+ unsigned long symbol
+ ) const
+ {
+ if (counts[symbol].present == false)
+ return 0;
+
+ data* start = counts;
+ while (start->symbol != symbol)
+ {
+ ++start;
+ }
+ return start->count;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ unsigned long conditioning_class_kernel_3<alphabet_size>::
+ get_alphabet_size (
+ )
+ {
+ return alphabet_size;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ unsigned long conditioning_class_kernel_3<alphabet_size>::
+ get_total (
+ ) const
+ {
+ return total;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ unsigned long conditioning_class_kernel_3<alphabet_size>::
+ get_range (
+ unsigned long symbol,
+ unsigned long& low_count,
+ unsigned long& high_count,
+ unsigned long& total_count
+ ) const
+ {
+ if (counts[symbol].present == false)
+ return 0;
+
+ total_count = total;
+ unsigned long low_count_temp = 0;
+ data* start = counts;
+ while (start->symbol != symbol)
+ {
+ low_count_temp += start->count;
+ ++start;
+ }
+
+ low_count = low_count_temp;
+ high_count = low_count_temp + start->count;
+ return start->count;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size
+ >
+ void conditioning_class_kernel_3<alphabet_size>::
+ get_symbol (
+ unsigned long target,
+ unsigned long& symbol,
+ unsigned long& low_count,
+ unsigned long& high_count
+ ) const
+ {
+ unsigned long high_count_temp = counts->count;
+ const data* start = counts;
+ while (target >= high_count_temp)
+ {
+ ++start;
+ high_count_temp += start->count;
+ }
+
+ low_count = high_count_temp - start->count;
+ high_count = high_count_temp;
+ symbol = static_cast<unsigned long>(start->symbol);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+}
+
+#endif // DLIB_CONDITIONING_CLASS_KERNEl_3_
+
diff --git a/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_4.h b/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_4.h
new file mode 100644
index 000000000..cb48ac196
--- /dev/null
+++ b/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_4.h
@@ -0,0 +1,533 @@
+// Copyright (C) 2004 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#ifndef DLIB_CONDITIONING_CLASS_KERNEl_4_
+#define DLIB_CONDITIONING_CLASS_KERNEl_4_
+
+#include "conditioning_class_kernel_abstract.h"
+#include "../assert.h"
+#include "../algs.h"
+
+namespace dlib
+{
+ template <
+ unsigned long alphabet_size,
+ unsigned long pool_size,
+ typename mem_manager
+ >
+ class conditioning_class_kernel_4
+ {
+ /*!
+ REQUIREMENTS ON pool_size
+ pool_size > 0
+ this will be the number of nodes contained in our memory pool
+
+ REQUIREMENTS ON mem_manager
+ mem_manager is an implementation of memory_manager/memory_manager_kernel_abstract.h
+
+ INITIAL VALUE
+ total == 1
+ escapes == 1
+ next == 0
+
+ CONVENTION
+ get_total() == total
+ get_count(alphabet_size-1) == escapes
+
+ if (next != 0) then
+ next == pointer to the start of a linked list and the linked list
+ is terminated by a node with a next pointer of 0.
+
+ get_count(symbol) == node::count for the node where node::symbol==symbol
+ or 0 if no such node currently exists.
+
+ if (there is a node for the symbol) then
+ LOW_COUNT(symbol) == the sum of all node's counts in the linked list
+ up to but not including the node for the symbol.
+
+ get_memory_usage() == global_state.memory_usage
+ !*/
+
+
+ struct node
+ {
+ unsigned short symbol;
+ unsigned short count;
+ node* next;
+ };
+
+ public:
+
+ class global_state_type
+ {
+ public:
+ global_state_type (
+ ) :
+ memory_usage(pool_size*sizeof(node)+sizeof(global_state_type))
+ {}
+ private:
+ unsigned long memory_usage;
+
+ typename mem_manager::template rebind<node>::other pool;
+
+ friend class conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>;
+ };
+
+ conditioning_class_kernel_4 (
+ global_state_type& global_state_
+ );
+
+ ~conditioning_class_kernel_4 (
+ );
+
+ void clear(
+ );
+
+ bool increment_count (
+ unsigned long symbol,
+ unsigned short amount = 1
+ );
+
+ unsigned long get_count (
+ unsigned long symbol
+ ) const;
+
+ inline unsigned long get_total (
+ ) const;
+
+ unsigned long get_range (
+ unsigned long symbol,
+ unsigned long& low_count,
+ unsigned long& high_count,
+ unsigned long& total_count
+ ) const;
+
+ void get_symbol (
+ unsigned long target,
+ unsigned long& symbol,
+ unsigned long& low_count,
+ unsigned long& high_count
+ ) const;
+
+ unsigned long get_memory_usage (
+ ) const;
+
+ global_state_type& get_global_state (
+ );
+
+ static unsigned long get_alphabet_size (
+ );
+
+
+ private:
+
+ void half_counts (
+ );
+ /*!
+ ensures
+ - divides all counts by 2 but ensures that escapes is always at least 1
+ !*/
+
+ // restricted functions
+ conditioning_class_kernel_4(conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>&); // copy constructor
+ conditioning_class_kernel_4& operator=(conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>&); // assignment operator
+
+ // data members
+ unsigned short total;
+ unsigned short escapes;
+ node* next;
+ global_state_type& global_state;
+
+ };
+
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+ // member function definitions
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size,
+ unsigned long pool_size,
+ typename mem_manager
+ >
+ conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>::
+ conditioning_class_kernel_4 (
+ global_state_type& global_state_
+ ) :
+ total(1),
+ escapes(1),
+ next(0),
+ global_state(global_state_)
+ {
+ COMPILE_TIME_ASSERT( 1 < alphabet_size && alphabet_size < 65536 );
+
+ // update memory usage
+ global_state.memory_usage += sizeof(conditioning_class_kernel_4);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size,
+ unsigned long pool_size,
+ typename mem_manager
+ >
+ conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>::
+ ~conditioning_class_kernel_4 (
+ )
+ {
+ clear();
+ // update memory usage
+ global_state.memory_usage -= sizeof(conditioning_class_kernel_4);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size,
+ unsigned long pool_size,
+ typename mem_manager
+ >
+ void conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>::
+ clear(
+ )
+ {
+ total = 1;
+ escapes = 1;
+ while (next)
+ {
+ node* temp = next;
+ next = next->next;
+ global_state.pool.deallocate(temp);
+ }
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size,
+ unsigned long pool_size,
+ typename mem_manager
+ >
+ unsigned long conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>::
+ get_memory_usage(
+ ) const
+ {
+ return global_state.memory_usage;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size,
+ unsigned long pool_size,
+ typename mem_manager
+ >
+ typename conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>::global_state_type& conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>::
+ get_global_state(
+ )
+ {
+ return global_state;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size,
+ unsigned long pool_size,
+ typename mem_manager
+ >
+ bool conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>::
+ increment_count (
+ unsigned long symbol,
+ unsigned short amount
+ )
+ {
+ if (symbol == alphabet_size-1)
+ {
+ // make sure we won't cause any overflow
+ if (total >= 65536 - amount )
+ half_counts();
+
+ escapes += amount;
+ total += amount;
+ return true;
+ }
+
+
+ // find the symbol and increment it or add a new node to the list
+ if (next)
+ {
+ node* temp = next;
+ node* previous = 0;
+ while (true)
+ {
+ if (temp->symbol == static_cast<unsigned short>(symbol))
+ {
+ // make sure we won't cause any overflow
+ if (total >= 65536 - amount )
+ half_counts();
+
+ // we have found the symbol
+ total += amount;
+ temp->count += amount;
+
+ // if this node now has a count greater than its parent node
+ if (previous && temp->count > previous->count)
+ {
+ // swap the nodes so that the nodes will be in semi-sorted order
+ swap(temp->count,previous->count);
+ swap(temp->symbol,previous->symbol);
+ }
+ return true;
+ }
+ else if (temp->next == 0)
+ {
+ // we did not find the symbol so try to add it to the list
+ if (global_state.pool.get_number_of_allocations() < pool_size)
+ {
+ // make sure we won't cause any overflow
+ if (total >= 65536 - amount )
+ half_counts();
+
+ node* t = global_state.pool.allocate();
+ t->next = 0;
+ t->symbol = static_cast<unsigned short>(symbol);
+ t->count = amount;
+ temp->next = t;
+ total += amount;
+ return true;
+ }
+ else
+ {
+ // no memory left
+ return false;
+ }
+ }
+ else if (temp->count == 0)
+ {
+ // remove nodes that have a zero count
+ if (previous)
+ {
+ previous->next = temp->next;
+ node* t = temp;
+ temp = temp->next;
+ global_state.pool.deallocate(t);
+ }
+ else
+ {
+ next = temp->next;
+ node* t = temp;
+ temp = temp->next;
+ global_state.pool.deallocate(t);
+ }
+ }
+ else
+ {
+ previous = temp;
+ temp = temp->next;
+ }
+ } // while (true)
+ }
+ // if there aren't any nodes in the list yet then do this instead
+ else
+ {
+ if (global_state.pool.get_number_of_allocations() < pool_size)
+ {
+ // make sure we won't cause any overflow
+ if (total >= 65536 - amount )
+ half_counts();
+
+ next = global_state.pool.allocate();
+ next->next = 0;
+ next->symbol = static_cast<unsigned short>(symbol);
+ next->count = amount;
+ total += amount;
+ return true;
+ }
+ else
+ {
+ // no memory left
+ return false;
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size,
+ unsigned long pool_size,
+ typename mem_manager
+ >
+ unsigned long conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>::
+ get_count (
+ unsigned long symbol
+ ) const
+ {
+ if (symbol == alphabet_size-1)
+ {
+ return escapes;
+ }
+ else
+ {
+ node* temp = next;
+ while (temp)
+ {
+ if (temp->symbol == symbol)
+ return temp->count;
+ temp = temp->next;
+ }
+ return 0;
+ }
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size,
+ unsigned long pool_size,
+ typename mem_manager
+ >
+ unsigned long conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>::
+ get_alphabet_size (
+ )
+ {
+ return alphabet_size;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size,
+ unsigned long pool_size,
+ typename mem_manager
+ >
+ unsigned long conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>::
+ get_total (
+ ) const
+ {
+ return total;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size,
+ unsigned long pool_size,
+ typename mem_manager
+ >
+ unsigned long conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>::
+ get_range (
+ unsigned long symbol,
+ unsigned long& low_count,
+ unsigned long& high_count,
+ unsigned long& total_count
+ ) const
+ {
+ if (symbol != alphabet_size-1)
+ {
+ node* temp = next;
+ unsigned long low = 0;
+ while (temp)
+ {
+ if (temp->symbol == static_cast<unsigned short>(symbol))
+ {
+ high_count = temp->count + low;
+ low_count = low;
+ total_count = total;
+ return temp->count;
+ }
+ low += temp->count;
+ temp = temp->next;
+ }
+ return 0;
+ }
+ else
+ {
+ total_count = total;
+ high_count = total;
+ low_count = total-escapes;
+ return escapes;
+ }
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ unsigned long alphabet_size,
+ unsigned long pool_size,
+ typename mem_manager
+ >
+ void conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>::
+ get_symbol (
+ unsigned long target,
+ unsigned long& symbol,
+ unsigned long& low_count,
+ unsigned long& high_count
+ ) const
+ {
+ node* temp = next;
+ unsigned long high = 0;
+ while (true)
+ {
+ if (temp != 0)
+ {
+ high += temp->count;
+ if (target < high)
+ {
+ symbol = temp->symbol;
+ high_count = high;
+ low_count = high - temp->count;
+ return;
+ }
+ temp = temp->next;
+ }
+ else
+ {
+ // this must be the escape symbol
+ symbol = alphabet_size-1;
+ low_count = total-escapes;
+ high_count = total;
+ return;
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+ // private member function definitions
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+
+
+ template <
+ unsigned long alphabet_size,
+ unsigned long pool_size,
+ typename mem_manager
+ >
+ void conditioning_class_kernel_4<alphabet_size,pool_size,mem_manager>::
+ half_counts (
+ )
+ {
+ total = 0;
+ if (escapes > 1)
+ escapes >>= 1;
+
+ //divide all counts by 2
+ node* temp = next;
+ while (temp)
+ {
+ temp->count >>= 1;
+ total += temp->count;
+ temp = temp->next;
+ }
+ total += escapes;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+}
+
+#endif // DLIB_CONDITIONING_CLASS_KERNEl_4_
+
diff --git a/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_abstract.h b/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_abstract.h
new file mode 100644
index 000000000..411aea566
--- /dev/null
+++ b/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_abstract.h
@@ -0,0 +1,228 @@
+// Copyright (C) 2003 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#undef DLIB_CONDITIONING_CLASS_KERNEl_ABSTRACT_
+#ifdef DLIB_CONDITIONING_CLASS_KERNEl_ABSTRACT_
+
+#include "../algs.h"
+
+namespace dlib
+{
+
+ template <
+ unsigned long alphabet_size
+ >
+ class conditioning_class
+ {
+ /*!
+ REQUIREMENTS ON alphabet_size
+ 1 < alphabet_size < 65536
+
+ INITIAL VALUE
+ get_total() == 1
+ get_count(X) == 0 : for all valid values of X except alphabet_size-1
+ get_count(alphabet_size-1) == 1
+
+ WHAT THIS OBJECT REPRESENTS
+ This object represents a conditioning class used for arithmetic style
+ compression. It maintains the cumulative counts which are needed
+ by the entropy_coder and entropy_decoder objects.
+
+ At any moment a conditioning_class object represents a set of
+ alphabet_size symbols. Each symbol is associated with an integer
+ called its count.
+
+ All symbols start out with a count of zero except for alphabet_size-1.
+ This last symbol will always have a count of at least one. It is
+ intended to be used as an escape into a lower context when coding
+ and so it must never have a zero probability or the decoder won't
+ be able to identify the escape symbol.
+
+ NOTATION:
+ Let MAP(i) be a function which maps integers to symbols. MAP(i) is
+ one to one and onto. Its domain is 1 to alphabet_size inclusive.
+
+ Let RMAP(s) be the inverse of MAP(i).
+ ( i.e. RMAP(MAP(i)) == i and MAP(RMAP(s)) == s )
+
+ Let COUNT(i) give the count for the symbol MAP(i).
+ ( i.e. COUNT(i) == get_count(MAP(i)) )
+
+
+ Let LOW_COUNT(s) == the sum of COUNT(x) for x == 1 to x == RMAP(s)-1
+ (note that the sum of COUNT(x) for x == 1 to x == 0 is 0)
+ Let HIGH_COUNT(s) == LOW_COUNT(s) + get_count(s)
+
+
+
+ Basically what this is saying is just that you shoudln't assume you know
+ what order the symbols are placed in when calculating the cumulative
+ sums. The specific mapping provided by the MAP() function is unspecified.
+
+ THREAD SAFETY
+ This object can be used safely in a multithreaded program as long as the
+ global state is not shared between conditioning classes which run on
+ different threads.
+
+ GLOBAL_STATE_TYPE
+ The global_state_type obejct allows instances of the conditioning_class
+ object to share any kind of global state the implementer desires.
+ However, the global_state_type object exists primarily to facilitate the
+ sharing of a memory pool between many instances of a conditioning_class
+ object. But note that it is not required that there be any kind of
+ memory pool at all, it is just a possibility.
+ !*/
+
+ public:
+
+ class global_state_type
+ {
+ global_state_type (
+ );
+ /*!
+ ensures
+ - #*this is properly initialized
+ throws
+ - std::bad_alloc
+ !*/
+
+ // my contents are implementation specific.
+ };
+
+ conditioning_class (
+ global_state_type& global_state
+ );
+ /*!
+ ensures
+ - #*this is properly initialized
+ - &#get_global_state() == &global_state
+ throws
+ - std::bad_alloc
+ !*/
+
+ ~conditioning_class (
+ );
+ /*!
+ ensures
+ - all memory associated with *this has been released
+ !*/
+
+ void clear(
+ );
+ /*!
+ ensures
+ - #*this has its initial value
+ throws
+ - std::bad_alloc
+ !*/
+
+ bool increment_count (
+ unsigned long symbol,
+ unsigned short amount = 1
+ );
+ /*!
+ requires
+ - 0 <= symbol < alphabet_size
+ - 0 < amount < 32768
+ ensures
+ - if (sufficient memory is available to complete this operation) then
+ - returns true
+ - if (get_total()+amount < 65536) then
+ - #get_count(symbol) == get_count(symbol) + amount
+ - else
+ - #get_count(symbol) == get_count(symbol)/2 + amount
+ - if (get_count(alphabet_size-1) == 1) then
+ - #get_count(alphabet_size-1) == 1
+ - else
+ - #get_count(alphabet_size-1) == get_count(alphabet_size-1)/2
+ - for all X where (X != symbol)&&(X != alpahbet_size-1):
+ #get_count(X) == get_count(X)/2
+ - else
+ - returns false
+ !*/
+
+ unsigned long get_count (
+ unsigned long symbol
+ ) const;
+ /*!
+ requires
+ - 0 <= symbol < alphabet_size
+ ensures
+ - returns the count for the specified symbol
+ !*/
+
+ unsigned long get_total (
+ ) const;
+ /*!
+ ensures
+ - returns the sum of get_count(X) for all valid values of X
+ (i.e. returns the sum of the counts for all the symbols)
+ !*/
+
+ unsigned long get_range (
+ unsigned long symbol,
+ unsigned long& low_count,
+ unsigned long& high_count,
+ unsigned long& total_count
+ ) const;
+ /*!
+ requires
+ - 0 <= symbol < alphabet_size
+ ensures
+ - returns get_count(symbol)
+ - if (get_count(symbol) != 0) then
+ - #total_count == get_total()
+ - #low_count == LOW_COUNT(symbol)
+ - #high_count == HIGH_COUNT(symbol)
+ - #low_count < #high_count <= #total_count
+ !*/
+
+ void get_symbol (
+ unsigned long target,
+ unsigned long& symbol,
+ unsigned long& low_count,
+ unsigned long& high_count
+ ) const;
+ /*!
+ requires
+ - 0 <= target < get_total()
+ ensures
+ - LOW_COUNT(#symbol) <= target < HIGH_COUNT(#symbol)
+ - #low_count == LOW_COUNT(#symbol)
+ - #high_count == HIGH_COUNT(#symbol)
+ - #low_count < #high_count <= get_total()
+ !*/
+
+ global_state_type& get_global_state (
+ );
+ /*!
+ ensures
+ - returns a reference to the global state used by *this
+ !*/
+
+ unsigned long get_memory_usage (
+ ) const;
+ /*!
+ ensures
+ - returns the number of bytes of memory allocated by all conditioning_class
+ objects that share the global state given by get_global_state()
+ !*/
+
+ static unsigned long get_alphabet_size (
+ );
+ /*!
+ ensures
+ - returns alphabet_size
+ !*/
+
+ private:
+
+ // restricted functions
+ conditioning_class(conditioning_class<alphabet_size>&); // copy constructor
+ conditioning_class<alphabet_size>& operator=(conditioning_class<alphabet_size>&); // assignment operator
+
+ };
+
+}
+
+#endif // DLIB_CONDITIONING_CLASS_KERNEl_ABSTRACT_
+
diff --git a/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_c.h b/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_c.h
new file mode 100644
index 000000000..964240be8
--- /dev/null
+++ b/ml/dlib/dlib/conditioning_class/conditioning_class_kernel_c.h
@@ -0,0 +1,162 @@
+// Copyright (C) 2003 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#ifndef DLIB_CONDITIONING_CLASS_KERNEl_C_
+#define DLIB_CONDITIONING_CLASS_KERNEl_C_
+
+#include "conditioning_class_kernel_abstract.h"
+#include "../algs.h"
+#include "../assert.h"
+#include <iostream>
+
+namespace dlib
+{
+
+ template <
+ typename cc_base
+ >
+ class conditioning_class_kernel_c : public cc_base
+ {
+ const unsigned long alphabet_size;
+
+ public:
+
+ conditioning_class_kernel_c (
+ typename cc_base::global_state_type& global_state
+ ) : cc_base(global_state),alphabet_size(cc_base::get_alphabet_size()) {}
+
+ bool increment_count (
+ unsigned long symbol,
+ unsigned short amount = 1
+ );
+
+ unsigned long get_count (
+ unsigned long symbol
+ ) const;
+
+ unsigned long get_range (
+ unsigned long symbol,
+ unsigned long& low_count,
+ unsigned long& high_count,
+ unsigned long& total_count
+ ) const;
+
+ void get_symbol (
+ unsigned long target,
+ unsigned long& symbol,
+ unsigned long& low_count,
+ unsigned long& high_count
+ ) const;
+ };
+
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+// member function definitions
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename cc_base
+ >
+ bool conditioning_class_kernel_c<cc_base>::
+ increment_count (
+ unsigned long symbol,
+ unsigned short amount
+ )
+ {
+ // make sure requires clause is not broken
+ DLIB_CASSERT(symbol < alphabet_size &&
+ 0 < amount && amount < 32768,
+ "\tvoid conditioning_class::increment_count()"
+ << "\n\tthe symbol must be in the range 0 to alphabet_size-1. and"
+ << "\n\tamount must be in the range 1 to 32767"
+ << "\n\talphabet_size: " << alphabet_size
+ << "\n\tsymbol: " << symbol
+ << "\n\tamount: " << amount
+ << "\n\tthis: " << this
+ );
+
+ // call the real function
+ return cc_base::increment_count(symbol,amount);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename cc_base
+ >
+ unsigned long conditioning_class_kernel_c<cc_base>::
+ get_count (
+ unsigned long symbol
+ ) const
+ {
+ // make sure requires clause is not broken
+ DLIB_CASSERT(symbol < alphabet_size,
+ "\tvoid conditioning_class::get_count()"
+ << "\n\tthe symbol must be in the range 0 to alphabet_size-1"
+ << "\n\talphabet_size: " << alphabet_size
+ << "\n\tsymbol: " << symbol
+ << "\n\tthis: " << this
+ );
+
+ // call the real function
+ return cc_base::get_count(symbol);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename cc_base
+ >
+ unsigned long conditioning_class_kernel_c<cc_base>::
+ get_range (
+ unsigned long symbol,
+ unsigned long& low_count,
+ unsigned long& high_count,
+ unsigned long& total_count
+ ) const
+ {
+ // make sure requires clause is not broken
+ DLIB_CASSERT(symbol < alphabet_size,
+ "\tvoid conditioning_class::get_range()"
+ << "\n\tthe symbol must be in the range 0 to alphabet_size-1"
+ << "\n\talphabet_size: " << alphabet_size
+ << "\n\tsymbol: " << symbol
+ << "\n\tthis: " << this
+ );
+
+ // call the real function
+ return cc_base::get_range(symbol,low_count,high_count,total_count);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename cc_base
+ >
+ void conditioning_class_kernel_c<cc_base>::
+ get_symbol (
+ unsigned long target,
+ unsigned long& symbol,
+ unsigned long& low_count,
+ unsigned long& high_count
+ ) const
+ {
+ // make sure requires clause is not broken
+ DLIB_CASSERT( target < this->get_total(),
+ "\tvoid conditioning_class::get_symbol()"
+ << "\n\tthe target must be in the range 0 to get_total()-1"
+ << "\n\tget_total(): " << this->get_total()
+ << "\n\ttarget: " << target
+ << "\n\tthis: " << this
+ );
+
+ // call the real function
+ cc_base::get_symbol(target,symbol,low_count,high_count);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+}
+
+#endif // DLIB_CONDITIONING_CLASS_KERNEl_C_
+