index

// Binary to Gray with m dimensions and n bits per dimension

typedef unsigned int uint;

bool GetRightLastTwo(bool& b1, bool& b2, vector<bool> vGrayCode);

uint NumberOfContinuousFalseLeftOfRightLastTwo(vector<bool> vGrayCode);

vector<bool> GetIteriveSegment(uint nNthBit, uint nBitsPerDimension, uint nDimensions, vector<bool> v);

vector<bool> InvertCoordinate(uint nPos, vector<bool> v);
vector<bool> InvertCoordinates(uint nPos1, uint nPos2, vector<bool> v);

bool GetRotationsAndInversionsForTwoDimensions(bool b1, bool b2, uint& nRotations, uint& nInversion, vector<bool> vGrayCode);
bool GetRotationsAndInversionsForThreeDimensions(bool b1, bool b2, uint& nRotations, uint& nInversion, vector<bool> vGrayCode)

bool GetRotationsAndInversions(uint& nRotations, uint& nInversion, vector<bool> vGrayCode);
bool GetRotationsAndInversions(bool b1, bool b2, uint nDimensions, uint& nRotations, uint& nInversion, vector<bool> vGrayCode)

vector<bool> RotateCoordinatesLeft(uint nStart, uint nLength, vector<bool> v);
vector<bool> RotateCoordinatesLeftDownStream(uint nStart, uint nLength, vector<bool> v);

vector<bool> RotateCoordinatesRight(uint nStart, uint nLength, vector<bool> v);
vector<bool> RotateCoordinatesRightDownStream(uint nStart, uint nLength, vector<bool> v);

vector<bool> OneDimensionalGrayCodeToGrayCoordinatesOf_M_DimensionsAnd_N_BitsPerDimension(uint nDimensions, uint nBitsPerDimension, vector<bool> vGrayCode); // this is a gray code length into its coordinates as gray code
vector<bool> GrayCoordinatesOf_M_DimensionsAnd_N_BitsPerDimensionToOneDimensionalGrayCode(uint nDimensions, uint nBitsPerDimension, vector<bool> vGrayCoordinates);

vector<bool> BinaryLengthToGrayCoordinatesOf_M_DimensionsAnd_N_BitsPerDimension(uint nDimensions, uint nBitsPerDimension, vector<bool> vBool);
vector<bool> GrayCoordinatesOf_M_DimensionsAnd_N_BitsPerDimensionToBinaryLength(uint nDimensions, uint nBitsPerDimension, vector<bool> vGrayCoordinates );


bool GetRightLastTwo(bool& b1, bool& b2, vector<bool> vGrayCode)
{
        b1 = false;
        b2 = false;

        if(vGrayCode.size() > 1)
        {
                uint nLast = vGrayCode.size() - 1;

                b2 = vGrayCode[nLast];
                b1 = vGrayCode[nLast - 1];

                return true;
        }

        return false;
}

uint NumberOfContinuousFalseLeftOfRightLastTwo(vector<bool> vGrayCode)
{
        uint nCount = 0;

        if(vGrayCode.size() > 2)
        {
                for(int n = vGrayCode.size() - 2 - 1; n > 0; n--)       // note the first is never counted
                {
                        if(!vGrayCode[n])
                        {
                                nCount++;
                        }
                        else break;
                }
        }

        return nCount;
}

vector<bool> GetIteriveSegment(uint nNthBit, uint nBitsPerDimension, uint nDimensions, vector<bool> v)
{
        uint nSize = v.size();
        vector<bool> vSeg(nDimensions, 0);

        if((nNthBit <= nBitsPerDimension) && (nSize == m_ nBitsPerDimension * nDimensions))
        {
                uint nStartPos = nSize - (nNthBit * nDimensions);
                for(uint n = 0; n < nDimensions; n++)
                {
                        vSeg[n] = v[nStartPos + n];
                }
        }
        return vSeg;
}

vector<bool> InvertCoordinate(uint nPos, vector<bool> v)
{
        if(nPos < v.size())
        {
                if(v[nPos])
                {
                       v[nPos] = false;
                }
                else
                {
                        v[nPos] = true;
                }
        }
        return v;
}

vector<bool> InvertCoordinates(uint nPos1, uint nPos2, vector<bool> v)
{
        v = InvertCoordinate(nPos1, v);
        v = InvertCoordinate(nPos2, v);
        return v;
}

bool GetRotationsAndInversionsForTwoDimensions(bool b1, bool b2, uint& nRotations, uint& nInversion, vector<bool> vGrayCode)
{       // Curve Dimensions = Rotations + Inverts + 1   // actually there are only two bits inverted, the inversions is really the distance between the two bits
        if((!b1 && !b2) || (b1 && !b2))
        {
                nRotations = 1;
                nInversion = 0;
                return true;
        }
        else if((!b1 && b2) || (b1 && b2))
        {
                nRotations = 0;
                nInversion = 1;
                return true;
        }
        return false;
}

