Пример #1
0
status_t Ifft(mcon::Vector<double>& timeSeries, const mcon::Matrix<double>& complex)
{
    const size_t N = complex.GetColumnLength();
    if (Count1(N) != 1)
    {
        return -ERROR_ILLEGAL;
    }
    mcon::Vector<double> tsPair;
    mcon::Vector<double> sinTable;
    mcon::Vector<double> cosTable;

    if ( false == timeSeries.Resize(N)
        || false == tsPair.Resize(N)
        || false == sinTable.Resize(N)
        || false == cosTable.Resize(N) )
    {
        return -ERROR_CANNOT_ALLOCATE_MEMORY;
    }

    const double df = 2.0 * g_Pi / N;

    for (size_t i = 0; i < N / 2; ++i)
    {
        sinTable[i] = sin(df * i);
        cosTable[i] = cos(df * i);
    }
    // Substitute beforehand
    timeSeries = complex[0];
    tsPair = complex[1];

    size_t innerLoop = N / 2;
    size_t outerLoop = 1;

    // Decimation in frequency.
    for ( ; 0 < innerLoop; innerLoop >>= 1, outerLoop <<= 1)
    {
        //DEBUG_LOG("inner=%d, outer=%d\n", innerLoop, outerLoop);
        for (size_t outer = 0; outer < outerLoop; ++outer )
        {
            const int& step = innerLoop;
            const int ofs = outer * step * 2;
            // Easier to look into.
            void* _pTs = timeSeries;
            void* _pTsPair = tsPair;
            double* pTsL     = reinterpret_cast<double*>(_pTs) + ofs;
            double* pTsPairL = reinterpret_cast<double*>(_pTsPair) + ofs;
            double* pTsH     = reinterpret_cast<double*>(_pTs) + ofs + step;
            double* pTsPairH = reinterpret_cast<double*>(_pTsPair) + ofs + step;
            for (size_t k = 0; k < innerLoop; ++k )
            {
                const double r1 = pTsL[k];
                const double i1 = pTsPairL[k];
                const double r2 = pTsH[k];
                const double i2 = pTsPairH[k];

                const size_t idx = k * outerLoop;
                pTsL[k]     = r1 + r2;
                pTsPairL[k] = i1 + i2;
                pTsH[k]     =   (r1 - r2) * cosTable[idx] - (i1 - i2) * sinTable[idx];
                pTsPairH[k] =   (r1 - r2) * sinTable[idx] + (i1 - i2) * cosTable[idx];
                //DEBUG_LOG("step=%d, ofs=%d, k=%d, idx=%d\n", step, ofs, k, idx);
            }
        }
    }
    // Bit-reverse
    const int width = Ilog2(N);
    //DEBUG_LOG("width=%d\n", width);
    for (size_t i = 0; i < N; ++i )
    {
        const size_t k = BitReverse(i, width);
        if (k < i)
        {
            continue;
        }
        const double ts_temp = timeSeries[k] / N;
        timeSeries[k] = timeSeries[i] / N;
        timeSeries[i] = ts_temp;
    }
    return NO_ERROR;
}
Пример #2
0
status_t Fft(mcon::Matrix<double>& complex, const mcon::Vector<double>& timeSeries)
{
    const size_t N = timeSeries.GetLength();
    if (Count1(N) != 1)
    {
        return -ERROR_ILLEGAL;
    }
    bool status = complex.Resize(2, N);
    if (false == status)
    {
        return -ERROR_CANNOT_ALLOCATE_MEMORY;
    }
    mcon::VectordBase& real = complex[0];
    mcon::VectordBase& imag = complex[1];

    const double df = 2.0 * g_Pi / N;

    mcon::Vector<double> sinTable(N/2);
    mcon::Vector<double> cosTable(N/2);

    for (size_t i = 0; i < N / 2; ++i)
    {
        sinTable[i] = sin(df * i);
        cosTable[i] = cos(df * i);
    }
    // Substitute beforehand
    real = timeSeries;
    imag = 0;

    size_t innerLoop = N / 2;
    int outerLoop = 1;
    //DEBUG_LOG("N=%d\n", N);

    // Decimation in frequency.
    for ( ; 0 < innerLoop; innerLoop >>= 1, outerLoop <<= 1)
    {
        //DEBUG_LOG("inner=%d, outer=%d\n", innerLoop, outerLoop);
        for ( int outer = 0; outer < outerLoop; ++outer )
        {
            const int& step = innerLoop;
            const int ofs = outer * step * 2;
#if 0
            for (size_t k = 0; k < innerLoop; ++k )
            {
                const double r1 = real[k+ofs];
                const double i1 = imag[k+ofs];
                const double r2 = real[k+step+ofs];
                const double i2 = imag[k+step+ofs];

                real[k+ofs] = r1 + r2;
                imag[k+ofs] = i1 + i2;
                const int idx = k * outerLoop;
                //DEBUG_LOG("step=%d, ofs=%d, k=%d, idx=%d\n", step, ofs, k, idx);
                real[k+step+ofs] =   (r1 - r2) * cosTable[idx] + (i1 - i2) * sinTable[idx];
                imag[k+step+ofs] = - (r1 - r2) * sinTable[idx] + (i1 - i2) * cosTable[idx];
            }
#else
            // Easier to look into.
            void* _pReal = real;
            void* _pImag = imag;
            double* pRealL = reinterpret_cast<double*>(_pReal) + ofs;
            double* pImagL = reinterpret_cast<double*>(_pImag) + ofs;
            double* pRealH = reinterpret_cast<double*>(_pReal) + ofs + step;
            double* pImagH = reinterpret_cast<double*>(_pImag) + ofs + step;
            for (size_t k = 0; k < innerLoop; ++k )
            {
                const double r1 = pRealL[k];
                const double i1 = pImagL[k];
                const double r2 = pRealH[k];
                const double i2 = pImagH[k];

                const size_t idx = k * outerLoop;
                pRealL[k] = r1 + r2;
                pImagL[k] = i1 + i2;
                pRealH[k] =   (r1 - r2) * cosTable[idx] + (i1 - i2) * sinTable[idx];
                pImagH[k] = - (r1 - r2) * sinTable[idx] + (i1 - i2) * cosTable[idx];
                //DEBUG_LOG("step=%d, ofs=%d, k=%d, idx=%d\n", step, ofs, k, idx);
            }
#endif
        }
    }
    // Bit-reverse
    const int width = Ilog2(N);
    //DEBUG_LOG("width=%d\n", width);
    for (size_t i = 0; i < N; ++i )
    {
        const size_t k = BitReverse(i, width);
        if (k == i || k < i)
        {
            continue;
        }
        const double real_temp = real[k];
        const double imag_temp = imag[k];
        real[k] = real[i];
        imag[k] = imag[i];
        real[i] = real_temp;
        imag[i] = imag_temp;
    }
    return NO_ERROR;
}
Пример #3
0
void HuffmanDecoder::Initialize(const unsigned int *codeBits, unsigned int nCodes)
{
	// the Huffman codes are represented in 3 ways in this code:
	//
	// 1. most significant code bit (i.e. top of code tree) in the least significant bit position
	// 2. most significant code bit (i.e. top of code tree) in the most significant bit position
	// 3. most significant code bit (i.e. top of code tree) in n-th least significant bit position,
	//    where n is the maximum code length for this code tree
	//
	// (1) is the way the codes come in from the deflate stream
	// (2) is used to sort codes so they can be binary searched
	// (3) is used in this function to compute codes from code lengths
	//
	// a code in representation (2) is called "normalized" here
	// The BitReverse() function is used to convert between (1) and (2)
	// The NormalizeCode() function is used to convert from (3) to (2)

	if (nCodes == 0)
		throw Err("null code");

	m_maxCodeBits = *std::max_element(codeBits, codeBits+nCodes);

	if (m_maxCodeBits > MAX_CODE_BITS)
		throw Err("code length exceeds maximum");

	if (m_maxCodeBits == 0)
		throw Err("null code");

	// count number of codes of each length
	SecBlockWithHint<unsigned int, 15+1> blCount(m_maxCodeBits+1);
	std::fill(blCount.begin(), blCount.end(), 0);
	unsigned int i;
	for (i=0; i<nCodes; i++)
		blCount[codeBits[i]]++;

	// compute the starting code of each length
	code_t code = 0;
	SecBlockWithHint<code_t, 15+1> nextCode(m_maxCodeBits+1);
	nextCode[1] = 0;
	for (i=2; i<=m_maxCodeBits; i++)
	{
		// compute this while checking for overflow: code = (code + blCount[i-1]) << 1
		if (code > code + blCount[i-1])
			throw Err("codes oversubscribed");
		code += blCount[i-1];
		if (code > (code << 1))
			throw Err("codes oversubscribed");
		code <<= 1;
		nextCode[i] = code;
	}

	if (code > (1 << m_maxCodeBits) - blCount[m_maxCodeBits])
		throw Err("codes oversubscribed");
	else if (m_maxCodeBits != 1 && code < (1 << m_maxCodeBits) - blCount[m_maxCodeBits])
		throw Err("codes incomplete");

	// compute a vector of <code, length, value> triples sorted by code
	m_codeToValue.resize(nCodes - blCount[0]);
	unsigned int j=0;
	for (i=0; i<nCodes; i++) 
	{
		unsigned int len = codeBits[i];
		if (len != 0)
		{
			code = NormalizeCode(nextCode[len]++, len);
			m_codeToValue[j].code = code;
			m_codeToValue[j].len = len;
			m_codeToValue[j].value = i;
			j++;
		}
	}
	std::sort(m_codeToValue.begin(), m_codeToValue.end());

	// initialize the decoding cache
	m_cacheBits = STDMIN(9U, m_maxCodeBits);
	m_cacheMask = (1 << m_cacheBits) - 1;
	m_normalizedCacheMask = NormalizeCode(m_cacheMask, m_cacheBits);
	CRYPTOPP_ASSERT(m_normalizedCacheMask == BitReverse(m_cacheMask));

	if (m_cache.size() != size_t(1) << m_cacheBits)
		m_cache.resize(1 << m_cacheBits);

	for (i=0; i<m_cache.size(); i++)
		m_cache[i].type = 0;
}