Eigen: static assertion failed - c++

I need to use the eigen library in my project on Ubuntu (this project works fine on windows). However when I compile I receive the following error:
dv_qkd_ldpc_tx_error_correction_20200819.cpp:186:91: required from here
Eigen/src/Core/util/XprHelper.h:835:96: error: static assertion failed: YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY
Acording to terminal, this error is caused by one of my .cpp file at the line 186:
*pt_calculatedSindrome = sparseParityCheckMatrix * (*pt_receivedData);
or
*pt_calculatedSindrome = (*pt_calculatedSindrome).unaryExpr([](const t_binary x) {return x % 2;}); //to compute mod(sindrome,2)
I understand that this error is asking to apply some casting on the matrixes. And according to this page, I applied the following which didn't work:
*pt_calculatedSindrome = (sparseParityCheckMatrix.cast<t_binary>()) * ((*pt_receivedData).cast<t_binary>());
*pt_calculatedSindrome = ((*pt_calculatedSindrome).cast<t_binary>()).unaryExpr([](const t_binary x) {return x % 2;}); //to compute mod(sindrome,2)
Edit: in which:
t_binary = uint8_t
Even when I comment these lines (or even when I remove the whole lines of the file), I still get the same error with the same error line!!! I checked my Makefile to make sure it builds all the .cpp files and it seems to be ok.
Here are the terminal errors:
In file included from Eigen/Core:369,
from Eigen/SparseCore:11,
from Eigen/Sparse:26,
from netxpto_20200819.h:48,
from dv_qkd_ldpc_tx_error_correction_20200819.h:4,
from dv_qkd_ldpc_tx_error_correction_20200819.cpp:1:
Eigen/src/Core/AssignEvaluator.h: In instantiation of ‘void Eigen::internal::call_assignment_no_alias(Dst&, const Src&, const Func&) [with Dst = Eigen::Matrix<unsigned char, -1, 1, 0, -1, 1>; Src = Eigen::CwiseUnaryOp<DvQkdLdpcTxErrorCorrection::runBlock()::<lambda(t_binary)>, const Eigen::Matrix<unsigned char, -1, 1, 0, -1, 1> >; Func = Eigen::internal::assign_op<unsigned char, int>]’:
Eigen/src/Core/AssignEvaluator.h:804:27: required from ‘void Eigen::internal::call_assignment(Dst&, const Src&, const Func&, typename Eigen::internal::enable_if<(! Eigen::internal::evaluator_assume_aliasing<Src>::value), void*>::type) [with Dst = Eigen::Matrix<unsigned char, -1, 1, 0, -1, 1>; Src = Eigen::CwiseUnaryOp<DvQkdLdpcTxErrorCorrection::runBlock()::<lambda(t_binary)>, const Eigen::Matrix<unsigned char, -1, 1, 0, -1, 1> >; Func = Eigen::internal::assign_op<unsigned char, int>; typename Eigen::internal::enable_if<(! Eigen::internal::evaluator_assume_aliasing<Src>::value), void*>::type = void*]’
Eigen/src/Core/AssignEvaluator.h:782:18: required from ‘void Eigen::internal::call_assignment(Dst&, const Src&) [with Dst = Eigen::Matrix<unsigned char, -1, 1, 0, -1, 1>; Src = Eigen::CwiseUnaryOp<DvQkdLdpcTxErrorCorrection::runBlock()::<lambda(t_binary)>, const Eigen::Matrix<unsigned char, -1, 1, 0, -1, 1> >]’
Eigen/src/Core/PlainObjectBase.h:714:32: required from ‘Derived& Eigen::PlainObjectBase<Derived>::_set(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<DvQkdLdpcTxErrorCorrection::runBlock()::<lambda(t_binary)>, const Eigen::Matrix<unsigned char, -1, 1, 0, -1, 1> >; Derived = Eigen::Matrix<unsigned char, -1, 1, 0, -1, 1>]’
Eigen/src/Core/Matrix.h:225:24: required from ‘Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::operator=(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<DvQkdLdpcTxErrorCorrection::runBlock()::<lambda(t_binary)>, const Eigen::Matrix<unsigned char, -1, 1, 0, -1, 1> >; _Scalar = unsigned char; int _Rows = -1; int _Cols = 1; int _Options = 0; int _MaxRows = -1; int _MaxCols = 1]’
dv_qkd_ldpc_tx_error_correction_20200819.cpp:186:89: required from here
Eigen/src/Core/util/XprHelper.h:835:96: error: static assertion failed: YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY
835 | ernal::has_ReturnType<ScalarBinaryOpTraits<LHS, RHS,BINOP> >::value), \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
Eigen/src/Core/util/StaticAssert.h:33:54: note: in definition of macro ‘EIGEN_STATIC_ASSERT’
33 | #define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
| ^
Eigen/src/Core/AssignEvaluator.h:834:3: note: in expansion of macro ‘EIGEN_CHECK_BINARY_COMPATIBILIY’
834 | EIGEN_CHECK_BINARY_COMPATIBILIY(Func,typename ActualDstTypeCleaned::Scalar,typename Src::Scalar);
Makefile:91: recipe for target 'dv_qkd_ldpc_tx_error_correction_20200819.o' failed
Here is .cpp file causing error:
#include "cv_qokd_ldpc_tx_sindrome_reconciliation_20200819.h"
void CvQokdLdpcTxSindromeReconciliation::initialize(void)
{
if (errorCorrectionMethod == CvQokdLdpcTxSindromeReconciliation::t_method::LDPC)
{
loadSparseParityCheckMatrix();
sparseParityCheckMatrixTranspose = sparseParityCheckMatrix.transpose();
calculatedSindromeSize_0 = codeLength - codeRank;
calculatedSindrome_0.resize(calculatedSindromeSize_0, 1);
calculatedSindrome_0_posIn = 0;
calculatedSindrome_0_posOut = calculatedSindrome_0.size();
calculatedSindrome_0_newData = false;
calculatedSindromeSize_1 = codeLength - codeRank;
calculatedSindrome_1.resize(calculatedSindromeSize_1, 1);
calculatedSindrome_1_posIn = 0;
calculatedSindrome_1_posOut = calculatedSindrome_1.size();
calculatedSindrome_1_newData = false;
receivedSindromeSize = 1; // codeLength - codeRank;
receivedSindrome.resize(receivedSindromeSize, 1);
receivedSindrome_posIn = 0;
receivedSindrome_posOut = receivedSindrome.size();
receivedSindrome_newData = false;
receivedDataSize_0 = codeLength;
receivedData_0.resize(receivedDataSize_0, 1);
receivedData_0_posIn = 0;
receivedData_0_posOut = receivedData_0.size();
receivedData_0_newData = false;
receivedDataSize_1 = codeLength;
receivedData_1.resize(receivedDataSize_1, 1);
receivedData_1_posIn = 0;
receivedData_1_posOut = receivedData_1.size();
receivedData_1_newData = false;
DataIn.resize((size_t)4*inputSignals[0]->getBufferLength());
DataOut.resize(DataIn.size());
SindromeIn.resize((size_t)4*inputSignals[1]->getBufferLength());
SindromeOut.resize(SindromeIn.size());
prioriMessageProbabilities.resize(codeLength, 1);
M.resize(codeLength - codeRank, codeLength);
M.reserve(numberOfNonZerosValuesInSparseParityCheckMatrix);
E.resize(codeLength - codeRank, codeLength);
E.reserve(numberOfNonZerosValuesInSparseParityCheckMatrix);
tripletList.reserve(getNumberOfNonZerosValuesInSparseParityCheckMatrix());
bitFillingPeriod = numberOfDataBitsPerBitFillingPeriod + numberOfDummyBitsPerBitFillingPeriod;
}
else
{
std::cerr << "DVQkdErrorCorrectionLDPC::initialize() - wrong error correction method";
}
startSendingSindrome = (getErrorCorrectionRole() == t_role::Rx && getErrorCorrectionMode() == t_mode::InverseReconciliation) || (getErrorCorrectionRole() == t_role::Tx && getErrorCorrectionMode() == t_mode::DirectReconciliation);
}
bool CvQokdLdpcTxSindromeReconciliation::runBlock(void)
{
if (bypassErrorCorrection)
{
auto ready = inputSignals[0]->ready();
auto space = outputSignals[0]->space();
auto process = std::min(ready, space);
totalNumberOfInputBits += process;
totalNumberOfOutputBits += process;
for (; process--;)
{
t_binary dataIn{ 0 };
inputSignals[0]->bufferGet(&dataIn);
outputSignals[0]->bufferPut(dataIn);
}
for (auto k = 1; k < inputSignals.size(); k++)
{
ready = inputSignals[k]->ready();
space = inputSignals[k]->space();
process = std::min(ready, space);
for (; process--;)
inputSignals[k]->bufferGet();
}
return false;
}
bool alive{ false };
Eigen::Index ready = DataOut.ready();
Eigen::Index space = outputSignals[0]->space();
Eigen::Index process = std::min(ready, space);
alive = !alive ? process > 0: alive;
totalNumberOfOutputBits += process;
for (; process--;)
outputSignals[0]->bufferPut(DataOut.bufferGet());
ready = SindromeOut.ready();
space = outputSignals[1]->space();
process = std::min(ready, space);
alive = !alive ? process > 0: alive;
for (; process--;)
outputSignals[1]->bufferPut(SindromeOut.bufferGet());
ready = inputSignals[0]->ready();
space = DataIn.space();
process = std::min(ready, space);
alive = !alive ? process > 0: alive;
totalNumberOfInputBits += process;
for (; process--;)
{
t_binary val{ 0 };
inputSignals[0]->bufferGet(&val);
DataIn.bufferPut(val);
}
ready = inputSignals[1]->ready();
space = SindromeIn.space();
process = std::min(ready, space);
alive = !alive ? process > 0: alive;
for (; process--;)
{
t_binary val{ 0 };
inputSignals[1]->bufferGet(&val);
SindromeIn.bufferPut(val);
}
ready = SindromeIn.ready();
process = std::min(ready, receivedSindromeSize - receivedSindrome_posIn);
alive = !alive ? process > 0: alive;
for (auto k = receivedSindrome_posIn; k < receivedSindrome_posIn + process; k++)
receivedSindrome(k, 0) = SindromeIn.bufferGet();
receivedSindrome_posIn += process;
if (process > 0 && receivedSindrome_posIn == receivedSindromeSize)
{
if (getVerboseMode())
{
std::ofstream file;
file.open(getSignalsFolderName() + "/received_sindrome_tx.txt", std::ios_base::app);
for (auto k = 0; k < receivedSindromeSize; k++)
{
if (k != 0) file << " ";
file << std::to_string(receivedSindrome[k]);
}
file << std::endl;
file.close();
}
receivedSindrome_newData = true;
}
ready = DataIn.ready();
process = std::min( ready, *pt_receivedDataSize - *pt_receivedData_posIn);
alive = !alive ? process > 0: alive;
for (auto k = *pt_receivedData_posIn; k < *pt_receivedData_posIn + process; k++)
{
if (numberOfDummyBitsPerBitFillingPeriod)
{
if (*pt_inDataBitFillingCounter >= numberOfDataBitsPerBitFillingPeriod)
{
(*pt_receivedData)[k] = 0;
}
else
(*pt_receivedData)[k] = DataIn.bufferGet();
*pt_inDataBitFillingCounter = ++(*pt_inDataBitFillingCounter) % bitFillingPeriod;
}
else
(*pt_receivedData)[k] = DataIn.bufferGet();
}
*pt_receivedData_posIn += process;
if (process > 0 && *pt_receivedData_posIn == *pt_receivedDataSize)
*pt_receivedData_newData = true;
if (*pt_receivedData_newData && *pt_calculatedSindrome_posIn == 0 && *pt_calculatedSindrome_newData == false)
{
if (getVerboseMode())
{
std::ofstream file;
file.open(getSignalsFolderName() + "/receivedData_tx.txt", std::ios_base::app);
for (auto k = 0; k < *pt_receivedDataSize; k++)
{
if (k != 0 && k % 200 == 0) file << std::endl;
file << std::to_string((*pt_receivedData)[k]);
}
file << std::endl;
file.close();
}
*pt_calculatedSindrome = sparseParityCheckMatrix * *pt_receivedData;
*pt_calculatedSindrome = (*pt_calculatedSindrome).unaryExpr([](const t_binary x) {return x % 2;}); //to compute mod(sindrome,2)
numberOfCalculatedSindromes++;
*pt_receivedData_posIn = *pt_receivedDataSize;
*pt_receivedData_posOut = *pt_receivedDataSize;
*pt_receivedData_newData = false;
if (getVerboseMode())
{
std::ofstream file;
file.open(getSignalsFolderName() + "/calculated_sindrome_tx.txt", std::ios_base::app);
for (auto k = 0; k < *pt_calculatedSindromeSize; k++)
{
if (k != 0) file << " ";
file << std::to_string((*pt_calculatedSindrome)[k]);
}
file << std::endl;
file.close();
}
*pt_calculatedSindrome_posIn = *pt_calculatedSindromeSize;
*pt_calculatedSindrome_newData = true;
if (process_block == 1)
{
if (startSendingSindrome)
{
calculatedSindrome_1_posOut = 0;
startedSendingSindrome_1 = true;
}
process_block = 0;
pt_receivedDataSize = &receivedDataSize_0;
pt_receivedData = &receivedData_0;
pt_receivedData_posIn = &receivedData_0_posIn;
pt_receivedData_posOut = &receivedData_0_posOut;
pt_receivedData_newData = &receivedData_0_newData;
pt_calculatedSindrome = &calculatedSindrome_0;
pt_calculatedSindromeSize = &calculatedSindromeSize_0;
pt_calculatedSindrome_posIn = &calculatedSindrome_0_posIn;
pt_calculatedSindrome_posOut = &calculatedSindrome_0_posOut;
pt_calculatedSindrome_newData = &calculatedSindrome_0_newData;
pt_inDataBitFillingCounter = &inDataBitFillingCounter_0;
pt_outDataBitFillingCounter = &outDataBitFillingCounter_0;
}
else
{
if (startSendingSindrome)
{
calculatedSindrome_0_posOut = 0;
startedSendingSindrome_0 = true;
}
process_block = 1;
pt_receivedDataSize = &receivedDataSize_1;
pt_receivedData = &receivedData_1;
pt_receivedData_posIn = &receivedData_1_posIn;
pt_receivedData_posOut = &receivedData_1_posOut;
pt_receivedData_newData = &receivedData_1_newData;
pt_calculatedSindrome = &calculatedSindrome_1;
pt_calculatedSindromeSize = &calculatedSindromeSize_1;
pt_calculatedSindrome_posIn = &calculatedSindrome_1_posIn;
pt_calculatedSindrome_posOut = &calculatedSindrome_1_posOut;
pt_calculatedSindrome_newData = &calculatedSindrome_1_newData;
pt_inDataBitFillingCounter = &inDataBitFillingCounter_1;
pt_outDataBitFillingCounter = &outDataBitFillingCounter_1;
}
}
ready = calculatedSindromeSize_0 - calculatedSindrome_0_posOut;
space = SindromeOut.space();
process = std::min(ready, space);
if ( startedSendingSindrome_0 && (!startedSendingSindrome_1) && process)
{
for (auto k = calculatedSindrome_0_posOut; k < calculatedSindrome_0_posOut + process; k++)
SindromeOut.bufferPut(calculatedSindrome_0[k]);
calculatedSindrome_0_posOut = calculatedSindrome_0_posOut + process;
if (calculatedSindrome_0_posIn == calculatedSindromeSize_0) calculatedSindrome_0_posIn = 0;
if (calculatedSindrome_0_posOut == calculatedSindromeSize_0)
startedSendingSindrome_0 = false;
}
ready = calculatedSindromeSize_1 - calculatedSindrome_1_posOut;
space = SindromeOut.space();
process = std::min(ready, space);
if (startedSendingSindrome_1 && (!startedSendingSindrome_0) && process)
{
for (auto k = calculatedSindrome_1_posOut; k < calculatedSindrome_1_posOut + process; k++)
SindromeOut.bufferPut(calculatedSindrome_1[k]);
calculatedSindrome_1_posOut = calculatedSindrome_1_posOut + process;
if (calculatedSindrome_1_posIn == calculatedSindromeSize_1) calculatedSindrome_1_posIn = 0;
if (calculatedSindrome_1_posOut == calculatedSindromeSize_1)
startedSendingSindrome_1 = false;
}
if (receivedSindrome_newData)
{
numberOfValidatedSindromes++;
if (receivedSindrome[0]==0)
{
numberOfNoMatchedSindromes++;
receivedData_0_posIn = 0;
receivedData_1_posIn = 0;
}
else
{
receivedData_0_posOut = 0;
receivedData_1_posOut = 0;
}
receivedSindrome_posIn = 0;
receivedSindrome_newData = false;
calculatedSindrome_0_newData = false;
calculatedSindrome_1_newData = false;
calculatedSindrome_0_posOut = 0;
calculatedSindrome_1_posOut = 0;
}
ready = std::min(receivedDataSize_0 - receivedData_0_posOut, receivedDataSize_1 - receivedData_1_posOut);
space = (Eigen::Index) (DataOut.space()/3);
process = std::min(ready, space);
if (process)
{
for (auto k = 0; k < process; k++)
{
if (numberOfDummyBitsPerBitFillingPeriod)
{
if (*pt_outDataBitFillingCounter < numberOfDataBitsPerBitFillingPeriod)
{
DataOut.bufferPut(receivedData_0[receivedData_0_posOut + k]);
DataOut.bufferPut(receivedData_1[receivedData_1_posOut + k]);
}
*pt_outDataBitFillingCounter = ++(*pt_outDataBitFillingCounter) % bitFillingPeriod;
}
else
{
DataOut.bufferPut((t_binary) 0);
DataOut.bufferPut(receivedData_0[receivedData_0_posOut + k]);
DataOut.bufferPut(receivedData_1[receivedData_1_posOut + k]);
}
}
receivedData_0_posOut = receivedData_0_posOut + process;
receivedData_1_posOut = receivedData_1_posOut + process;
if (receivedData_0_posIn == receivedDataSize_0) receivedData_0_posIn = 0;
if (receivedData_1_posIn == receivedDataSize_1) receivedData_1_posIn = 0;
if (sindromeMatch) sindromeMatch = false;
}
ready = DataOut.ready();
space = outputSignals[0]->space();
process = std::min(ready, space);
alive = !alive ? process > 0: alive;
totalNumberOfOutputBits += process;
for (; process--;)
outputSignals[0]->bufferPut(DataOut.bufferGet());
ready = SindromeOut.ready();
space = outputSignals[1]->space();
process = std::min(ready, space);
alive = !alive ? process > 0: alive;
for (; process--;)
outputSignals[1]->bufferPut(SindromeOut.bufferGet());
ready = SindromeIn.ready();
process = std::min(ready, receivedSindromeSize - receivedSindrome_posIn);
alive = !alive ? process > 0: alive;
for (auto k = receivedSindrome_posIn; k < receivedSindrome_posIn + process; k++)
receivedSindrome(k, 0) = SindromeIn.bufferGet();
receivedSindrome_posIn += process;
if (process > 0 && receivedSindrome_posIn == receivedSindromeSize)
{
if (getVerboseMode())
{
std::ofstream file;
file.open("/received_sindrome_tx.txt", std::ios_base::app);
for (auto k = 0; k < receivedSindromeSize; k++)
file << std::to_string(receivedSindrome[k]);
file.close();
}
receivedSindrome_newData = true;
}
ready = DataIn.ready();
process = std::min(ready, (*pt_receivedDataSize) - (*pt_receivedData_posIn));
alive = !alive ? process > 0: alive;
for (auto k = *pt_receivedData_posIn; k < *pt_receivedData_posIn + process; k++)
{
if (numberOfDummyBitsPerBitFillingPeriod)
{
if (*pt_inDataBitFillingCounter >= numberOfDataBitsPerBitFillingPeriod)
{
(*pt_receivedData)[k] = 0;
}
else
(*pt_receivedData)[k] = DataIn.bufferGet();
*pt_inDataBitFillingCounter = ++(*pt_inDataBitFillingCounter) % bitFillingPeriod;
}
else
(*pt_receivedData)[k] = DataIn.bufferGet();
}
*pt_receivedData_posIn += process;
if (process > 0 && *pt_receivedData_posIn == *pt_receivedDataSize)
*pt_receivedData_newData = true;
return alive;
}
t_bool CvQokdLdpcTxSindromeReconciliation::errorCorrectionLDPCAlgorithm(Eigen::Matrix<t_binary, Eigen::Dynamic, 1>* pt_calculatedSindrome, Eigen::Matrix<t_binary, Eigen::Dynamic, 1>* pt_receivedData)
{
for (int k = 0; k < codeLength; ++k)
{
if ((*pt_receivedData)[k] == 0)
prioriMessageProbabilities[k] = log((1 - p_f) / p_f);
else
prioriMessageProbabilities[k] = log(p_f / (1 - p_f));
}
for (int k = 0; k < sparseParityCheckMatrix.outerSize(); ++k) // iterates over the columns
{
for (Eigen::SparseMatrix<t_binary>::InnerIterator h(sparseParityCheckMatrix, k); h; ++h) //iterates over the non-zero elements of each column
{
tripletList.push_back(T((int)h.row(), k, prioriMessageProbabilities[k]));
}
}
M.setFromTriplets(tripletList.begin(), tripletList.end());
tripletList.resize(0);
auto sindromeNoMatch{ 0 };
for (auto m = 0; m < ldpcErrorCorrectionAlgorithMaxIterations; ++m)
{
for (int k = 0; k < sparseParityCheckMatrixTranspose.outerSize(); ++k) // iterates over the columns of H^T, i.e. the lines of H
{
for (Eigen::SparseMatrix<t_binary>::InnerIterator h(sparseParityCheckMatrixTranspose, k); h; ++h) //iterates over the non-zero elements of each column of H^T, i.e. over the non-zero elements of each line of H
{
t_real prod{ 1 };
for (Eigen::SparseMatrix<t_binary>::InnerIterator o(sparseParityCheckMatrixTranspose, k); o; ++o) //iterates over the non-zero elements of each column of H^T, i.e. over the non-zero elements of each line of H
{
if (o.row() != h.row())
prod = prod * tanh(M.coeff(k, (int)o.row()) / 2);
}
tripletList.push_back(T(k, (int)h.row(), log(1 + (1 - 2 * (t_real)receivedSindrome[k]) * prod) - log(1 - (1 - 2 * (t_real)receivedSindrome[k]) * prod)));
}
}
E.setFromTriplets(tripletList.begin(), tripletList.end());
tripletList.resize(0);
for (int k = 0; k < codeLength; ++k)
{
t_real sum{ 0 };
for (Eigen::SparseMatrix<t_binary>::InnerIterator h(sparseParityCheckMatrix, k); h; ++h)
{
sum = sum + E.coeff((int)h.row(), k);
}
auto L = sum + prioriMessageProbabilities[k];
if (L <= 0.0)
(*pt_receivedData)[k] = 1;
else
(*pt_receivedData)[k] = 0;
}
*pt_calculatedSindrome = sparseParityCheckMatrix * *pt_receivedData;
*pt_calculatedSindrome = (*pt_calculatedSindrome).unaryExpr([](const t_binary x) {return x % 2;}); //to compute mod(sindrome,2)
sindromeNoMatch = 0;
for (auto k = 0; k < *pt_calculatedSindromeSize; k++)
if ((*pt_calculatedSindrome)[k] != receivedSindrome[k])
sindromeNoMatch++;
if (sindromeNoMatch == 0)
{
if (getVerboseMode())
{
std::ofstream file;
file.open( getSignalsFolderName() + "/new_sindrome_tx.txt", std::ios_base::app);
if (file.is_open())
{
for (auto k = 0; k < *pt_calculatedSindromeSize; k++)
file << std::to_string((*pt_calculatedSindrome)[k]);
file << std::endl;
file.close();
}
else
std::cerr << "DV_QKD_LDPC_TX_Error_Correction: Error opening file";
}
break;
}
for (int k = 0; k < sparseParityCheckMatrix.outerSize(); ++k) // iterates over the columns of H
{
for (Eigen::SparseMatrix<t_binary>::InnerIterator h(sparseParityCheckMatrix, k); h; ++h) //iterates over the non-zero elements of each column of H
{
t_real sum{ 0 };
for (Eigen::SparseMatrix<t_binary>::InnerIterator o(sparseParityCheckMatrix, k); o; ++o) //iterates over the non-zero elements of each column of H^T, i.e. over the non-zero elements of each line of H
{
if (o.row() != h.row())
sum = sum + E.coeff((int)o.row(), k);
}
tripletList.push_back(T((int)h.row(), k, sum + prioriMessageProbabilities[k]));
}
}
M.setFromTriplets(tripletList.begin(), tripletList.end());
tripletList.resize(0);
}
if (sindromeNoMatch > 0)
return false;
else
return true;
}
void CvQokdLdpcTxSindromeReconciliation::loadSparseParityCheckMatrix()
{
auto pos_a = parityCheckMatrixFileName.find("_n");
auto pos_b = parityCheckMatrixFileName.find("_k");
codeLength = stoi(parityCheckMatrixFileName.substr(pos_a + 2, pos_b - pos_a - 2));
pos_a = parityCheckMatrixFileName.find("_k");
pos_b = parityCheckMatrixFileName.find("_nonZeros");
codeRank = stoi(parityCheckMatrixFileName.substr(pos_a + 2, pos_b - pos_a - 2));
pos_a = parityCheckMatrixFileName.find("_nonZeros");
pos_b = parityCheckMatrixFileName.find(".dat");
numberOfNonZerosValuesInSparseParityCheckMatrix = stoi(parityCheckMatrixFileName.substr(pos_a + 9, pos_b - pos_a - 9));
sparseParityCheckMatrix.resize(codeLength - codeRank, codeLength);
sparseParityCheckMatrix.reserve(numberOfNonZerosValuesInSparseParityCheckMatrix);
if (parityCheckMatrixFileName.substr(parityCheckMatrixFileName.find_last_of(".") + 1) == "txt")
{
std::fstream fp;
fp.open(parityCheckMatrixFolderName + "/" + parityCheckMatrixFileName, std::ios::in);
if (!fp.is_open()) std::cerr << "Error in dv_qkd_ldpc_error_correction_.cpp: file sparseParityCheckMatrix.txt not found!!!!";
double data;
int row{ 0 }, column{ 0 };
while (true)
{
fp >> data;
if (data != 0)
sparseParityCheckMatrix.insert(row, column) = (uint8_t)data;
column++;
if (column == codeLength)
{
column = 0;
row++;
}
if (row == codeLength - codeRank)
break;
}
fp.close();
}
else if (parityCheckMatrixFileName.substr(parityCheckMatrixFileName.find_last_of(".") + 1) == "dat")
{
std::ifstream parityCheckMatrixFile(parityCheckMatrixFolderName + "/" + parityCheckMatrixFileName);
if (!parityCheckMatrixFile.is_open()) std::cerr << "Error in dv_qkd_ldpc_error_correction_.cpp: file parityCheckMatrixFileName not found!!!!";;
size_t bufferSize = (codeLength - codeRank) * codeLength;
std::unique_ptr<char[]> buffer(new char[bufferSize]);
parityCheckMatrixFile.read(buffer.get(), bufferSize);
int row{ 0 }, column{ 0 };
uint8_t data{ 0 };
char* ptr{ &buffer[0] };
for (auto k = 0; k < bufferSize; ++k)
{
data = *ptr - '0';
if (data != 0)
sparseParityCheckMatrix.insert(row, column) = (uint8_t)data;
ptr++;
column++;
if (column == codeLength)
{
column = 0;
row++;
}
}
}
else
{
std::cerr << "DVQkdRxErrorCorrectionLDPC::loadSparseParityCheckMatrix() - wrong file extension";
}
if (getVerboseMode())
{
std::ofstream file;
file.open(getSignalsFolderName() + "/SparseParityCheckMatrix.txt", std::ios_base::out);
if (file.is_open())
{
file << "Position of no-zero values (row, column)" << std::endl;
for (int k = 0; k < sparseParityCheckMatrix.outerSize(); ++k) // iterates over the columns of H
{
for (Eigen::SparseMatrix<t_binary>::InnerIterator it(sparseParityCheckMatrix, k); it; ++it)
file << "(" << it.row() << ", " << it.col() << ")" << std::endl;
}
file.close();
}
else
std::cerr << "Error in dv_qkd_ldpc_rx_error_correction_.cpp: file not open!!!";
}
return;
}
Any help is appreciated.