bool GetRotationsAndInversionsForThreeDimensions(bool b1, bool b2, uint& nRotations, uint& nInversion, vector<bool> vGrayCode)
{       // Curve Dimensions = Rotations + Inverts + 1   // actually there are only two bits inverted, the inversions is really the distance between the two bits
        if(!b1 && !b2)   
        {
                nRotations = 2;
                nInversion = 0;
                return true;
        }
        if((!b1 && b2) || (b1 && b2))
        {
                nRotations = 1;
                nInversion = 1;
                return true;
        }
        if(b1 && !b2)
        {
                nRotations = 0;
                nInversion = 2;
                return true;
        }
        return false;
}

bool GetRotationsAndInversions(uint& nRotations, uint& nInversion, vector<bool> vGrayCode)
{       // Curve Dimensions = Rotations + Inverts + 1   // actually there are only two bits inverted, the inversions is really the distance between the two bits
        nRotations =  0;
        nInversion = 0;
        uint nDimensions = GetCurveDimensions();

        bool b1 = false;
        bool b2 = false;

        if(!GetRightLastTwo(b1, b2, vGrayCode)) return false;

        if(nDimensions == 2)
        {
                return GetRotationsAndInversionsForTwoDimensions(b1, b2, nRotations, nInversion, vGrayCode);
        }
        if(nDimensions == 3)
        {
                return GetRotationsAndInversionsForThreeDimensions(b1, b2, nRotations, nInversion, vGrayCode);
        }
        return GetRotationsAndInversions(b1, b2, nDimensions, nRotations, nInversion, vGrayCode);

        return false;
}

 bool GetRotationsAndInversions(bool b1, bool b2, uint nDimensions, uint& nRotations, uint& nInversion, vector<bool> vGrayCode)
{       // Curve Dimensions = Rotations + Inverts + 1   // actually there are only two bits inverted, the inversions is really the distance between the two bits
        if(!b1 && !b2)
        {
                uint nLeftContinousFalseCount = NumberOfContinuousFalseLeftOfRightLastTwo(vGrayCode);
                if(nLeftContinousFalseCount + 2 + 1 == nDimensions)
                {
                        nRotations = nDimensions - 1;
                        nInversion = 0;
                        return true;
                }
                if(nLeftContinousFalseCount + 2 + 1 == nDimensions - 1)
                {
                        nRotations = 0;
                        nInversion = nDimensions - 1;
                        return true;
                }


                if(nLeftContinousFalseCount + 4 > nDimensions) return false;

                nRotations = nDimensions - 4 - nLeftContinousFalseCount;
                nInversion = nDimensions - 1 - nRotations;

               
return true;
        }
        if((!b1 && b2) || (b1 && b2))
        {
                nRotations = nDimensions - 2;
                nInversion = 1;
                return true;
        }
        if(b1 && !b2)
        {
                nRotations = nDimensions - 3;
                nInversion = 2;
                return true;
        }

        return false;
}

vector<bool> RotateCoordinatesLeft(uint nStart, uint nLength, vector<bool> v)
{
        if(v.size() < 2) return v;

        vector<bool> vRotate = v;

        if(nStart + nLength - 1 < v.size())
        {
                vRotate[nStart + nLength - 1] = v[nStart];

                for(uint n = 0; n < nLength - 1; n++)
                {
                        vRotate[nStart + n] = v[nStart + n + 1];
                }
        }

        return vRotate;
}

vector<bool> RotateCoordinatesLeftDownStream(uint nStart, uint nLength, vector<bool> v)
{
        if(v.size() < 2) return v;
        if(nLength  < 2) return v;

        vector<bool> vRotate = v;

        while(nStart + nLength - 1 < v.size())
        {
                 vRotate = RotateCoordinatesLeft(nStart, nLength, vRotate);

                 nStart += nLength;
        }

        return vRotate;
}

vector<bool> RotateCoordinatesRight(uint nStart, uint nLength, vector<bool> v)
{
        if(v.size() < 2) return v;

        if(nLength  < 2) return v;

        vector<bool> vRotate = v;

        if(nStart + nLength - 1 < v.size())
        {
                vRotate[nStart] = v[nStart + nLength - 1];

                for(uint n = 0; n < nLength - 1; n++)
                {
                        vRotate[nStart + n + 1] = v[nStart + n];
                }
        }

        return vRotate;
}

vector<bool> RotateCoordinatesRightDownStream(uint nStart, uint nLength, vector<bool> v)
{
        if(v.size() < 2) return v;

        if(nLength  < 2) return v;

        vector<bool> vRotate = v;

         while(nStart + nLength - 1 < v.size())
        {
                 vRotate = RotateCoordinatesRight(nStart, nLength, vRotate);

                 nStart += nLength;
        }

        return vRotate;
}

