Related
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.
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());
}
In order to become more familiar with cpp I began making a program that takes the derivative of simple polynomials using the power rule. So far, it is working fine for polynomials such as 5x^2+4x. However, if the polynomial contains a constant (like 5x + 3) I get a string subscript out of range error. I used the debugger and found the error triggers on line 33 (std::string term = differentiateTerm(*iter);). I'm not exactly sure what I'm doing wrong here and I would appreciate any help.
Full code:
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> terms;
std::vector<std::string>::const_iterator iter;
std::string takeDerivative(std::string expression);
void separateTerms(std::string expression);
std::string differentiateTerm(std::string inputTerm);
int main()
{
std::string userExpression;
std::cout << "Enter a polynomial.\n";
std::cin >> userExpression;
std::string outputExpression = takeDerivative(userExpression);
std::cout << "The derivative of your expression is: " + outputExpression;
return 0;
}
std::string takeDerivative(std::string expression)
{
std::string derivative;
separateTerms(expression);
for (iter = terms.begin(); iter != terms.end(); iter++)
{
std::string term = differentiateTerm(*iter);
if (iter - terms.begin() == 0)
{
derivative = term;
}
else
{
derivative += "+" + term;
}
}
return derivative;
}
void separateTerms(std::string expression)
{
int previousSign = 0;
bool firstTerm = true;
for (int i = 0; i < expression.size() + 1; i++)
{
if (expression[i] == '+' || expression[i] == '-')
{
if (firstTerm)
{
terms.push_back(expression.substr(0, i));
firstTerm = false;
previousSign = i;
}
else
{
terms.push_back(expression.substr(previousSign + 1, i - previousSign - 1));
previousSign = i;
}
}
else if (i == expression.size())
{
if (firstTerm)
{
terms.push_back(expression.substr(previousSign, i));
}
else
{
terms.push_back(expression.substr(previousSign + 1, i - previousSign));
}
}
}
}
std::string differentiateTerm(std::string inputTerm)
{
std::string outputTerm;
int coefficient = 1;
int exponent = 1;
int varPos = inputTerm.find('x');
if (inputTerm[varPos] == std::string::npos)
{
outputTerm = "0";
return outputTerm;
}
else {
if (inputTerm[varPos - 1] != std::string::npos)
{
coefficient = std::stoi(inputTerm.substr(0, varPos));
}
if (inputTerm[varPos + 1] == '^')
{
if (inputTerm[varPos + 2] != std::string::npos)
{
exponent = std::stoi(std::string(1, inputTerm[varPos + 2]));
}
}
}
coefficient = coefficient * exponent;
exponent--;
if (exponent <= 0)
{
outputTerm = std::to_string(coefficient);
}
else if (exponent == 1)
{
outputTerm = std::to_string(coefficient) + "x";
}
else
{
outputTerm = std::to_string(coefficient) + "x^" + std::to_string(exponent);
}
return outputTerm;
}
You're not checking the return value from find correctly in differentiateTerm. This causes inputTerm[varPos] to access out of bounds.
The correct check is
if (varPos == std::string::npos)
In the subsequent if statements, since you have a valid subscript in varPos, you should check that against the size of the string. So you'd have if (varPos > 0), if (varPos < inputTerm.size() - 1), etc.
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()
}
i've been working on word search algorithm for quite long I think i made it good and decided to test limits. I've created program which makes file as big as I want to. So i made a matrix 10000 * 10000 (10000000 letters) and really long word from top left corner to bottom right corner. Thing is that it works with 4000 * 4000 matrix but then it gets bigger it just crashes. I tried to comment all other checkings for possible location and left the right one and it works perfectly even with 10000 * 10000 matrix but as soon as I add other checks it stops and I have no idea why. Any suggestions?
My code:
#include <iostream> //Might Be:
#include <string> // <----->
#include <fstream> // /-\ (1)/\ /\(3)
#include <new> // | \ /
#include <cstdlib> // | \ /
// | \ /
// | \ /
// | \ /
// \_/ (2)\/ \/(4)
//
using namespace std;
//Loop[4] //Loop[5]
int * Possibles(int Widht, int Height, int Poz, int Poz1, int Leng, int * Possible)
{
if(Poz1 < Widht - Leng + 1) // To right
{
Possible[0] = 1;
}
if(Poz1 >= Leng - 1) // To left
{
Possible[1] = 1;
}
if(Poz <= Height - Leng) // From top to bottom
{
Possible[2] = 1;
}
if(Poz >= Leng) // From bottom to top
{
Possible[3] = 1;
}
if(Poz + Leng <= Height && Poz1 + Leng <= Widht) //(2)
{
Possible[4] = 1;
}
if(Poz + Leng <= Height && Poz1 - Leng + 1 >= 0) //(4)
{
Possible[5] = 1;
}
if(Poz - Leng + 1 >= 0 && Poz1 - Leng + 1 >= 0) //(1)
{
Possible[6] = 1;
}
if(Poz - Leng + 1 >= 0 && Poz1 + Leng <= Widht) //(3)
{
Possible[7] = 1;
}
return Possible;
}
int * Zero(int * Possible)
{
Possible[0] = 0;
Possible[1] = 0;
Possible[2] = 0;
Possible[3] = 0;
Possible[4] = 0;
Possible[5] = 0;
Possible[6] = 0;
Possible[7] = 0;
return Possible;
}
string Next(string * NewMatrix, int Height, int Widht)
{
return NewMatrix[Height].substr(Widht, 1);
}
bool Find(string Word, int Poz, int Poz1, int Look, string Have, string * Matrix, int * Possible, int Backup, int Backup1)
{
if(Have == Word)
{
return true;
return Possible;
}
string NewLet = Word.substr(Look, 1);
if(Possible[0] == 1)
{
if(NewLet == Next(Matrix, Poz, Poz1 + 1))
{
Have += NewLet;
return Find(Word, Poz, Poz1 + 1, Look + 1, Have, Matrix, Possible, Backup, Backup1);
}
else
{
Possible[0] = 0;
Have = Word.substr(0, 1);
return Find(Word, Backup, Backup1, 1, Have, Matrix, Possible, Backup, Backup1);
}
}
if(Possible[1] == 1)
{
if(NewLet == Next(Matrix, Poz, Poz1 - 1))
{
Have += NewLet;
return Find(Word, Poz, Poz1 - 1, Look + 1, Have, Matrix, Possible, Backup, Backup1);
}
else
{
Possible[1] = 0;
Have = Word.substr(0, 1);
return Find(Word, Backup, Backup1, 1, Have, Matrix, Possible, Backup, Backup1);
}
}
if(Possible[2] == 1)
{
if(NewLet == Next(Matrix, Poz + 1, Poz1))
{
Have += NewLet;
return Find(Word, Poz + 1, Poz1, Look + 1, Have, Matrix, Possible, Backup, Backup1);
}
else
{
Possible[2] = 0;
Have = Word.substr(0, 1);
return Find(Word, Backup, Backup1, 1, Have, Matrix, Possible, Backup, Backup1);
}
}
if(Possible[3] == 1)
{
if(NewLet == Next(Matrix, Poz - 1, Poz1))
{
Have += NewLet;
return Find(Word, Poz - 1, Poz1, Look + 1, Have, Matrix, Possible, Backup, Backup1);
}
else
{
Possible[3] = 0;
Have = Word.substr(0, 1);
return Find(Word, Backup, Backup1, 1, Have, Matrix, Possible, Backup, Backup1);
}
}
if(Possible[4] == 1)
{
if(NewLet == Next(Matrix, Poz + 1, Poz1 + 1))
{
Have += NewLet;
return Find(Word, Poz + 1, Poz1 + 1, Look + 1, Have, Matrix, Possible, Backup, Backup1);
}
else
{
Possible[4] = 0;
Have = Word.substr(0, 1);
return Find(Word, Backup, Backup1, 1, Have, Matrix, Possible, Backup, Backup1);
}
}
if(Possible[5] == 1)
{
if(NewLet == Next(Matrix, Poz + 1, Poz1 - 1))
{
Have += NewLet;
return Find(Word, Poz + 1, Poz1 - 1, Look + 1, Have, Matrix, Possible, Backup, Backup1);
}
else
{
Possible[5] = 0;
Have = Word.substr(0, 1);
return Find(Word, Backup, Backup1, 1, Have, Matrix, Possible, Backup, Backup1);
}
}
if(Possible[6] == 1)
{
if(NewLet == Next(Matrix, Poz - 1, Poz1 - 1))
{
Have += NewLet;
return Find(Word, Poz - 1, Poz1 - 1, Look + 1, Have, Matrix, Possible, Backup, Backup1);
}
else
{
Possible[6] = 0;
Have = Word.substr(0, 1);
return Find(Word, Backup, Backup1, 1, Have, Matrix, Possible, Backup, Backup1);
}
}
if(Possible[7] == 1)
{
if(NewLet == Next(Matrix, Poz - 1, Poz1 + 1))
{
Have += NewLet;
return Find(Word, Poz - 1, Poz1 + 1, Look + 1, Have, Matrix, Possible, Backup, Backup1);
}
else
{
Possible[7] = 0;
Have = Word.substr(0, 1);
return Find(Word, Backup, Backup1, 1, Have, Matrix, Possible, Backup, Backup1);
}
}
return false;
}
string Diro(int * Possible)
{
string Dir;
bool Next = true;
if(Possible[0] == 1 && Next == true)
{
Dir = " From right to left";
Next = false;
}
if(Possible[1] == 1 && Next == true)
{
Dir = " From left to right";
Next = false;
}
if(Possible[2] == 1 && Next == true)
{
Dir = " From top to bottom";
Next = false;
}
if(Possible[3] == 1 && Next == true)
{
Dir = " From bottom to top";
Next = false;
}
if(Possible[4] == 1 && Next == true)
{
Dir = " ";
Next = false;
}
if(Possible[5] == 1 && Next == true)
{
Dir = " ";
Next = false;
}
if(Possible[6] == 1 && Next == true)
{
Dir = " ";
Next = false;
}
if(Possible[7] == 1 && Next == true)
{
Dir = " ";
Next = false;
}
return Dir;
}
int main()
{
int Height = 0, Widht = 0, Numb = 0;
int Loop[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
int * Possible = new int[8];
string Dir, Search, Tempo, Temp;
ifstream Data("C:/Users/Magician/AppData/Local/VirtualStore/Program Files (x86)/CodeBlocks/MakeMaze/Files/Maze.txt");
Data >> Widht >> Height;
string * NewMatrix = new string[Height];
while(Loop[7] < Height)
{
Tempo = "";
Loop[8] = 0;
while(Loop[8] < Widht)
{
Data >> Temp;
Tempo += Temp;
Loop[8]++;
}
NewMatrix[Loop[7]] = Tempo;
Loop[7]++;
}
Data >> Numb;
string * Words = new string[Numb];
while(Loop[2] < Numb)
{
Data >> Words[Loop[2]];
Loop[2]++;
}
Data.close();
while(Loop[3] < Numb)
{
Search = Words[Loop[3]].substr(0, 1);
Loop[4] = 0;
while(Loop[4] < Height)
{
Loop[5] = 0;
while(Loop[5] < Widht)
{
if(NewMatrix[Loop[4]].substr(Loop[5], 1) == Search)
{
Zero(Possible);
Possibles(Widht, Height, Loop[4], Loop[5], Words[Loop[3]].size(), Possible);
if(Find(Words[Loop[3]], Loop[4], Loop[5], 1, Search, NewMatrix, Possible, Loop[4], Loop[5]))
{
cout << Words[Loop[3]] << " At: " << Loop[4] + 1 << " collumn, symbol " << Loop[5] + 1 << " " << Diro(Possible) << endl;
Loop[5] = Widht;
Loop[4] = Height;
}
}
Loop[5]++;
}
Loop[4]++;
}
Loop[3]++;
}
delete [] Possible;
delete [] Words;
delete [] NewMatrix;
return 0;
}
If you didn't understood what I wrote before: when I comment every if(Possible[] == )
except for if(Possible[5] == 1) in function Find() algorithm works then all allowed it doesn't. I've tried with 100 * 100 matrix with a lot of words to find and everything's ok.
One condition in Possibles is incorrect:
/* INCORRECT: Should be [ Poz >= Leng - 1 ] */
if(Poz >= Leng) // From bottom to top
{
Possible[3] = 1;
}
But this one is only a logical error and should not cause segmentation faults.
It looks like you have encountered a stack overflow.
Let's do simple calculation. For 10000 * 10000 matrix and word length of 10000, if you start calling Find() at the top left of the matrix, then three directions are possible. In worst case, Find() will traverse about 10000*3 elements. Note in Func() there are 3 string instances (sizeof(string) == 24 in 32bit VC2013), plus various integers. The size of a single frame could easily exceed 100 bytes. Since you are using recursive calls, this could lead to a stack usage of at least 10000 * 3 * 100 = 3000000bytes = approx. 3M.
This number is not very large, but enough for a stack overflow since Windows has a default stack size of 1M. (http://msdn.microsoft.com/en-us/library/8cxs58a6.aspx)
Advice for improvements
This is my used pattern to solve this kinds of matrix traversal problems.
First, define an constant array to hold offsets for movements (Moore neighborhood):
const int delta[8][2] = {
{ 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 },
{ -1, 0 }, { -1, -1 }, { 0, -1 }, { 1, -1 }
};
Second, use a single for to check for all directions:
int initial_x = .., initial_y = ..;
for (int dir = 0; dir < 8; dir++) {
for (int count = 0; count < WORD_LENGTH; count++) {
int current_x = initial_x + delta[dir][0] * count;
int current_y = initial_y + delta[dir][1] * count;
if (IS_INVALID(current_x, current_y)) {
break;
}
}
}
Last, insert various code and flags to complete the program.
Another hint: you can use char type to get and compare a single character in a string (Use word[idx] to get idxth character of word). This could be substantially faster than using substr.