Related

Implement next combination - C_n_k on C++ using vector

I am getting stuck - can't implement perfect algorithm for next Combination for lexicographical order. Could you please tell me where I get wrong? For instance, e.g. vector a = {1,2,0,3,0,1,2,4}; nextPermutation(a); has an overflow-heap when accessing to an element of the array std::next. How would this code be improved?
void nextPermutation(vector<int>& perm) {
auto temp1 = perm[0], temp2 = perm[0];
int idx1 = -1, idx2 = -1;
if (perm.size() == 1)
return;
if (perm.size() == 2)
{
reverse(perm.begin(), perm.end());
return;
}
for (auto &v : perm)
{
if (&v - &perm[0] == perm.size())
break;
if (v < *(&v + 1))
{
temp1 = v;
idx1 = &v - &perm[0];
//cout << idx1 << endl;
}
}
if (idx1 == -1)
{
reverse(perm.begin(), perm.end());
return;
}
for (auto v = perm.begin(); v < perm.end(); v++)
{
if (*v > *next(perm.begin(), idx1))
{
temp2 = *v;
idx2 = std::distance(perm.begin(), v);
//cout << idx2 << endl;
}
}
int temp = perm[idx1];
perm[idx1] = perm[idx2];
perm[idx2] = temp;
reverse(perm.begin() + idx1 + 1, perm.end());
}