vector<bool> OneDimensionalGrayCodeToGrayCoordinatesOf_M_DimensionsAnd_N_BitsPerDimension(uint nDimensions, uint nBitsPerDimension, vector<bool> vGrayCode)  // this is a gray code length into its coordinates as gray code
{// coordinates format (a1 b1 c1 a2 b2 c2 a3 b3 c3)

       
if(vGrayCode.size() != nDimensions * nBitsPerDimension)
        {
                return vGrayCode;  // error
        }

        if((nDimensions() == 1) || (nBitsPerDimension == 1)) return vGrayCode;    // nothing to do

        uint nRotations = 0;
        uint nInversion = 0;
        uint nStartPositionToRotateAndInvert = vGrayCode.size();

        for(uint n = 2; n <= GetCurveIterations(); n++) // iteration = 1 is the generator       // this goes right to left - the lowest are on the right
        {
                nStartPositionToRotateAndInvert -= GetCurveDimensions();

                vector<bool> vIteritiveSegment = GetIteriveSegment(n, vGrayCode);       // this determines how vGrayCode to the right of nStartPositionToRotateAndInvert will rotate and invert

                if(GetRotationsAndInversions(nRotations, nInversion, vIteritiveSegment))
                {
                        if(nInversion > 0)
                        {
                                vGrayCode = InvertCoordinates(nStartPositionToRotateAndInvert, nStartPositionToRotateAndInvert + nInversion, vGrayCode);
                        }

                        for(uint r = 0; r < nRotations; r++)
                        {
                                vGrayCode = RotateCoordinatesRightDownStream(nStartPositionToRotateAndInvert, GetCurveDimensions(), vGrayCode);
                        }
                }
        }

       
return vGrayCode;
}

 

vector<bool> GrayCoordinatesOf_M_DimensionsAnd_N_BitsPerDimensionToOneDimensionalGrayCode(uint nDimensions, uint nBitsPerDimension, vector<bool> vGrayCoordinates)
{// coordinates format (a1 b1 c1 a2 b2 c2 a3 b3 c3)           // this is a gray code coordinates to its length as gray code

        if(vGrayCoordinates.size() != nDimensions * nBitsPerDimension)
        {
                return vGrayCoordinates;    // error
        }

        if((nDimensions() == 1) || (nBitsPerDimension == 1)) return vGrayCoordinates;    // nothing to do

        uint nRotations = 0;
        uint nInversion = 0;
        uint nStartPositionToRotateAndInvert = 0;

 
       for(uint n = GetCurveIterations(); n >= 2; n--) // iteration = 1 is the generator       // this goes left to right - the highest iterations are on the left
        {
                nStartPositionToRotateAndInvert += GetCurveDimensions();
                vector<bool> vIteritiveSegment = GetIteriveSegment(n, vGrayCoordinates);        // this determines how vGrayCode to the right of nStartPositionToRotateAndInvert will rotate and invert

               
if(GetRotationsAndInversions(nRotations, nInversion, vIteritiveSegment))
                {
                        for(uint r = 0; r < nRotations; r++)
                        {
                                vGrayCoordinates = RotateCoordinatesLeftDownStream(nStartPositionToRotateAndInvert, GetCurveDimensions(), vGrayCoordinates);
                        }
                        if(nInversion > 0)
                        {
                                vGrayCoordinates = InvertCoordinates(nStartPositionToRotateAndInvert, nStartPositionToRotateAndInvert + nInversion, vGrayCoordinates);
                        }
                }
        }

        return vGrayCoordinates;
}

vector<bool> BinaryLengthTouint nDimensions, uint nBitsPerDimension, vector<bool> vBool)Bool)
{
        vector<vGrayCoordinates;

        if((nDimensions() == 1) || (nBitsPerDimension == 1))
        {
                vGrayCoordinates =  BinaryNumberToGrayCode(vBool);
        }
        else
        {
                vector<bool> vGrayCode = BinaryNumberToGrayCode(vBinaryLength);
                vGrayCoordinates =
OneDimensionalGrayCodeToGrayCoordinatesOf_M_DimensionsAnd_N_BitsPerDimension(nDimensions, nBitsPerDimension, vGrayCode);
        }

        return vGrayCoordinates;
}

vector<bool> GrayCoordinatesOf_M_DimensionsAnd_N_BitsPerDimensionToBinaryLength(uint nDimensions, uint nBitsPerDimension, vector<bool> vGrayCoordinates )
{
        vector<bool> vBinaryLength;

        if((nDimensions() == 1) || (nBitsPerDimension == 1))
        {
                vBinaryLength = GrayToBinary(vGrayCoordinates );
        }
        else
        {
            vector<bool> vGrayCode = GrayCoordinatesOf_M_DimensionsAnd_N_BitsPerDimensionToOneDimensionalGrayCode(nDimensions, nBitsPerDimension, vGrayCoordinates);
              
            vBinaryLength = GrayToBinary(vGrayCoordinates );
        }

        return vBinaryLength;
}