00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #pragma once
00014 #include "implimentation_types.h"
00015 #include "constlog2.h"
00016
00018 template <unsigned No_Letters, unsigned DEPTH>
00019 class
00020 _tensor_basis
00021 {
00022
00023 private:
00024
00026 _tensor_basis(const double base)
00027 : _word(base)
00028 {
00029 }
00030
00032 double _word;
00033
00035 static const unsigned uBitsInLetter = ConstLog2 < No_Letters - 1 > ::ans + 1;
00036 static const unsigned uMaxSizeAlphabet = (1 << uBitsInLetter);
00037 static const unsigned uMaxWordLength = 52 / uBitsInLetter;
00038
00039
00040 public:
00041
00043 typedef alg::LET LET;
00044
00046
00048 _tensor_basis(void)
00049 : _word(1.)
00050 {
00051 assert(DEPTH <= uMaxWordLength);
00052 }
00053
00055 ~_tensor_basis(void)
00056 {
00057 }
00058
00060 inline _tensor_basis& push_back(const _tensor_basis& rhs)
00061 {
00062 int iExponent;
00063 frexp(rhs._word, &iExponent);
00064 double dPowerOfTwo = ldexp(.5, iExponent);
00065 _word = (_word * dPowerOfTwo + rhs._word) - dPowerOfTwo;
00066 return *this;
00067 }
00068
00070 inline _tensor_basis operator* (const _tensor_basis& rhs) const
00071 {
00072 int iExponent;
00073 frexp(rhs._word, &iExponent);
00074 double dPowerOfTwo = ldexp(.5, iExponent);
00075 return (_word * dPowerOfTwo + rhs._word) - dPowerOfTwo;
00076 }
00077
00078
00080 inline bool operator < (const _tensor_basis & rhs) const
00081 {
00082 assert(size() <= DEPTH);
00083 return _word < rhs._word;
00084 }
00085
00086 _tensor_basis(const LET uLetter)
00087 : _word (uMaxSizeAlphabet + (uLetter - 1)%uMaxSizeAlphabet)
00088 {
00089 assert(uMaxSizeAlphabet >= uLetter && uLetter > 0);
00090 }
00091
00093 inline unsigned size () const
00094 {
00095 int iExponent;
00096 frexp(_word, &iExponent);
00097 assert((iExponent - 1) % uBitsInLetter == 0);
00098 return (iExponent - 1) / uBitsInLetter;
00099
00100 }
00101
00103 inline LET FirstLetter() const
00104 {
00105 static const double dShiftPlus1(uMaxSizeAlphabet * 2);
00106 static const double dShift(uMaxSizeAlphabet);
00107 static const double dMinusShift = 1 / dShift;
00108
00109 assert(size() > 0);
00110 int iExponent;
00111 double dMantissa = frexp(_word, &iExponent);
00112 double ans;
00113 modf(dMantissa * dShiftPlus1, &ans);
00114 return LET(ans - dShift) + 1;
00115 }
00116
00118 inline _tensor_basis lparent() const
00119 {
00120 static const double dShiftPlus1(uMaxSizeAlphabet * 2);
00121 static const double dShift(uMaxSizeAlphabet);
00122 static const double dMinusShift = 1 / dShift;
00123
00124 assert(size() > 0);
00125 int iExponent;
00126 double dMantissa = frexp(_word, &iExponent);
00127 double ans;
00128 modf(dMantissa * dShiftPlus1, &ans);
00129 return ans;
00130 }
00131
00133 inline _tensor_basis rparent() const
00134 {
00135 static const double dShiftPlus1(uMaxSizeAlphabet * 2);
00136 static const double dShift(uMaxSizeAlphabet);
00137 static const double dMinusShift = 1 / dShift;
00138
00139 assert(size() > 0);
00140 int iExponent;
00141 double dMantissa = frexp(_word, &iExponent);
00142 double ans;
00143 double dPowerOfTwo = ldexp(.5, iExponent - uBitsInLetter);
00144 return (modf(dMantissa * dShiftPlus1, &ans) + 1.) * dPowerOfTwo;
00145 }
00146
00147 static _tensor_basis end()
00148 {
00149 return std::numeric_limits<double>::infinity();
00150 }
00151
00152 friend std::ostream & operator << (std::ostream & os, const typename _tensor_basis < No_Letters, DEPTH > & word)
00153 {
00154 int iExponent;
00155 unsigned count = word.size();
00156 double dNormalised = frexp(word._word, &iExponent) * 2. - 1.;
00157 os << "(";
00158 while (count > 0)
00159 {
00160 double letter;
00161 dNormalised = modf(dNormalised * uMaxSizeAlphabet, &letter);
00162 os << letter + 1.;
00163 --count;
00164 if (count != 0)
00165 os << ",";
00166 }
00167 return os << ")";
00168 }
00169 };
00170