Product of all the nodes on the path of a tree

I was learning MO's Algorithm. In that I found a question. In which we have to make a program to take input n for n nodes of a tree then n-1 pairs of u and v denoting the connection between node u and node v. After that giving the n node values.
Then we will ask q queries. For each query we take input of k and l which denote the two nodes of that tree. Now we have to find the product of all the nodes in the path of k and l (including k and l).
I want to use MO's algorithm. https://codeforces.com/blog/entry/43230
But I am unable to make the code. Can anybody help me out in this.
The basic code for that would be:
int n, q;
int nxt[ N ], to[ N ], hd[ N ];
struct Que{
int u, v, id;
} que[ N ];
void init() {
// read how many nodes and how many queries
cin >> n >> q;
// read the edge of tree
for ( int i = 1 ; i < n ; ++ i ) {
int u, v; cin >> u >> v;
// save the tree using adjacency list
nxt[ i << 1 | 0 ] = hd[ u ];
to[ i << 1 | 0 ] = v;
hd[ u ] = i << 1 | 0;
nxt[ i << 1 | 1 ] = hd[ v ];
to[ i << 1 | 1 ] = u;
hd[ v ] = i << 1 | 1;
}
for ( int i = 0 ; i < q ; ++ i ) {
// read queries
cin >> que[ i ].u >> que[ i ].v;
que[ i ].id = i;
}
}
int dfn[ N ], dfn_, block_id[ N ], block_;
int stk[ N ], stk_;
void dfs( int u, int f ) {
dfn[ u ] = dfn_++;
int saved_rbp = stk_;
for ( int v_ = hd[ u ] ; v_ ; v_ = nxt[ v_ ] ) {
if ( to[ v_ ] == f ) continue;
dfs( to[ v_ ], u );
if ( stk_ - saved_rbp < SQRT_N ) continue;
for ( ++ block_ ; stk_ != saved_rbp ; )
block_id[ stk[ -- stk_ ] ] = block_;
}
stk[ stk_ ++ ] = u;
}
bool inPath[ N ];
void SymmetricDifference( int u ) {
if ( inPath[ u ] ) {
// remove this edge
} else {
// add this edge
}
inPath[ u ] ^= 1;
}
void traverse( int& origin_u, int u ) {
for ( int g = lca( origin_u, u ) ; origin_u != g ; origin_u = parent_of[ origin_u ] )
SymmetricDifference( origin_u );
for ( int v = u ; v != origin_u ; v = parent_of[ v ] )
SymmetricDifference( v );
origin_u = u;
}
void solve() {
// construct blocks using dfs
dfs( 1, 1 );
while ( stk_ ) block_id[ stk[ -- stk_ ] ] = block_;
// re-order our queries
sort( que, que + q, [] ( const Que& x, const Que& y ) {
return tie( block_id[ x.u ], dfn[ x.v ] ) < tie( block_id[ y.u ], dfn[ y.v ] );
} );
// apply mo's algorithm on tree
int U = 1, V = 1;
for ( int i = 0 ; i < q ; ++ i ) {
pass( U, que[ i ].u );
pass( V, que[ i ].v );
// we could our answer of que[ i ].id
}
}
This problem is a slight modification of the blog that you have shared.
Problem Tags:- MO's Algorithm, Trees, LCA, Binary Lifting, Sieve, Precomputation, Prime Factors
Precomputations:- Just we need to do some precomputations with seiveOfErothenesis to store the highest prime factor of each element possible in input constraints. Then using this we will store all the prime factors and their powers for each element in input array in another matrix.
Observation:- with the constraints you can see the there can be very few such primes possible for each element. For an element (10^6) there can be a maximum of 7 prime factors possible.
Modify MO Algo Given in blog:- Now in our compute method we just need to maintain a map that will store the current count of the prime factor. While adding or subtracting each element in solving the queries we will iterate on the prime factors of that element and divide our result(storing total no. of factors) with the old count of that prime and then update the count of that prime and the multiple our result with the new count.(This will be O(7) max for each addition/subtraction).
Complexity:- O(T * ((N + Q) * sqrt(N) * F)) where F is 7 in our case. F is the complexity of your check method().
T - no of test cases in input file.
N - the size of your input array.
Q - No. of queries.
Below is an implementation of the above approach in JAVA. computePrimePowers() and check() are the methods you would be interested in.
import java.util.*;
import java.io.*;
public class Main {
static int BLOCK_SIZE;
static int ar[];
static ArrayList<Integer> graph[];
static StringBuffer sb = new StringBuffer();
static boolean notPrime[] = new boolean[1000001];
static int hpf[] = new int[1000001];
static void seive(){
notPrime[0] = true;
notPrime[1] = true;
for(int i = 2; i < 1000001; i++){
if(!notPrime[i]){
hpf[i] = i;
for(int j = 2 * i; j < 1000001; j += i){
notPrime[j] = true;
hpf[j] = i;
}
}
}
}
static long modI[] = new long[1000001];
static void computeModI() {
for(int i = 1; i < 1000001; i++) {
modI[i] = pow(i, 1000000005);
}
}
static long pow(long x, long y) {
if (y == 0)
return 1;
long p = pow(x, y / 2);
p = (p >= 1000000007) ? p % 1000000007 : p;
p = p * p;
p = (p >= 1000000007) ? p % 1000000007 : p;
if ((y & 1) == 0)
return p;
else {
long tt = x * p;
return (tt >= 1000000007) ? tt % 1000000007 : tt;
}
}
public static void main(String[] args) throws Exception {
Reader s = new Reader();
int test = s.nextInt();
seive();
computeModI();
for(int ii = 0; ii < test; ii++){
int n = s.nextInt();
lcaTable = new int[19][n + 1];
graph = new ArrayList[n + 1];
arrPrimes = new int[n + 1][7][2];
primeCnt = new int[1000001];
visited = new int[n + 1];
ar = new int[n + 1];
for(int i = 0; i < graph.length; i++) graph[i] = new ArrayList<>();
for(int i = 1; i < n; i++){
int u = s.nextInt(), v = s.nextInt();
graph[u].add(v);
graph[v].add(u);
}
int ip = 1; while(ip <= n) ar[ip++] = s.nextInt();
computePrimePowers();
int q = s.nextInt();
LVL = new int[n + 1];
dfsTime = 0;
dfs(1, -1);
BLOCK_SIZE = (int) Math.sqrt(dfsTime);
int Q[][] = new int[q][4];
int i = 0;
while(q-- > 0) {
int u = s.nextInt(), v = s.nextInt();
Q[i][0] = lca(u, v);
if (l[u] > l[v]) {
int temp = u; u = v; v = temp;
}
if (Q[i][0] == u) {
Q[i][1] = l[u];
Q[i][2] = l[v];
}
else {
Q[i][1] = r[u]; // left at col1 in query
Q[i][2] = l[v]; // right at col2
}
Q[i][3] = i;
i++;
}
Arrays.sort(Q, new Comparator<int[]>() {
#Override
public int compare(int[] x, int[] y) {
int block_x = (x[1] - 1) / (BLOCK_SIZE + 1);
int block_y = (y[1] - 1) / (BLOCK_SIZE + 1);
if(block_x != block_y)
return block_x - block_y;
return x[2] - y[2];
}
});
solveQueries(Q);
}
System.out.println(sb);
}
static long res;
private static void solveQueries(int [][] Q) {
int M = Q.length;
long results[] = new long[M];
res = 1;
int curL = Q[0][1], curR = Q[0][1] - 1;
int i = 0;
while(i < M){
while (curL < Q[i][1]) check(ID[curL++]);
while (curL > Q[i][1]) check(ID[--curL]);
while (curR < Q[i][2]) check(ID[++curR]);
while (curR > Q[i][2]) check(ID[curR--]);
int u = ID[curL], v = ID[curR];
if (Q[i][0] != u && Q[i][0] != v) check(Q[i][0]);
results[Q[i][3]] = res;
if (Q[i][0] != u && Q[i][0] != v) check(Q[i][0]);
i++;
}
i = 0;
while(i < M) sb.append(results[i++] + "\n");
}
static int visited[];
static int primeCnt[];
private static void check(int x) {
if(visited[x] == 1){
for(int i = 0; i < 7; i++) {
int c = arrPrimes[x][i][1];
int pp = arrPrimes[x][i][0];
if(pp == 0) break;
long tem = res * modI[primeCnt[pp] + 1];
res = (tem >= 1000000007) ? tem % 1000000007 : tem;
primeCnt[pp] -= c;
tem = res * (primeCnt[pp] + 1);
res = (tem >= 1000000007) ? tem % 1000000007 : tem;
}
}
else if(visited[x] == 0){
for(int i = 0; i < 7; i++) {
int c = arrPrimes[x][i][1];
int pp = arrPrimes[x][i][0];
if(pp == 0) break;
long tem = res * modI[primeCnt[pp] + 1];
res = (tem >= 1000000007) ? tem % 1000000007 : tem;
primeCnt[pp] += c;
tem = res * (primeCnt[pp] + 1);
res = (tem >= 1000000007) ? tem % 1000000007 : tem;
}
}
visited[x] ^= 1;
}
static int arrPrimes[][][];
static void computePrimePowers() {
int n = arrPrimes.length;
int i = 0;
while(i < n) {
int ele = ar[i];
int k = 0;
while(ele > 1) {
int c = 0;
int pp = hpf[ele];
while(hpf[ele] == pp) {
c++; ele /= pp;
}
arrPrimes[i][k][0] = pp;
arrPrimes[i][k][1] = c;
k++;
}
i++;
}
}
static int dfsTime;
static int l[] = new int[1000001], r[] = new int[1000001], ID[] = new int[1000001], LVL[], lcaTable[][];
static void dfs(int u, int p){
l[u] = ++dfsTime;
ID[dfsTime] = u;
int i = 1;
while(i < 19) {
lcaTable[i][u] = lcaTable[i - 1][lcaTable[i - 1][u]];
i++;
}
i = 0;
while(i < graph[u].size()){
int v = graph[u].get(i);
i++;
if (v == p) continue;
LVL[v] = LVL[u] + 1;
lcaTable[0][v] = u;
dfs(v, u);
}
r[u] = ++dfsTime;
ID[dfsTime] = u;
}
static int lca(int u, int v){
if (LVL[u] > LVL[v]) {
int temp = u;
u = v; v = temp;
}
int i = 18;
while(i >= 0) {
if (LVL[v] - (1 << i) >= LVL[u]) v = lcaTable[i][v];
i--;
}
if (u == v) return u;
i = 18;
while(i >= 0){
if (lcaTable[i][u] != lcaTable[i][v]){
u = lcaTable[i][u];
v = lcaTable[i][v];
}
i--;
}
return lcaTable[0][u];
}
}
// SIMILAR SOLUTION FOR FINDING NUMBER OF DISTINCT ELEMENTS FROM U TO V
// USING MO's ALGORITHM
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 40005;
const int MAXM = 100005;
const int LN = 19;
int N, M, K, cur, A[MAXN], LVL[MAXN], DP[LN][MAXN];
int BL[MAXN << 1], ID[MAXN << 1], VAL[MAXN], ANS[MAXM];
int d[MAXN], l[MAXN], r[MAXN];
bool VIS[MAXN];
vector < int > adjList[MAXN];
struct query{
int id, l, r, lc;
bool operator < (const query& rhs){
return (BL[l] == BL[rhs.l]) ? (r < rhs.r) : (BL[l] < BL[rhs.l]);
}
}Q[MAXM];
// Set up Stuff
void dfs(int u, int par){
l[u] = ++cur;
ID[cur] = u;
for (int i = 1; i < LN; i++) DP[i][u] = DP[i - 1][DP[i - 1][u]];
for (int i = 0; i < adjList[u].size(); i++){
int v = adjList[u][i];
if (v == par) continue;
LVL[v] = LVL[u] + 1;
DP[0][v] = u;
dfs(v, u);
}
r[u] = ++cur; ID[cur] = u;
}
// Function returns lca of (u) and (v)
inline int lca(int u, int v){
if (LVL[u] > LVL[v]) swap(u, v);
for (int i = LN - 1; i >= 0; i--)
if (LVL[v] - (1 << i) >= LVL[u]) v = DP[i][v];
if (u == v) return u;
for (int i = LN - 1; i >= 0; i--){
if (DP[i][u] != DP[i][v]){
u = DP[i][u];
v = DP[i][v];
}
}
return DP[0][u];
}
inline void check(int x, int& res){
// If (x) occurs twice, then don't consider it's value
if ( (VIS[x]) and (--VAL[A[x]] == 0) ) res--;
else if ( (!VIS[x]) and (VAL[A[x]]++ == 0) ) res++;
VIS[x] ^= 1;
}
void compute(){
// Perform standard Mo's Algorithm
int curL = Q[0].l, curR = Q[0].l - 1, res = 0;
for (int i = 0; i < M; i++){
while (curL < Q[i].l) check(ID[curL++], res);
while (curL > Q[i].l) check(ID[--curL], res);
while (curR < Q[i].r) check(ID[++curR], res);
while (curR > Q[i].r) check(ID[curR--], res);
int u = ID[curL], v = ID[curR];
// Case 2
if (Q[i].lc != u and Q[i].lc != v) check(Q[i].lc, res);
ANS[Q[i].id] = res;
if (Q[i].lc != u and Q[i].lc != v) check(Q[i].lc, res);
}
for (int i = 0; i < M; i++) printf("%d\n", ANS[i]);
}
int main(){
int u, v, x;
while (scanf("%d %d", &N, &M) != EOF){
// Cleanup
cur = 0;
memset(VIS, 0, sizeof(VIS));
memset(VAL, 0, sizeof(VAL));
for (int i = 1; i <= N; i++) adjList[i].clear();
// Inputting Values
for (int i = 1; i <= N; i++) scanf("%d", &A[i]);
memcpy(d + 1, A + 1, sizeof(int) * N);
// Compressing Coordinates
sort(d + 1, d + N + 1);
K = unique(d + 1, d + N + 1) - d - 1;
for (int i = 1; i <= N; i++) A[i] = lower_bound(d + 1, d + K + 1, A[i]) - d;
// Inputting Tree
for (int i = 1; i < N; i++){
scanf("%d %d", &u, &v);
adjList[u].push_back(v);
adjList[v].push_back(u);
}
// Preprocess
DP[0][1] = 1;
dfs(1, -1);
int size = sqrt(cur);
for (int i = 1; i <= cur; i++) BL[i] = (i - 1) / size + 1;
for (int i = 0; i < M; i++){
scanf("%d %d", &u, &v);
Q[i].lc = lca(u, v);
if (l[u] > l[v]) swap(u, v);
if (Q[i].lc == u) Q[i].l = l[u], Q[i].r = l[v];
else Q[i].l = r[u], Q[i].r = l[v];
Q[i].id = i;
}
sort(Q, Q + M);
compute();
}
}
Demo

