diff --git a/10.1.1.108.5117.pdf b/10.1.1.108.5117.pdf new file mode 100644 index 0000000..67e6e32 Binary files /dev/null and b/10.1.1.108.5117.pdf differ diff --git a/Figures/figure_1.png b/Figures/figure_1.png new file mode 100644 index 0000000..662173b Binary files /dev/null and b/Figures/figure_1.png differ diff --git a/Figures/figure_2.png b/Figures/figure_2.png new file mode 100644 index 0000000..6501125 Binary files /dev/null and b/Figures/figure_2.png differ diff --git a/Implementation/Int Encoding/InfIntSequence.cpp b/Implementation/Int Encoding/InfIntSequence.cpp new file mode 100644 index 0000000..d667a4e --- /dev/null +++ b/Implementation/Int Encoding/InfIntSequence.cpp @@ -0,0 +1,5 @@ +#include "InfIntStream.h" +#include + +using namespace InfIntStream_NS; + diff --git a/Implementation/Int Encoding/InfIntSequence.h b/Implementation/Int Encoding/InfIntSequence.h new file mode 100644 index 0000000..e662ea3 --- /dev/null +++ b/Implementation/Int Encoding/InfIntSequence.h @@ -0,0 +1,64 @@ + +#ifndef INFUINTSEQUENCE_H +#define INFUINTSEQUENCE_H + +using namespace BitSequence_NS; + +namespace InfIntSequence_NS { + + template + class InfUintSequence { + BitStream_NS::BitStream bseq; + + public: + InfUintSequence(byte* const bit_first, byte* const bit_last); + operator bool() const; + + bool skip_next(); + bool has_next() const; + template + bool peek_next(UINT& value) const; + + + // TODO must implement bits-remaining checks + template + bool operator<<(const UINT& u) { + UINT n; + bool o; + if (u < 3) { + // Treat values <3 as having the most sig. bit + // at bit pos. CHAR_BIT*sizeof(UINT) + n = CHAR_BIT*sizeof(UINT); + o=false; + } else { + n = u; + for (std::size_t i=1; i>i; + } + n^=(n>>1); + o = u & (n>>1); + n = get_bit_pos(n); + } + if (!bseq.has_next(2*n+o-3)) return false; + bseq.set(true,n+o-3); + bseq << false; + bseq << !o; + bseq.set(u, n-2); + + return *this; + } + template + bool operator>>(UINT& u) { + std::size_t n; + bool o; + n = bseq.get(true); + bseq.skip_next(); + bseq >> o; + + u=0; + bseq.get(u,n+o); + u+=(UINT(3)+o)< + +template +void divide_w_nneg_remainder(const SINT& dividend, const SINT& divisor, + SINT& quotient, SINT& remainder) { + quotient = dividend / divisor; + remainder = dividend % divisor; + if ((!std::numeric_limits::is_specialized || std::numeric_limits::is_signed) && remainder<0) { + --quotient; + remainder+=divisor; + } +} +template +SINT quotient_w_nneg_remainder(const SINT& dividend, const SINT& divisor) { + SINT quotient, tmp; + divide_w_pos_remainder(dividend, divisor, quotient, tmp); + return quotient; +} +template +SINT nneg_remainder(const SINT& dividend, const SINT& divisor) { + SINT tmp, remainder; + divide_w_pos_remainder(dividend, divisor, tmp, remainder); + return remainder; +} + +#endif diff --git a/Implementation/rational.cpp b/Implementation/rational.cpp deleted file mode 100644 index 12c7540..0000000 --- a/Implementation/rational.cpp +++ /dev/null @@ -1,194 +0,0 @@ -#include "rational.h" -#include "uint_log2.h" -///////////// Constructors //////////////// - -T_rational::T_rational() { - bits_enc.set(); -} - -///////////// Utility Functions /////////////// - -// ### TODO test options & decide on implementation ### -//* -bool T_rational::get_nth_digit_v1(const T_index digit, const T_uint_dec& value) { - return value & (((T_uint_dec)1)<>digit) % 2; -} -bool T_rational::get_nth_digit_v3(const T_index digit, const T_uint_dec& value) { - return (value>>digit) & 1; -} -//*/ -bool T_rational::get_nth_digit(const T_index digit, const T_uint_dec& value) { - return get_nth_digit_v1(digit, value); -} - -void T_rational::set_nth_digit(const T_index digit, T_uint_dec& value, bool bit) { - if (bit) value |= (1<(value); -} - -// Returns whether or not value was successfully encoded into bitstream -bool T_rational::encode_into_bitstream(const T_uint_dec& value_dec, bitstream& bstream) { - // '0' is an invalid input -> treat '0' as 'MAX+1' - // Encode 1 - if (!bstream.has_next()) return false; - // ^ Test if enough bits are available - if (value_dec==1) { - bstream << _0; - return true; - } else { // if (value_dec >=2) - bstream << _1; - } - // Encode all other values - const T_uint_dec value_adj = value_dec+1; - const T_index value_adj_log2 = (value_adj>1) - ? log2(value_adj) - : (8*sizeof(T_uint_dec))+1; - const bool value_adj_2nd_bit = get_nth_digit(value_adj_log2-1,value_adj); - if (!bstream.has_next_multi((2*value_adj_log2)-(value_adj_2nd_bit?0:1))) return false; - // ^ Test if enough bits are available - bstream.set_multi((T_uint_dec)(value_adj_2nd_bit?-4:-3), - value_adj_log2+(value_adj_2nd_bit ? 1:0)); - bstream.set_multi(value_adj, value_adj_log2-1); - return true; -} - -// Returns whether or not value was successfully decoded from bitstream -bool T_rational::decode_from_bitstream(bitstream& bstream, T_uint_dec& value_dec) const { - // Decode '1' - if (!bstream.has_next()) return false; - bool bool_tmp; - bstream >> bool_tmp; - if (bool_tmp == _0) { - value_dec = 1; - return true; - } - // Decode all other values - value_dec = 0; // clear return value - // Count leading '1's - T_index enc_1streak = 0; - while (true) { - if (!bstream.has_next_multi(enc_1streak+2)) return false; - // checks if bits exist to encode minimum-length value - // i.e., ^ assumes next two bits are _0, _0 - bstream >> bool_tmp; - if (bool_tmp != _1) break; - ++enc_1streak; - } - //const T_index enc_1streak = i_enc-i_enc_preinc-1; - // Get bit after first '0' - bstream >> bool_tmp; - const bool enc_2nd_digit = bool_tmp; - if (enc_2nd_digit && !bstream.has_next_multi(enc_1streak+1)) - return false; - // Get remaining bits - bstream.get_multi(value_dec, enc_1streak+(enc_2nd_digit ? 1:0)); - value_dec+=((enc_2nd_digit ? 4:3)<> bool_tmp; - if (bool_tmp==_0) { - prefix = _ZERO; - } else { - // Decode all other values - bstream >> bool_tmp; - prefix = (bool_tmp==_0 ?_POS_NEG:0); - } -} - - -/* Bitstream Functions - * - * - * - * - * - * - * - * - */ - -T_rational::bitstream::bitstream(T_rational& rational) -: bits_enc(rational.bits_enc), index(rational.bits_enc.size()) {} - -T_rational::bitstream::bitstream(std::bitset<8*(4)>& bits) -: bits_enc(bits), index(bits.size()) {} - -T_rational::bitstream::bitstream(const bitstream& bstream) -: bits_enc(bstream.bits_enc), index(bstream.index) {} - -T_rational::bitstream& T_rational::bitstream::operator=(const bitstream& bstream) { - bits_enc = bstream.bits_enc; - index = bstream.index; - return *this; -} - -bool T_rational::bitstream::has_next() const { - return index >= 1; -} -bool T_rational::bitstream::has_next_multi(T_rational::T_index bitcount) const { - return index >= bitcount; -} - -//void T_rational::bitstream::skip_next() { -// ++index; -//} -//void T_rational::bitstream::skip_next_multi(T_rational::T_index bitcount) { -// index+=bitcount; -//} - -void T_rational::bitstream::reset() { - index = bits_enc.size(); -} - -T_rational::bitstream& T_rational::bitstream::operator>>(bool& bit) { - bit = bits_enc[--index]; - return *this; -} -T_rational::bitstream& T_rational::bitstream::operator<<(const bool bit) { - bits_enc.set(--index, bit); - return *this; -} -T_rational::bitstream& T_rational::bitstream::get_multi(T_rational::T_uint_dec& target, - T_rational::T_index bitcount) { - index-=bitcount; - const T_rational::T_uint_dec neg_mask = (((T_rational::T_uint_dec)-1)<>index) & ~neg_mask; - return *this; -} -T_rational::bitstream& T_rational::bitstream::set_multi(const T_rational::T_uint_dec& source, - T_rational::T_index bitcount) { - index-=bitcount; - const T_rational::T_uint_dec mask = (~(((T_rational::T_uint_dec)-1)<)((bits_enc.to_ulong() & ~mask) | ((source< - -#ifndef RATIONAL_H -#define RATIONAL_H - -/* TODO List: - * - make/use bitstream class for template-adjustable implementation - * - consider sizeless rational number class - * - */ - -class T_rational { -//private: -public: - - // Typedefs/Const Values - typedef unsigned long int T_uint_dec; - typedef long int T_int_dec; - typedef unsigned char T_index; - - static const bool _0 = false; - static const bool _1 = true; - - typedef unsigned char T_prefix; - static const T_prefix _ZERO = 1; - static const T_prefix _POS_NEG = 2; - - - // Internal Variables - std::bitset<8*(4)> bits_enc; - - class bitstream; - - // Support Functions - ////////// TODO test ////////////// - static bool get_nth_digit_v1(const T_index digit, const T_uint_dec& value); - static bool get_nth_digit_v2(const T_index digit, const T_uint_dec& value); - static bool get_nth_digit_v3(const T_index digit, const T_uint_dec& value); - static inline bool get_nth_digit(const T_index digit, const T_uint_dec& value); - static inline void set_nth_digit(const T_index digit, T_uint_dec& value, bool bit); - static T_index log2_v1(const T_uint_dec& x); - static T_index log2_v2(const T_uint_dec& x); - static inline T_index log2(const T_uint_dec& x); - - /* - static inline T_rational::T_index no_of_bits_in_encoding_of(const T_uint_dec& value); - static inline T_rational::T_uint_dec max_value_for_bitcount_of(T_index bitcount); - inline bool can_encode_value_in_bitset_v1(const T_uint_dec& value_dec, T_index& i_enc) const; - inline bool can_encode_value_in_bitset_v2(const T_uint_dec& value_dec, T_index& i_enc) const; - inline bool can_encode_value_in_bitset(const T_uint_dec& value_dec, T_index& i_enc) const; - */ - - - // Utility Functions - bool encode_into_bitstream(const T_uint_dec& value_dec, bitstream& bstream); - bool decode_from_bitstream(bitstream& bstream, T_uint_dec& value_dec) const; - void encode_1st_into_bitstream(const T_prefix prefix, bitstream& bstream); - void decode_1st_from_bitstream(bitstream& bstream, T_prefix& prefix) const; - -public: - // Constructors - T_rational(); - //template - //t_float_contfrac(P_INT p_begin, P_INT p_end); - - // Float Casting - //operator float(); -}; - -class T_rational::bitstream { -//private: -public: - std::bitset<8*(4)>& bits_enc; - T_index index; - -public: - bitstream(T_rational& rational); - bitstream(std::bitset<8*(4)>& bits); - bitstream(const bitstream& bstream); - inline bitstream& operator=(const bitstream& bstream); - - - bool has_next() const; - bool has_next_multi(T_rational::T_index bitcount) const; - //inline void skip_next(); - //inline void skip_next_multi(T_rational::T_index bitcount); - bitstream& operator>>(bool& bit); - bitstream& operator<<(const bool bit); - bitstream& get_multi(T_rational::T_uint_dec& target, T_rational::T_index bitcount); - bitstream& set_multi(const T_rational::T_uint_dec& source, T_rational::T_index bitcount); - - void reset(); -}; - -#endif diff --git a/Implementation/rational_TEST.cpp b/Implementation/rational_TEST.cpp index a9a11fc..466387e 100644 --- a/Implementation/rational_TEST.cpp +++ b/Implementation/rational_TEST.cpp @@ -17,8 +17,8 @@ void T_rational_TEST::test_bitstream_in_out() { std::cout << "Starting Test..." << std::endl; // Variables - T_rational value_rational; - T_rational::bitstream bstream(value_rational); + T_rational<4> value_rational; + T_rational<4>::bitstream bstream(value_rational); char c; // Input loop @@ -66,8 +66,8 @@ void T_rational_TEST::test_bitstream_in_out_multi() { std::cout << "Starting Test..." << std::endl; // Variables - T_rational value_rational; - T_rational::bitstream bstream(value_rational); + T_rational<4> value_rational; + T_rational<4>::bitstream bstream(value_rational); char c; T_uint_dec bits_tmp=0; unsigned short bitcount; @@ -138,23 +138,13 @@ void T_rational_TEST::test_bitstream_in_out_multi() { * * */ -unsigned char T_rational_TEST::encode_and_decode(T_rational& value_rational, - T_rational::bitstream& bstream, - const T_uint_dec& value_in, - T_uint_dec& value_out) { - unsigned char ret = 0; - T_rational::bitstream bstream_copy = bstream; - ret += value_rational.T_rational::encode_into_bitstream(value_in, bstream) ? 0:1; - ret += value_rational.T_rational::decode_from_bitstream(bstream_copy, value_out) ? 0:2; - return ret; -} void T_rational_TEST::test_encoding_2nd_Nth_v1() { std::cout << "Test Name: Encoding (v1)" << std::endl; std::cout << "Starting Test..." << std::endl; // Instantiate bitset used for encoding - T_rational value_rational; + T_rational<4> value_rational; std::cout << "Number of bits to store encoding = " << value_rational.bits_enc.size() << std::endl; std::cout << "Bits stored: " << value_rational.bits_enc << std::endl; @@ -167,7 +157,7 @@ void T_rational_TEST::test_encoding_2nd_Nth_v1() { // Input-encode-decode values individually T_uint_dec value_enc; - T_rational::bitstream bstream(value_rational); + T_rational<4>::bitstream bstream(value_rational); std::cout << "Values: " << std::endl; for (unsigned int i=1; i<=valuecount; ++i) { std::cout << i << ")\t>>> "; @@ -203,11 +193,11 @@ void T_rational_TEST::test_encoding_2nd_Nth_v2() { std::cout << "Starting Test..." << std::endl; // Declare variables - T_rational value_rational; + T_rational<4> value_rational; unsigned char failed_encoding = 0; T_uint_dec in; T_uint_dec out; - T_rational::bitstream bstream(value_rational); + T_rational<4>::bitstream bstream(value_rational); // Start test std::cout << "Starting Test..." << std::endl; for (in=1; !failed_encoding && in!=0; ++in) { @@ -250,10 +240,10 @@ void T_rational_TEST::test_decoding_2nd_Nth() { std::cout << "Test Name: Decoding" << std::endl; std::cout << "Starting Test..." << std::endl; - T_rational value_rational; + T_rational<4> value_rational; T_uint_dec in; T_uint_dec out; - T_rational::bitstream bstream(value_rational); + T_rational<4>::bitstream bstream(value_rational); std::cout << "Value to partially encode >>> "; std::cin >> in; diff --git a/Implementation/rational_TEST.h b/Implementation/rational_TEST.h index 873b8b4..69ef463 100644 --- a/Implementation/rational_TEST.h +++ b/Implementation/rational_TEST.h @@ -1,5 +1,3 @@ -#include - #ifndef RATIONAL_TEST_H #define RATIONAL_TEST_H @@ -8,18 +6,26 @@ //class T_rational; namespace T_rational_TEST { - typedef T_rational::T_uint_dec T_uint_dec; - typedef T_rational::T_index T_index; + typedef T_rational<4>::T_uint_dec T_uint_dec; + typedef T_rational<4>::T_index T_index; // Test T_rational::bitstream member functions void test_bitstream_in_out(); void test_bitstream_in_out_multi(); // Test T_rational member functions - unsigned char encode_and_decode(T_rational& value_rational, - T_rational::bitstream& bstream, + template + unsigned char encode_and_decode(T_rational& value_rational, + typename T_rational::bitstream& bstream, const T_uint_dec& value_in, - T_uint_dec& value_out); + T_uint_dec& value_out) { + unsigned char ret = 0; + typename T_rational::bitstream bstream_copy = bstream; + ret += value_rational.T_rational::encode_into_bitstream(value_in, bstream) ? 0:1; + ret += value_rational.T_rational::decode_from_bitstream(bstream_copy, value_out) ? 0:2; + return ret; + + } void test_encoding_2nd_Nth_v1(); void test_encoding_2nd_Nth_v2(); void test_decoding_2nd_Nth(); diff --git a/Implementation/rational_base.cpp b/Implementation/rational_base.cpp new file mode 100644 index 0000000..76bf2fa --- /dev/null +++ b/Implementation/rational_base.cpp @@ -0,0 +1,166 @@ +#include "rational_base.h" +#include "rational_hyperops.h" +#include + +using namespace CFRN; +/******************************************************************** + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + ********************************************************************/ + +/* +T_rational_base* T_rational_base::operator+(const T_rational_base& rhs) { + return new T_rational_binary_ops(*this, rhs, + 0,1,1,0, + 0,0,0,1); +} +T_rational_base* T_rational_base::operator-(const T_rational_base& rhs) { + return new T_rational_binary_ops(*this, rhs, + 0,1,-1,0, + 0,0,0,1); +} +T_rational_base* T_rational_base::operator*(const T_rational_base& rhs) { + return new T_rational_binary_ops(*this, rhs, + 1,0,0,0, + 0,0,0,1); +} +T_rational_base* T_rational_base::operator/(const T_rational_base& rhs) { + return new T_rational_binary_ops(*this, rhs, + 0,1,0,0, + 0,0,1,1); +} +T_rational_base* T_rational_base::inverse() { + return new T_rational_binary_ops(*this, *this, + 0,0,0,1, + 0,1,0,0); +} +*/ + +template class R> +//, typename SINT, typename UINT> +inline bool evaluate_relation(const T_rational_base& lhs, const T_rational_base& rhs) { + const R relation_s{}; + T_int sint_l, sint_r; + + // Get first terms for comparison + T_intostream_base& ios_l = *lhs.make_new_intstream(sint_l); + T_intostream_base& ios_r = *rhs.make_new_intstream(sint_r); + // Logic for failed stream output + if (!(ios_l && ios_r)) { + return false; + } else if (sint_l != sint_r) { + return relation_s(sint_l, sint_r); + } + + const R relation_u{}; + T_uint uint_l, uint_r; + bool reverse_return_value = true; + while (true) { + // Get next terms for comparison + ios_l >> uint_l; + ios_r >> uint_r; + + // Logic for failed stream output + if (!(ios_l && ios_r)) { + if (!(ios_l || ios_r)) { + // both streams fail & previous values between streams are identical + // -> represented rational numbers are identical + uint_l = 1; + uint_r = 1; + } else { + if (reverse_return_value!=ios_l) { + uint_l = 1; + uint_r = 2; + } else { + uint_l = 2; + uint_r = 1; + } + } + break; + } + + // Logic for succesful stream output + if (ios_l != ios_r) break; + reverse_return_value = !reverse_return_value; + } + +RETURN: + delete &ios_l; + delete &ios_r; + return (reverse_return_value? relation_u(uint_r,uint_l):relation_u(uint_l,uint_r)); +} + +bool operator<(const T_rational_base& lhs, const T_rational_base& rhs) { + T_intostream_base + *p_intstream_l = lhs.make_new_intstream(), + *p_intstream_r = rhs.make_new_intstream(); + const bool ret = evaluate_relation >(*p_intstream_l, *p_intstream_r); + delete p_intstream_l; + delete p_intstream_r; + return ret; +} +bool operator>(const T_rational_base& lhs, const T_rational_base& rhs) { + T_intostream_base + *p_intstream_l = lhs.make_new_intstream(), + *p_intstream_r = rhs.make_new_intstream(); + const bool ret = evaluate_relation >(*p_intstream_l, *p_intstream_r); + delete p_intstream_l; + delete p_intstream_r; + return ret; +} +bool operator<=(const T_rational_base& lhs, const T_rational_base& rhs) { + T_intostream_base + *p_intstream_l = lhs.make_new_intstream(), + *p_intstream_r = rhs.make_new_intstream(); + const bool ret = evaluate_relation >(*p_intstream_l, *p_intstream_r); + delete p_intstream_l; + delete p_intstream_r; + return ret; +} +bool operator>=(const T_rational_base& lhs, const T_rational_base& rhs) { + T_intostream_base + *p_intstream_l = lhs.make_new_intstream(), + *p_intstream_r = rhs.make_new_intstream(); + const bool ret = evaluate_relation >(*p_intstream_l, *p_intstream_r); + delete p_intstream_l; + delete p_intstream_r; + return ret; +} +bool operator==(const T_rational_base& lhs, const T_rational_base& rhs) { + T_intostream_base + *p_intstream_l = lhs.make_new_intstream(), + *p_intstream_r = rhs.make_new_intstream(); + const bool ret = evaluate_relation >(*p_intstream_l, *p_intstream_r); + delete p_intstream_l; + delete p_intstream_r; + return ret; +} +bool operator!=(const T_rational_base& lhs, const T_rational_base& rhs) { + T_intostream_base + *p_intstream_l = lhs.make_new_intstream(), + *p_intstream_r = rhs.make_new_intstream(); + const bool ret = evaluate_relation >(*p_intstream_l, *p_intstream_r); + delete p_intstream_l; + delete p_intstream_r; + return ret; +} + diff --git a/Implementation/rational_base.h b/Implementation/rational_base.h new file mode 100644 index 0000000..ad4dce1 --- /dev/null +++ b/Implementation/rational_base.h @@ -0,0 +1,94 @@ +#ifndef RATIONAL_BASE_H +#define RATIONAL_BASE_H + +/* TODO List: + * - make/use bitstream class for template-adjustable implementation + * - consider sizeless rational number class + * + */ + +/******************************************************************** + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + ********************************************************************/ + +// i.e. Continued-Fraction Rational Numbers +namespace CFRN { + + // Declaration + class T_intostream_base; + + // Typedefs (TODO may be removed for template implementations later) + typedef long int T_int; + typedef unsigned long T_uint; + + // Classes + ////////////////////////////////////////////////////////////////// + class T_rational_base { + protected: + friend T_intostream_base; + + public: + virtual T_intostream_base* make_new_intstream(T_int& value_s) const=0; + + virtual T_rational_base* operator-() const =0; + virtual T_rational_base* inverse() const; + + }; + ////////////////////////////////////////////////////////////////// + class T_intostream_base { + protected: + // Is called in constructor + //virtual T_intostream_base& get_1st(T_int& int_dec)=0; + + public: + virtual ~T_intostream_base()=0; + + virtual T_intostream_base* make_new_copy() const=0; + + virtual operator bool()=0; + virtual bool has_next() const=0; + //virtual bool peek_next(T_uint& value) const=0; + virtual bool peek_next(T_uint& value) const=0; + virtual bool skip_next()=0; + + //virtual T_intostream_base& operator>>(T_uint& value)=0; + virtual T_intostream_base& operator>>(T_uint& value)=0; + }; + ////////////////////////////////////////////////////////////////// + +} + +//virtual T_rational_base* operator+(const T_rational_base& rhs) const; +//virtual T_rational_base* operator-(const T_rational_base& rhs) const; +//virtual T_rational_base* operator*(const T_rational_base& rhs) const; +//virtual T_rational_base* operator/(const T_rational_base& rhs) const; +//virtual T_rational_base& operator%(const T_rational_base& rhs) const=0; + +bool operator< (const CFRN::T_rational_base& lhs, const CFRN::T_rational_base& rhs); +bool operator> (const CFRN::T_rational_base& lhs, const CFRN::T_rational_base& rhs); +bool operator<=(const CFRN::T_rational_base& lhs, const CFRN::T_rational_base& rhs); +bool operator>=(const CFRN::T_rational_base& lhs, const CFRN::T_rational_base& rhs); +bool operator==(const CFRN::T_rational_base& lhs, const CFRN::T_rational_base& rhs); +bool operator!=(const CFRN::T_rational_base& lhs, const CFRN::T_rational_base& rhs); + +#endif diff --git a/Implementation/rational_hyperops.cpp b/Implementation/rational_hyperops.cpp new file mode 100644 index 0000000..04256ba --- /dev/null +++ b/Implementation/rational_hyperops.cpp @@ -0,0 +1,147 @@ +#include "rational_hyperops.h" +using namespace CFRN; + +/******************************************************************** + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + ********************************************************************/ + +// Constructor & creation methods +T_rational_unary_hyperops::T_rational_unary_hyperops(const T_rational_base& x, + T_int n_x, + T_int n_1, + T_int d_x, + T_int d_1) +: arg(x), vars_initial{n_x, n_1, d_x, d_1} {} + +T_rational_unary_hyperops::T_intostream_unary_hyperops* T_rational_unary_hyperops::make_new_uintstream(T_int& value_s) const { + return new T_intostream_unary_hyperops(*this, value_s); +} + +T_rational_unary_hyperops* T_rational_unary_hyperops::operator-() const { + return new T_rational_unary_hyperops(arg, + -vars_initial[NUM_X], -vars_initial[NUM_1], + vars_initial[DEN_X], vars_initial[DEN_1]); +} + +T_rational_unary_hyperops* T_rational_unary_hyperops::inverse() const { + return new T_rational_unary_hyperops(arg, + vars_initial[DEN_X], vars_initial[DEN_1], + vars_initial[NUM_X], vars_initial[NUM_1]); +} + +/******************************************************************** + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + ********************************************************************/ + +// Constructors +T_rational_unary_hyperops::T_intostream_unary_hyperops::T_intostream_unary_hyperops(const T_rational_unary_hyperops& rational, T_int& value_s) +: vars{rational.vars_initial[0], rational.vars_initial[1], rational.vars_initial[2], rational.vars_initial[3]}, arg_intostream(*rational.arg.make_new_intstream(value_s)) { + // Test validity based on *this state + if ((vars[DEN_1]==0 && vars[DEN_1]==0)) { + valid=false; + return; + } + const T_int int_tmp = value_s; + if ((vars[DEN_1]!=0 && vars[DEN_X]!=0) && produce_term(value_s)) { + // ^ is true -> new term was created successfully + apply_term(int_tmp); + return; + } + + // Else: get further term from argument + if (!arg_intostream) { + valid=false; + return; + } + apply_term(int_tmp); + T_uint uint_dec; + while ((vars[DEN_1]==0 || vars[DEN_X]==0) || !produce_term(uint_dec)) { + // ^ is true -> new term was created successfully + // Else: get further term from argument + if (!arg_intostream >> uint_dec) { + valid=false; + break; + } + apply_term(uint_dec); + } +} +T_rational_unary_hyperops::T_intostream_unary_hyperops::T_intostream_unary_hyperops(const T_intostream_unary_hyperops& intostream) +: vars{intostream.vars[0],intostream.vars[1],intostream.vars[2],intostream.vars[3]}, arg_intostream(*intostream.make_new_copy()) {} +T_rational_unary_hyperops::T_intostream_unary_hyperops::~T_intostream_unary_hyperops() { + delete &arg_intostream; +} + + +// Public methods +T_rational_unary_hyperops::T_intostream_unary_hyperops::operator bool() { + return valid; +} +bool T_rational_unary_hyperops::T_intostream_unary_hyperops::has_next() const { + T_intostream_unary_hyperops tmp (*this); + return tmp.skip_next(); +} +bool T_rational_unary_hyperops::T_intostream_unary_hyperops::peek_next(T_uint& value) const { + return T_intostream_unary_hyperops(*this).operator>>(value); +} +bool T_rational_unary_hyperops::T_intostream_unary_hyperops::skip_next() { + T_uint tmp; + return operator>>(tmp); +} + +T_rational_unary_hyperops::T_intostream_unary_hyperops& T_rational_unary_hyperops::T_intostream_unary_hyperops::operator>>(T_uint& uint_dec) { + // Test validity based on *this state + if ((vars[DEN_1]==0 && vars[DEN_1]==0)) { + valid=false; + return *this; + } + while ((vars[DEN_1]==0 || vars[DEN_X]==0) || !produce_term(uint_dec)) { + // ^ is true -> new term was created successfully + // Else: get further term from argument + if (!arg_intostream >> uint_dec) { + valid=false; + return *this; + } + apply_term(uint_dec); + } + return *this; +} diff --git a/Implementation/rational_hyperops.h b/Implementation/rational_hyperops.h new file mode 100644 index 0000000..676937c --- /dev/null +++ b/Implementation/rational_hyperops.h @@ -0,0 +1,133 @@ +#ifndef RATIONAL_HYPEROPS_H +#define RATIONAL_HYPEROPS_H + +#include "rational_base.h" +#include "divide_non_negative_remainder.h" +#include + +/* TODO List: + * - make/use bitstream class for template-adjustable implementation + * - consider sizeless rational number class + * + */ + +namespace CFRN { +/******************************************************************** + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + ********************************************************************/ + + class T_rational_unary_hyperops : public T_rational_base { + protected: + const T_rational_base &arg; + const T_int vars_initial[4]; + static const unsigned char NUM_X=0, NUM_1=1, DEN_X=2, DEN_1=3; + + ////////////////////////////////////////////////////////////////// + class T_intostream_unary_hyperops : public T_intostream_base { + protected: + friend T_rational_unary_hyperops; + T_intostream_base& arg_intostream; + T_int vars[4]; + bool valid=false; + + template + inline void apply_term(const INT& term) { + std::swap(vars[NUM_X], vars[NUM_1]); + std::swap(vars[DEN_X], vars[DEN_1]); + vars[NUM_X] += vars[NUM_1]*term; + vars[DEN_X] += vars[DEN_1]*term; + } + template + inline bool produce_term(INT& div_x) { + // assumes the denominator values are non-zero + T_int rem_x, div_1, rem_1; + divide_w_nneg_remainder(vars[NUM_X],vars[DEN_X],div_x,rem_x); + divide_w_nneg_remainder(vars[NUM_1],vars[DEN_1],div_1,rem_1); + if (div_x!=div_1) + return false; + vars[NUM_1] = vars[DEN_1]; + vars[NUM_X] = vars[DEN_X]; + vars[DEN_1] = rem_1; + vars[DEN_X] = rem_x; + return true; + } + + //T_intostream_base& get_1st(T_int& int_dec); + + public: + T_intostream_unary_hyperops(const T_rational_unary_hyperops& rational, + T_int& value_s); + T_intostream_unary_hyperops(const T_intostream_unary_hyperops& uintstream); + ~T_intostream_unary_hyperops(); + + T_intostream_unary_hyperops* make_new_copy() const; + + operator bool(); + bool has_next() const; + bool peek_next(T_uint& value) const; + bool skip_next(); + + T_intostream_unary_hyperops& operator>>(T_uint& value); + }; + ////////////////////////////////////////////////////////////////// + + public: + T_intostream_unary_hyperops* make_new_uintstream(T_int& value_s) const; + + T_rational_unary_hyperops(const T_rational_base& x, + T_int n_x, + T_int n_1, + T_int d_x, + T_int d_1); + + T_rational_unary_hyperops* operator-() const; + T_rational_unary_hyperops* inverse() const; + }; + +/******************************************************************** + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + ********************************************************************/ + +} + +#endif diff --git a/Implementation/rational_static.cpp b/Implementation/rational_static.cpp new file mode 100644 index 0000000..23a240f --- /dev/null +++ b/Implementation/rational_static.cpp @@ -0,0 +1,351 @@ +#include "rational_static.h" +#include "uint_log2.h" + +using namespace CFRN; +/******************************************************************** + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + ********************************************************************/ + + +///////////// Constructors //////////////// + +template +T_rational_static::T_rational_static() { + bits_enc.set(); +} + +///////////// Utility Functions /////////////// + +// ### TODO test options & decide on implementation ### +//* +template +bool T_rational_static::get_nth_digit_v1(const T_index digit, const T_uint& value) { + return value & (((T_uint)1)< +bool T_rational_static::get_nth_digit_v2(const T_index digit, const T_uint& value) { + return (value>>digit) % 2; +} +template +bool T_rational_static::get_nth_digit_v3(const T_index digit, const T_uint& value) { + return (value>>digit) & 1; +} +//*/ +template +bool T_rational_static::get_nth_digit(const T_index digit, const T_uint& value) { + return get_nth_digit_v1(digit, value); +} + +template +void T_rational_static::set_nth_digit(const T_index digit, T_uint& value, bool bit) { + if (bit) value |= (1< +T_index T_rational_static::log2(const T_uint& value) { + return uint_log2(value); +} + +/* intstream Functions + * + * + * + * + * + * + * + * + */ + +template +T_rational_static::T_intstream_static::T_intstream_static(T_rational_static& rational) +: bstream(rational) {} + +template +T_rational_static::T_intstream_static::T_intstream_static(const T_intstream_static& uintstream) +: bstream(uintstream.bstream) {} +template +T_rational_static::T_intstream_static::operator bool() const { + return valid; +} + +template +bool T_rational_static::T_intstream_static::skip_next() { + if (!valid) return false; + // Decode '1' + if (!bstream.has_next()) return false; + bool bool_tmp; + bstream >> bool_tmp; + if (bool_tmp == _0) { + return true; + } + // Decode all other values + // Count leading '1's + T_index enc_1streak = 0; + while (true) { + if (!bstream.has_next_multi(enc_1streak+2)) return false; + // checks if bits exist to encode minimum-length value + // i.e., ^ assumes next two bits are _0, _0 + bstream >> bool_tmp; + if (bool_tmp != _1) break; + ++enc_1streak; + } + //const T_index enc_1streak = i_enc-i_enc_preinc-1; + // Get bit after first '0' + bstream >> bool_tmp; + const bool enc_2nd_digit = bool_tmp; + if (enc_2nd_digit && !bstream.has_next_multi(enc_1streak+1)) + return false; + // Get remaining bits + return true; +} + +template +bool T_rational_static::T_intstream_static::has_next() const { + const typename bitstream::pos_data tmp = bstream.get_position_checkpoint(); + const bool ret = skip_next(); + bstream.restore_position(tmp); + return ret; +} + +template +bool T_rational_static::T_intstream_static::peek_next(T_int& value_dec) const { + const typename bitstream::pos_data tmp = bstream.get_position_checkpoint(); + const bool ret = operator>>(value_dec); + bstream.restore_position(tmp); + return ret; +} + +///////////// Encoding scheme for post-initial value in range [1, inf) //////////////// +// Encoding Decoded value +// 0 1 +// 100 2 +// 1010 3 +// 1011 4 +// 11000 5 +// 11001 6 +// ... +// +// 111...1 0* #### => (3+o)*2^n + int(###, n+o bits) +// ^-----^ n+1 = # of consecutive leading '1's +// ^ o = bit after first '0' bit +// ^ ### = following n+o bits +// +/////////////////////////////////////////////////////////////////////////////////////// + +// Returns whether or not value was successfully encoded into bitstream +template +typename T_rational_static::T_intstream_static& T_rational_static::T_intstream_static::operator<<(const T_uint& value_dec) { + // '0' is an invalid input -> treat '0' as 'MAX+1' + // Encode 1 + if (!bstream.has_next()) return false; + // ^ Test if enough bits are available + if (value_dec==1) { + bstream << _0; + return true; + } else { // if (value_dec >=2) + bstream << _1; + } + // Encode all other values + const T_uint value_adj = value_dec+1; + const T_index value_adj_log2 = (value_adj>1) + ? log2(value_adj) + : (8*sizeof(T_uint))+1; + const bool value_adj_2nd_bit = get_nth_digit(value_adj_log2-1,value_adj); + if (!bstream.has_next_multi((2*value_adj_log2)-(value_adj_2nd_bit?0:1))) return false; + // ^ Test if enough bits are available + bstream.set_multi((T_uint)(value_adj_2nd_bit?-4:-3), + value_adj_log2+(value_adj_2nd_bit ? 1:0)); + bstream.set_multi(value_adj, value_adj_log2-1); + return true; +} + +// Returns whether or not value was successfully decoded from bitstream +template +typename T_rational_static::T_intstream_static& T_rational_static::T_intstream_static::operator>>(T_int& value_dec) { + // Decode '1' + if (!bstream.has_next()) return false; + bool bool_tmp; + bstream >> bool_tmp; + if (bool_tmp == _0) { + value_dec = 1; + return true; + } + // Decode all other values + value_dec = 0; // clear return value + // Count leading '1's + T_index enc_1streak = 0; + while (true) { + if (!bstream.has_next_multi(enc_1streak+2)) return false; + // checks if bits exist to encode minimum-length value + // i.e., ^ assumes next two bits are _0, _0 + bstream >> bool_tmp; + if (bool_tmp != _1) break; + ++enc_1streak; + } + //const T_index enc_1streak = i_enc-i_enc_preinc-1; + // Get bit after first '0' + bstream >> bool_tmp; + const bool enc_2nd_digit = bool_tmp; + if (enc_2nd_digit && !bstream.has_next_multi(enc_1streak+1)) + return false; + // Get remaining bits + bstream.get_multi(value_dec, enc_1streak+(enc_2nd_digit ? 1:0)); + value_dec+=((enc_2nd_digit ? 4:3)< +typename T_rational_static::T_intstream_static& T_rational_static::T_intstream_static::reset_and_set_1st(const T_int& int_dec) { + // (as this is meant only for the first entry, we assume the bitset has room for the two zero/sign bits) + // Set to beginning of stream + bstream.reset(); + // Categorize input + const T_prefix bits_in = (int_dec==0?_ZERO: int_dec==-1?_NEG1: int_dec>0?_POS:_NEG); + // Encode based on category + switch (bits_in) { + case _ZERO: + case _NEG1: + bstream.set_multi(bits_in, 2); + break; + case _POS: + bstream.set_multi(bits_in, 2); + operator<<(int_dec); + break; + case _NEG: + bstream << (bool)MASK_NONZERO_RANGES; + operator<<(-int_dec); + break; + } +} + +template +typename T_rational_static::T_intstream_static& T_rational_static::T_intstream_static::reset_and_get_1st(T_int& int_dec) { + // (as this is meant only for the first entry, we assume the bitset has room for the two zero/sign bits) + //Set to beginning of stream + bstream.reset(); + // Get first bit + bool bool_tmp; + bstream >> bool_tmp; + + if (bool_tmp==MASK_NONZERO_RANGES) { + bstream >> bool_tmp; + int_dec = (bool_tmp==(bool)MASK_NEG? -1:0); + } else { + // Decode all other values + T_uint_dec uint_tmp; + operator>>(uint_tmp); + if (uint_tmp==1) { //-> value > 0 + operator>>(uint_tmp); + int_dec = uint_tmp; + } else { //-> value < 0 + int_dec = -uint_tmp; + } + } +} + + +/* Bitstream Functions + * + * + * + * + * + * + * + * + */ + +template +T_rational_static::bitstream::bitstream(T_rational_static& rational) +: bits_enc(rational.bits_enc), index(rational.bits_enc.size()) {} + +template +T_rational_static::bitstream::bitstream(const bitstream& bstream) +: bits_enc(bstream.bits_enc), index(bstream.index) {} + +template +typename T_rational_static::bitstream& T_rational_static::bitstream::operator=(const bitstream& bstream) { + bits_enc = bstream.bits_enc; + index = bstream.index; + return *this; +} + +template +bool T_rational_static::bitstream::has_next() const { + return index >= 1; +} +template +bool T_rational_static::bitstream::has_next_multi(T_rational_static::T_index bitcount) const { + return index >= bitcount; +} + +//void T_rational_static::bitstream::skip_next() { +// ++index; +//} +//void T_rational_static::bitstream::skip_next_multi(T_rational_static::T_index bitcount) { +// index+=bitcount; +//} + +template +void T_rational_static::bitstream::reset() { + index = bits_enc.size(); +} + +template +typename T_rational_static::bitstream& T_rational_static::bitstream::operator>>(bool& bit) { + bit = bits_enc[--index]; + return *this; +} +template +typename T_rational_static::bitstream& T_rational_static::bitstream::operator<<(const bool bit) { + bits_enc.set(--index, bit); + return *this; +} +template +typename T_rational_static::bitstream& T_rational_static::bitstream::get_multi(T_rational_static::T_uint_dec& target, + T_rational_static::T_index bitcount) { + index-=bitcount; + const T_rational_static::T_uint_dec neg_mask = (((T_rational_static::T_uint_dec)-1)<>index) & ~neg_mask; + return *this; +} +template +typename T_rational_static::bitstream& T_rational_static::bitstream::set_multi(const T_rational_static::T_uint_dec& source, + T_rational_static::T_index bitcount) { + index-=bitcount; + const T_rational_static::T_uint_dec mask = (~(((T_rational_static::T_uint_dec)-1)<)((bits_enc.to_ulong() & ~mask) | ((source< + +#ifndef RATIONAL_H +#define RATIONAL_H + +/* TODO List: + * - make/use bitstream class for template-adjustable implementation + * - consider sizeless rational number class + * + */ +namespace CFRN { + typedef unsigned char T_index; + +/******************************************************************** + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + ********************************************************************/ + + template + class T_rational_static : public T_rational_base { + private: + static const bool _0 = false; + static const bool _1 = true; + + typedef unsigned char T_prefix; + static const T_prefix MASK_NONZERO_RANGES=2; + static const T_prefix MASK_NEG=1; // NOTE: neg==1 -> the encoded value for '1'==bits(0) + static const T_prefix _ZERO = 0; + static const T_prefix _NEG1 = MASK_NEG; + static const T_prefix _POS = MASK_NONZERO_RANGES; + static const T_prefix _NEG = MASK_NONZERO_RANGES | MASK_NEG; + + // Internal Variables + std::bitset<8*(BYTE_COUNT)> bits_enc; + + // INNER CLASSES + //********************************************************************** + class bitstream { + private: + std::bitset<8*(BYTE_COUNT)>& bits_enc; + T_index index; + + public: + struct pos_data { + T_index index_tmp; + }; + pos_data get_position_checkpoint() const {return index;} + void restore_position(pos_data pos_checkpoint) {index = pos_checkpoint.index;} + + + bitstream(T_rational_static& rational); + bitstream(const bitstream& bstream); + inline bitstream& operator=(const bitstream& bstream); + + + bool has_next() const; + bool has_next_multi(T_index bitcount) const; + //inline void skip_next(); + //inline void skip_next_multi(T_rational::T_index bitcount); + bitstream& operator>>(bool& bit); + bitstream& operator<<(const bool bit); + bitstream& get_multi(T_uint& target, T_index bitcount); + bitstream& set_multi(const T_uint& source, T_index bitcount); + + void reset(); + }; + //********************************************************************** + class T_intstream_static : public T_intostream_base { + private: + bitstream bstream; + bool valid=false; + public: + T_intstream_static(T_rational_static& rational); + T_intstream_static(const T_intstream_static& uintstream); + operator bool() const; + + bool skip_next(); + bool has_next() const; + bool peek_next(T_int& value) const; + + T_intstream_static& operator>>(T_int& uint_dec); + T_intstream_static& operator<<(const T_uint& uint_dec); + + T_intstream_static& reset_and_set_1st(const T_int& int_dec); + T_intstream_static& reset_and_get_1st(T_int& int_dec); + }; + //********************************************************************** + + + // Support Functions + ////////// TODO test ////////////// + static bool get_nth_digit_v1(const T_index digit, const T_uint& value); + static bool get_nth_digit_v2(const T_index digit, const T_uint& value); + static bool get_nth_digit_v3(const T_index digit, const T_uint& value); + static inline bool get_nth_digit(const T_index digit, const T_uint& value); + static inline void set_nth_digit(const T_index digit, T_uint& value, bool bit); + static inline T_index log2(const T_uint& x); + + /* + static inline T_rational::T_index no_of_bits_in_encoding_of(const T_uint_dec& value); + static inline T_rational::T_uint_dec max_value_for_bitcount_of(T_index bitcount); + inline bool can_encode_value_in_bitset_v1(const T_uint_dec& value_dec, T_index& i_enc) const; + inline bool can_encode_value_in_bitset_v2(const T_uint_dec& value_dec, T_index& i_enc) const; + inline bool can_encode_value_in_bitset(const T_uint_dec& value_dec, T_index& i_enc) const; + */ + + + // Utility Functions + bool encode_into_bitstream(const T_int& value_dec, bitstream& bstream); + bool decode_from_bitstream(bitstream& bstream, T_int& value_dec) const; + void encode_1st_prefix_into_bitstream(const T_prefix prefix, bitstream& bstream); + void decode_1st_prefix_from_bitstream(bitstream& bstream, T_prefix& prefix) const; + + public: + // Constructors + T_rational_static(); + //template + //t_float_contfrac(P_INT p_begin, P_INT p_end); + + // Float Casting + //operator float(); + }; + + +/******************************************************************** + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + ********************************************************************/ + +} +#endif diff --git a/LaTeX_report.url b/LaTeX_report.url new file mode 100644 index 0000000..e3214bf --- /dev/null +++ b/LaTeX_report.url @@ -0,0 +1,2 @@ +[InternetShortcut] +URL=https://www.overleaf.com/7443165rjwydwfyjwpb diff --git a/Reading/Chaos in Numberland- The secret life of continued fractions | plus.maths.org.webloc b/Reading/Chaos in Numberland- The secret life of continued fractions | plus.maths.org.webloc new file mode 100644 index 0000000..bbccf10 --- /dev/null +++ b/Reading/Chaos in Numberland- The secret life of continued fractions | plus.maths.org.webloc @@ -0,0 +1,8 @@ + + + + + URL + https://plus.maths.org/content/chaos-numberland-secret-life-continued-fractions + + diff --git a/Reading/Let's ask for a term from _z_.webloc b/Reading/Let's ask for a term from _z_.webloc new file mode 100644 index 0000000..37ce73e --- /dev/null +++ b/Reading/Let's ask for a term from _z_.webloc @@ -0,0 +1,8 @@ + + + + + URL + http://perl.plover.com/classes/cftalk/TALK/slide032.html + + diff --git a/Reading/Numbers and Functions as Continued Fractions - Numericana.webloc b/Reading/Numbers and Functions as Continued Fractions - Numericana.webloc new file mode 100644 index 0000000..4cd8c23 --- /dev/null +++ b/Reading/Numbers and Functions as Continued Fractions - Numericana.webloc @@ -0,0 +1,8 @@ + + + + + URL + http://www.numericana.com/answer/fractions.htm + + diff --git a/Reading/WRAP_Beynon_cs-rr-034.pdf.webloc b/Reading/WRAP_Beynon_cs-rr-034.pdf.webloc new file mode 100644 index 0000000..3ff5e96 --- /dev/null +++ b/Reading/WRAP_Beynon_cs-rr-034.pdf.webloc @@ -0,0 +1,8 @@ + + + + + URL + http://wrap.warwick.ac.uk/47220/1/WRAP_Beynon_cs-rr-034.pdf + + diff --git a/Reading/ap01.pdf.lr_7928.pdf b/Reading/ap01.pdf.lr_7928.pdf new file mode 100644 index 0000000..6656a16 Binary files /dev/null and b/Reading/ap01.pdf.lr_7928.pdf differ diff --git a/lcf.dvi - download;jsessionid=12D41B2100B4F373950C0B28B7AFD793.webloc b/lcf.dvi - download;jsessionid=12D41B2100B4F373950C0B28B7AFD793.webloc new file mode 100644 index 0000000..a335898 --- /dev/null +++ b/lcf.dvi - download;jsessionid=12D41B2100B4F373950C0B28B7AFD793.webloc @@ -0,0 +1,8 @@ + + + + + URL + http://citeseer.ist.psu.edu/viewdoc/download;jsessionid=12D41B2100B4F373950C0B28B7AFD793?doi=10.1.1.108.5117&rep=rep1&type=pdf + + diff --git a/precision measure.py b/precision measure.py index 868f7ff..eadb4ef 100644 --- a/precision measure.py +++ b/precision measure.py @@ -18,6 +18,9 @@ # Returns precision achieved at value 'x' # assuming a worst-performance value-history parameter f_worst = lambda x: f(x, alpha_worst_by_x(x)) +# Returns precision achieved at value 'x' +# assuming a best-performance value-history parameter +f_best = lambda x: f(x, alpha_best_by_x(x)) # Returns minimum value that can be stored in 'b' bits # in order to have at most a precision density 'bar', @@ -47,7 +50,46 @@ BAR = 10**(-0.25) # FUNCTIONS -def plot_ideal_precision_densities(): + +# Plots the precision increase achieved (y coord.) by adding a term a_n (x coord.) +# for both best_case and worst_case value-history parameters +def plot_minmax_zoom_vs_value(): + # Init Figure + #fig = plt.figure() + #ax = fig.add_subplot(111) + labels = ( + "CF precision, alpha=0", + "CF precision, alpha=1", + "floating-point precision", + "CF precision min.", + "CF precision max." + ) + lines=[] + + # Constants + samples_perbit=10 + samples=1+samples_perbit*(NO_OF_BITS-1) + alpha_samples=10 + x_bits = [1+float(i)/samples_perbit for i in range(samples)] #bits used to represent x + x = [2**(i-1) for i in x_bits] + alphas = [float(i)/alpha_samples for i in range(alpha_samples+1)] + f_precision_CT_temp = lambda a: [f(x[i],a)**(1.0/x_bits[i]) for i in range(samples)] + # Plot Alpha Curves + lines += plt.plot( + x_bits, + f_precision_CT_temp(0), + color=(0.3,0.5,1), + label = labels[0] + ) + for a in alphas[1:-1]: + plt.plot(x_bits, f_precision_CT_temp(a), color=(0.3,0.5*(a+1),1-a)) + lines += plt.plot( + x_bits, + f_precision_CT_temp(1), + color=(0.3,1,0), + label = labels[1] + ) + # Constants x_bits = range(1,NO_OF_BITS+1) #bits used to represent x x = [2**(i-1) for i in x_bits] @@ -57,34 +99,111 @@ def plot_ideal_precision_densities(): # precision factor of binary floating-point numbers (i.e., a constant 1/2) prec_binary = [0.5 for i in x] - # Lower-bound for precision-factor of Continued Fractions - prec_CF_low = [f(x[i],0)**(1.0/x_bits[i]) for i in range(2,NO_OF_BITS)] - prec_CF_low.insert(0, sqrt(f(2,0))) - prec_CF_low.insert(0, f(1,1)) - + prec_CF_low = [f_best(x[i])**(1.0/x_bits[i]) for i in range(NO_OF_BITS)] # Upper-bound for precision factor of Continued Fractions - prec_CF_high = [f(x[i],1)**(1.0/x_bits[i]) for i in range(2,NO_OF_BITS)] - prec_CF_high.insert(0, sqrt(f(2,sqrt(2)-1))) - prec_CF_high.insert(0, f(1,0)) + prec_CF_high = [f_worst(x[i])**(1.0/x_bits[i]) for i in range(NO_OF_BITS)] - # Plot + # Plot w = range(1,NO_OF_BITS+1) - plt.plot(\ - x_bits, prec_binary, 'b-', \ - x_bits, prec_CF_low, 'g^', \ - x_bits, prec_CF_high, 'gv') + lines += plt.plot(x_bits, prec_binary, 'y-', label=labels[2]) + lines += plt.plot(x_bits, prec_CF_low, 'm^', label=labels[3]) + lines += plt.plot(x_bits, prec_CF_high, 'mv', label=labels[4]) + plt.legend(lines, labels) + plt.show() +# End function + + +def plot_zoom_per_bit_vs_value(): + # Constants + x = [2**i for i in range(NO_OF_BITS)] + # * this is a some-what conservative estimate (i.e. in reality, a larger x + # could be represented in said number of bits + # ** this does not take into account the bit-loss from storing mixed-width integers + + # precision factor of binary floating-point numbers (i.e., a constant 1/2) + prec_binary = 0.5 + + # precision factor of continuing block encoding (w/ block size of 1 bit) + DATA_BITS=1 + prec_cont_block_1_low_logx = [] + prec_cont_block_1_low = [] + prec_cont_block_1_high_logx = [0] + prec_cont_block_1_high = [f_worst(1)**(0.5)] + for i in range(1,NO_OF_BITS): + prec_cont_block_1_high_logx.append(log((2**i)-1,2)) + prec_cont_block_1_high.append( + f_worst((2**i)-1)**(1.0/((1+(i-1)/DATA_BITS)*(DATA_BITS+1))) + ) + prec_cont_block_1_high_logx.append(i) + prec_cont_block_1_high.append( + f_worst(2**i)**(1.0/((1+i/DATA_BITS)*(DATA_BITS+1))) + ) + # ^TODO + # lowest upper limit for optimal coding + bar = lowest_bar_inwhich_code_exists() + + # precision factor for coded values + prec_optimal_low = [] + prec_optimal_low_logx = [] + prec_optimal_high = [] + prec_optimal_high_logx = [] + + #ics = itemcounts_by_bitcount_from_bar(BAR, int(2*f_b_max_worst(2**NO_OF_BITS, BAR))) + #optimize_itemcounts_per_bitcount(ics) + #sum=0 + #for b in range(len(ics)): + # if not ics[b]==0: + # sum+=1 + # prec_optimal_high.append(f_worst(sum)**(1.0/b)) + # prec_optimal_high_logx.append(log(sum,2)) + # sum+=ics[b]-1 + # prec_optimal_high.append(f_worst(sum)**(1.0/b)) + # prec_optimal_high_logx.append(log(sum,2)) + #del sum + #del ics + sum=0 + b=0 + while sum <= 2**NO_OF_BITS: + if not itemcount_by_bitcount_scheme2(b)==0: + sum+=1 + prec_optimal_high.append(f_worst(sum)**(1.0/b)) + prec_optimal_high_logx.append(log(sum,2)) + sum+=itemcount_by_bitcount_scheme2(b)-1 + prec_optimal_high.append(f_worst(sum)**(1.0/b)) + prec_optimal_high_logx.append(log(sum,2)) + b+=1 + - #import numpy as np - #alphas = np.arange(0.0, 1.0, 0.05) - alphas = [0,1] - f_precision_CT_temp = lambda a: [f(x[i],a)**(1.0/x_bits[i]) for i in range(N)] - for a in alphas: - plt.plot(x_bits, f_precision_CT_temp(a), 'g') + lexibinary_values = [2**((i+1)/2)-i%2 for i in range(NO_OF_BITS*2)] + lexibinary_logx = [log(x,2) for x in lexibinary_values] + #lexibinary_bits = [i+1-i%2 for i in range(NO_OF_BITS)] + lexibinary_prec = [f_worst(lexibinary_values[i])**(1.0/(i+1-i%2)) + for i in range(NO_OF_BITS*2)] + # Plot + labels = ( + "floating-point binary precision", + #, + "VLQ precision (data bits/block = "+str(DATA_BITS)+")", + "CF precision worst-case limit", + "lexibinary precision", + #, + "CF precision" + ) + lines = [] + lines += plt.plot((0, NO_OF_BITS+1), (prec_binary,prec_binary), 'y-') + #lines += plt.plot(prec_cont_block_1_low_logx, prec_cont_block_1_low, '0.75') + lines += plt.plot(prec_cont_block_1_high_logx, prec_cont_block_1_high, '0.75') + lines += plt.plot((0, NO_OF_BITS+1), (BAR,BAR), 'm--') + lines += plt.plot(lexibinary_logx, lexibinary_prec, "b-") + #lines += plt.plot(prec_optimal_low_logx, prec_optimal_low, 'r-') + lines += plt.plot(prec_optimal_high_logx, prec_optimal_high, 'r-') + plt.legend(lines, labels) plt.show() # End function + def plot2(): x_max = [int(ceil(f_x_min_worst(i,0.5))) for i in range(1,NO_OF_BITS+2)] log_x_max = [log(x,2) for x in x_max] @@ -94,6 +213,7 @@ def plot2(): plt.show() # Arrange items by their limit of bits -> input[bitlimit] == [items] +# returns whether a binary code is successfully generated def code_for_itemlists_per_bit(itemlists_by_bitcount, dict_codes): dict_codes.clear() _prefixes = [BitArray('')] @@ -142,6 +262,11 @@ def itemlists_by_bitcounts_from_bar(bar, max_bits): int(ceil(f_x_min_worst(b+1,bar))) )\ if b>0 else [] for b in range(max_bits+1)] +def itemlists_by_bitcount_lexibinary(max_bits): + result=[] + for i in range(1,max_bits,2): + + def itemcounts_by_bitcount_from_bar(bar, max_bits): return [int(ceil(f_x_min_worst(b+1,bar))-ceil(f_x_min_worst(b,bar)))\ if b>0 else 0 for b in range(max_bits+1)] @@ -177,7 +302,7 @@ def lowest_bar_inwhich_code_exists(): return bar # lowest bar = 0.5623413251903491 -# = 10**-0.25 (for x=3, b=4) +# = 10**-0.25 (for x=3, b=4) ''' def points_of_optimal_precision(): bar = lowest_bar_inwhich_code_exists() @@ -190,74 +315,6 @@ def points_of_optimal_precision(): ''' -def plot_real_precision_densities(): - # Constants - x = [2**i for i in range(NO_OF_BITS)] - # * this is a some-what conservative estimate (i.e. in reality, a larger x - # could be represented in said number of bits - # ** this does not take into account the bit-loss from storing mixed-width integers - - # precision factor of binary floating-point numbers (i.e., a constant 1/2) - prec_binary = 0.5 - - # precision factor of continuing block encoding (w/ block size of 1 bit) - prec_cont_block_1_low_logx = [] - prec_cont_block_1_low = [] - prec_cont_block_1_high_logx = [0] - prec_cont_block_1_high = [f_worst(1)**(0.5)] - for i in range(1,NO_OF_BITS): - prec_cont_block_1_high_logx.append( log((2**i)-1,2)) - prec_cont_block_1_high.append( f_worst((2**i)-1)**(0.5/i)) - prec_cont_block_1_high_logx.append( i) - prec_cont_block_1_high.append( f_worst(2**i)**(0.5/(i+1))) - - # lowest upper limit for optimal coding - bar = lowest_bar_inwhich_code_exists() - - # precision factor for coded values - prec_optimal_low = [] - prec_optimal_low_logx = [] - prec_optimal_high = [] - prec_optimal_high_logx = [] - - #ics = itemcounts_by_bitcount_from_bar(BAR, int(2*f_b_max_worst(2**NO_OF_BITS, BAR))) - #optimize_itemcounts_per_bitcount(ics) - #sum=0 - #for b in range(len(ics)): - # if not ics[b]==0: - # sum+=1 - # prec_optimal_high.append(f_worst(sum)**(1.0/b)) - # prec_optimal_high_logx.append(log(sum,2)) - # sum+=ics[b]-1 - # prec_optimal_high.append(f_worst(sum)**(1.0/b)) - # prec_optimal_high_logx.append(log(sum,2)) - #del sum - #del ics - sum=0 - b=0 - while sum <= 2**NO_OF_BITS: - if not itemcount_by_bitcount_scheme2(b)==0: - sum+=1 - prec_optimal_high.append(f_worst(sum)**(1.0/b)) - prec_optimal_high_logx.append(log(sum,2)) - sum+=itemcount_by_bitcount_scheme2(b)-1 - prec_optimal_high.append(f_worst(sum)**(1.0/b)) - prec_optimal_high_logx.append(log(sum,2)) - b+=1 - - # Plot - plt.plot(\ - (0, NO_OF_BITS+1), (prec_binary,prec_binary), 'y-', \ - prec_cont_block_1_low_logx, prec_cont_block_1_low, '0.75', \ - prec_cont_block_1_high_logx, prec_cont_block_1_high, '0.75', \ - (0, NO_OF_BITS+1), (BAR,BAR), 'm--', \ - prec_optimal_low_logx, prec_optimal_low, 'r-', \ - prec_optimal_high_logx, prec_optimal_high, 'r-', \ - ) - - plt.show() -# End function - def find_bit_length_for_hybrid_code(cont_block_size): itemcounts = itemcounts_by_bitcount_from_bar(BAR, NO_OF_BITS)