visual studio access violation reading location 0xc0000005

I am receiving data in TCP in C++ using Qt library. I store the received packet in a QByteArray, but after reading the whole data, I face this error in debug. At the end, I try to clear the buffer, but I face this problem while trying to clear it too.
Here is my code :
void AvaNPortTester::scoket_readyRead()
{
ui.lineEdit_Sending_Status_->setText("Sent");
ui.lineEdit_Sending_Status_->setStyleSheet("QLineEdit { background: rgb(50, 255, 50); }");
tcpSocket_data_buffer_.append(tcpSocket_->readAll());
//qDebug() << serialport_data_buffer_.size();
//auto ddd = QString::number(tcpSocket_data_buffer_.size());// +" : " + tcpSocket_data_buffer_.toHex();
//ui.lableSocketRead->setText(ddd);
bool read_aain = false;
QByteArray dummy(int(1446), Qt::Initialization::Uninitialized);
int reminded_data = 0;
int dummy_size = 0;
int frame_size = 0;
int l_size = 0;
int total_size_rcvd = tcpSocket_data_buffer_.size();
//int total_size_rcvd_b = total_size_rcvd_b;
int temp = 0;
while (total_size_rcvd != 0)
{
if(total_size_rcvd != 0){
auto packet = tcpSocket_data_buffer_.mid(0, 1446);
auto rem = tcpSocket_data_buffer_.mid(1446);//****1146
tcpSocket_data_buffer_ = rem;
QDataStream streamdata(packet);
uint8_t Sync_Header[3];
auto ss = streamdata.readRawData((char*)&Sync_Header, 3);
uint8_t Total_size[2];
ss = streamdata.readRawData((char*)&Total_size, 2);
int t_size = Total_size[0] * 256 + Total_size[1];
uint8_t Reserved[2];
ss = streamdata.readRawData((char*)&Reserved, 2);
frame_size = t_size - 2;
reminded_data = t_size - 2;
while (frame_size != 0)
{
uint8_t portid;
ss = streamdata.readRawData((char*)&portid, 1);
//ui.lineEdit_FileSize->setText(QString::number(fileSend_2Ser->size()));
uint8_t ProtocolID;
ss = streamdata.readRawData((char*)&ProtocolID, 1);
uint8_t MoreFragmentFlag;
ss = streamdata.readRawData((char*)&MoreFragmentFlag, 1);
uint8_t Seq;
ss = streamdata.readRawData((char*)&Seq, 1);
uint8_t size[2];
ss = streamdata.readRawData((char*)&size, 2);
l_size = size[0] * 256 + size[1];
if (packet_flags.Ser2Eth.packet_started[portid] == false) {
uint8_t DDCMP_Header[14];
ss = streamdata.readRawData((char*)&DDCMP_Header, 14);
packet_flags.Ser2Eth.protocol_payload_size[portid] = DDCMP_Header[7] + 256 * DDCMP_Header[8];
temp = packet_flags.Ser2Eth.protocol_payload_size[portid];
packet_flags.Ser2Eth.packet_started[portid] = true;
}
QByteArray ddcmp_datap(int(l_size), Qt::Initialization::Uninitialized);
streamdata.readRawData(ddcmp_datap.data(), l_size - 14);
if ((pre_more_frag == 0) && (MoreFragmentFlag == 0)) {
packet_flags.Ser2Eth.packet_ended[portid] = true;
packet_flags.Ser2Eth.protocol_payload_size[portid] = l_size;
temp = packet_flags.Ser2Eth.protocol_payload_size[portid];
}
else if ((pre_more_frag == 0) && (MoreFragmentFlag == 1)) {
packet_flags.Ser2Eth.packet_ended[portid] = false;
packet_flags.Ser2Eth.protocol_payload_size[portid] = l_size + 16;
temp = packet_flags.Ser2Eth.protocol_payload_size[portid];
}
else if ((pre_more_frag == 1) && (MoreFragmentFlag == 1)) {
packet_flags.Ser2Eth.packet_ended[portid] = false;
packet_flags.Ser2Eth.protocol_payload_size[portid] = packet_flags.Ser2Eth.protocol_payload_size[portid] + l_size;
temp = packet_flags.Ser2Eth.protocol_payload_size[portid];
}
else if ((pre_more_frag == 1) && (MoreFragmentFlag == 0)) {
packet_flags.Ser2Eth.packet_ended[portid] = true;
packet_flags.Ser2Eth.protocol_payload_size[portid] = packet_flags.Ser2Eth.protocol_payload_size[portid] + l_size;
temp = packet_flags.Ser2Eth.protocol_payload_size[portid];
}
if (MoreFragmentFlag == 1) {
pre_more_frag = 1;
}
else {
pre_more_frag = 0;
}
int ff = 0;
if (packet_flags.Ser2Eth.packet_ended[portid] == true) {
packet_flags.Ser2Eth.packet_started[portid] = false;
packet_flags.Ser2Eth.packet_started[portid] = false;
set_port_id_flag(portid, packet_flags.Ser2Eth.protocol_payload_size[portid], ProtocolID);
pre_more_frag = 0;
}
reminded_data = reminded_data - 6 - l_size;
//ui.lableSocketRead->setText(ddcmp_datap.toHex());
frame_size = frame_size - l_size - 6;
}//end of while (frame_size != 0)
uint8_t sync_footer[3];
streamdata.readRawData((char *)&sync_footer, 3);
dummy_size = 1446 - t_size - 8;
uint8_t dummy_data[1000];
streamdata.readRawData((char *)&dummy_data, dummy_size);
total_size_rcvd = total_size_rcvd - 1446;
if (total_size_rcvd == 0) {
tcpSocket_data_buffer_.clear();
}
} //end of if
}//end of while()
}

Why I'm getting different results from GNU g++ and VC++

I'm trying to solve this problem in C++:
"Given a sequence S of integers, find a number of increasing sequences I such that every two consecutive elements in I appear in S, but on the opposite sides of the first element of I."
This is the code I've developed:
#include<iostream>
#include<set>
#include<vector>
using namespace std;
struct Element {
long long height;
long long acc;
long long con;
};
bool fncomp(Element* lhs, Element* rhs) {
return lhs->height < rhs->height;
}
int solution(vector<int> &H) {
// set up
int N = (int)H.size();
if (N == 0 || N == 1) return N;
long long sol = 0;
// build trees
bool(*fn_pt)(Element*, Element*) = fncomp;
set<Element*, bool(*)(Element*, Element*)> rightTree(fn_pt), leftTree(fn_pt);
set<Element*, bool(*)(Element*, Element*)>::iterator ri, li;
for (int i = 0; i < N; i++) {
Element* e = new Element;
e->acc = 0;
e->con = 0;
e->height = H[i];
rightTree.insert(e);
}
//tree elements set up
ri = --rightTree.end();
Element* elem = *ri;
elem->con = 1;
elem->acc = 1;
while (elem->height > H[0]) {
Element* succ = elem;
ri--;
elem = *ri;
elem->con = 1;
elem->acc = succ->acc + 1;
}
rightTree.erase(ri);
elem->con = elem->acc;
leftTree.insert(elem);
sol += elem->acc;
// main loop
Element* pE = new Element;
for (int j = 1; j < (N - 1); j++) {
// bad case
if (H[j] < H[j - 1]) {
///////
Element* nE = new Element;
nE->height = H[j];
pE->height = H[j - 1];
rightTree.erase(nE);
leftTree.insert(nE);
///////
li = leftTree.lower_bound(pE);
long ltAcc = (*li)->acc;
li--;
///////
ri = rightTree.lower_bound(pE);
long rtAcc = 0;
if (ri != rightTree.end()) rtAcc = (*ri)->acc;
ri--;
///////
while (ri != (--rightTree.begin()) && (*ri)->height > H[j]) {
if (fncomp(*ri, *li)) {
(*li)->con = rtAcc + 1;
(*li)->acc = rtAcc + 1 + ltAcc;
ltAcc = (*li)->acc;
--li;
}
else {
(*ri)->con = ltAcc + 1;
(*ri)->acc = ltAcc + 1 + rtAcc;
rtAcc = (*ri)->acc;
--ri;
}
}
while ((*li)->height > H[j]) {
(*li)->con = rtAcc + 1;
(*li)->acc = rtAcc + 1 + ltAcc;
ltAcc = (*li)->acc;
--li;
}
(*li)->con = rtAcc + 1;
(*li)->acc = rtAcc + 1 + ltAcc;
sol += (*li)->acc;
}
// good case
else {
Element* nE = new Element;
nE->height = H[j];
ri = rightTree.upper_bound(nE);
li = leftTree.upper_bound(nE);
rightTree.erase(nE);
if (li == leftTree.end() && ri == rightTree.end()) {
nE->con = 1;
nE->acc = 1;
}
else if (li != leftTree.end() && ri == rightTree.end()) {
nE->con = 1;
nE->acc = 1 + (*li)->acc;
}
else if (li == leftTree.end() && ri != rightTree.end()) {
nE->con = (*ri)->acc + 1;
nE->acc = nE->con;
}
else {
nE->con = (*ri)->acc + 1;
nE->acc = nE->con + (*li)->acc;
}
leftTree.insert(nE);
sol += nE->acc;
}
}
// final step
li = leftTree.upper_bound(*rightTree.begin());
while (li != leftTree.end()) {
sol++;
li++;
}
sol++;
return (int)(sol % 1000000007);
}
int main(int argc, char* argv[]) {
vector<int> H = { 13, 2, 5 };
cout << "sol: " << solution(H) << endl;
system("pause");
}
The main function calls solution(vector<int> H). The point is, when the argument has the particular value of H = {13, 2, 5} the VC++ compiled program give an output value of 7 (which is the correct one), but the GNU g++ compiled program give an output value of 5 (also clang compiled program behave like this).
I'm using this website, among others, for testing different compilers
http://rextester.com/l/cpp_online_compiler_gcc
I've tried to figure out the reason for this wierd behaviour but didn't found any relevant info. Only one post treat a similar problem:
Different results VS C++ and GNU g++
and that's why I'm using long long types in the code, but the problem persists.
The problem was decrementing the start-of-sequence --rightTree.begin()
As I found VC++ and GNU g++ does not behave the same way on above operation. Here is the code that shows the difference, adapted from http://www.cplusplus.com/forum/general/84609/:
#include<iostream>
#include<set>
using namespace std;
struct Element {
long long height;
long long acc;
long long con;
};
bool fncomp(Element* lhs, Element* rhs) {
return lhs->height < rhs->height;
}
int main(){
bool(*fn_pt)(Element*, Element*) = fncomp;
set<Element*, bool(*)(Element*, Element*)> rightTree(fn_pt);
set<Element*, bool(*)(Element*, Element*)>::iterator ri;
ri = rightTree.begin();
--ri;
++ri;
if(ri == rightTree.begin()) cout << "it works!" << endl;
}

Image processing error

I must implement in C++ using diblok The Seeded Region Growing algorithm due to Adams and Bischof which can be found here http://bit.ly/1nIxphj.
It is the fig.2 pseudocode.
After I choose the seeded points using the mouse , it throws this message : Unhandled exception at 0x00416ca0 in diblook.exe: 0xC0000005: Access violation reading location 0x3d2f6e68.
This is the code of the function:
void CDibView::OnLButtonDblClk(UINT nFlags, CPoint point)
{ BEGIN_SOURCE_PROCESSING;
int** labels = new int* [dwHeight];
for(int k = 0;k < dwHeight; k++)
labels[k] = new int[dwWidth];
int noOfRegions = 2;
double meanRegion[2];
double noOfPointsInRegion[2];
for(int i = 0; i < dwHeight ; i++)
for(int j = 0; j < dwWidth ; j++)
{
labels[i][j] = -1;
}
if(noOfPoints < 6)
{
CPoint p = GetScrollPosition() + point;
pos[noOfPoints].x = p.x;
pos[noOfPoints].y = p.y;
int regionLabel = 0;
if(noOfPoints <= noOfPoints / 2)
labels[p.x][p.y] = regionLabel;
else
labels[p.x][p.y] = regionLabel + 1;
noOfPoints++;
}
else
{
// Calculate the mean of each region
for(int i = 0; i < noOfRegions; i++)
{
for(int j = 0 ; j < noOfPoints; j++)
{
if(labels[pos[j].x][pos[j].y] == i)
{
meanRegion[i] += lpSrc[pos[j].x * w + pos[j].y];
}
}
meanRegion[i] /= 3;
noOfPointsInRegion[i] = 3;
}
for(int seedPoint = 0; seedPoint < noOfPoints; seedPoint++)
{
// define list
node *start, *temp;
start = (node *) malloc (sizeof(node));
temp = start;
temp -> next = NULL;
for(int i = -1; i <= 1; i++)
for(int j = -1; j<= 1; j++)
{
if(i == 0 && j == 0) continue;
int gamma = lpSrc[(pos[seedPoint].x + i) * + pos[seedPoint].y + j] - lpSrc[pos[seedPoint].x * w + pos[seedPoint].y];
push(start, pos[seedPoint].x + i, pos[seedPoint].y + j, gamma);
}
sort(start);
if(start != NULL)
{
node *y = start;
pop(start);
int sameNeighbour = 1;
int neighValue = -1;
for(int k = -1; k <= 1; k++)
for(int l = -1; l <= 1;l++)
{
if(k ==0 && l==0) continue;
if(labels[y -> x + k][y -> y + l] != -1)
{
neighValue = labels[y -> x + k][y -> y + l];
break;
}
}
for(int k = -1; k <= 1; k++)
for(int l = -1; l <= 1;l++)
{
if(k == 0 && l==0) continue;
if(labels[y -> x + k][y -> y = 1] != -1 && labels[y -> x + k][y -> y + l] != neighValue)
sameNeighbour = 0;
}
if(sameNeighbour == 1)
{
labels[y -> x][y -> y] = neighValue;
meanRegion[neighValue] = meanRegion[neighValue] * noOfPointsInRegion[neighValue] / noOfPointsInRegion[neighValue] + 1;
noOfPointsInRegion[neighValue]++;
for(int k = -1; k <= 1; k++)
for(int l = -1; l <= 1;l++)
{
if(k == 0 && l == 0) continue;
if(labels[y -> x + k][y -> y + l] == -1 && find(start, y->x + k, y->y + l) == 0)
{
int gammak = meanRegion[neighValue] - lpSrc[(y->x +k) * w + (y->y + l)];
push(start, y->x + k, y->y + l, gammak);
sort(start);
}
}
}
else
{
labels[y->x][y->y] = -1;
}
}
}
int noOfRegionOne = 0;
int noOfRegionTwo = 0;
int noOfBoundary = 0;
for(int i = 0; i< dwHeight; i++)
for(int j = 0;j<dwWidth; j++)
{
if(labels[i][j] == -1)
noOfBoundary++;
else if(labels[i][j] == 0)
noOfRegionOne++;
else if(labels[i][j] == 1)
noOfRegionTwo++;
}
CString info;
info.Format("Boundary %d, One %d, Two %d", noOfBoundary, noOfRegionOne, noOfRegionTwo);
AfxMessageBox(info);
noOfPoints = 0;
}
CScrollView::OnLButtonDblClk(nFlags, point);
END_SOURCE_PROCESSING;
}
After a choose to break the running, this is what is shown http://postimg.org/image/j2sh9k0a1/
Can anybody tell what is wrong and why it doesn't work?
Thanks.
Your screenshot shows that your node (Y is a terrible name, incidentally) has garbage values in it. Offhand, I suspect that 'sort' is overwriting your node values, resulting in garbage. I would create a static copy of your current node to prevent it from changing during processing:
Change
node *y = start;
pop(start);
to
node y = *start;
pop(start);