This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Compilation error using new API MEX and Eigen

Tags: None
(comma "," separated)
cdadon
Registered Member
Posts
1
Karma
0
Hello,
i am trying to use Eigen with MEX new CPP API of matlab.
when i compile the program without the MEX headers it compile perfectly fine.
but when i added the MEX header " #include "mexAdapter.hpp" " i get compile the compile errors:

eigen\src\core\plainobjectbase.h(903): error C2131: expression did not evaluate to a constant
eigen\src\core\plainobjectbase.h(903): note: failure was caused by call of undefined function or one not declared 'constexpr'
eigen\src\core\plainobjectbase.h(903): note: see usage of 'matlab::data::operator !='
eigen\src\core\plainobjectbase.h(902): note: while compiling class template member function 'void Eigen::PlainObjectBase<Eigen::Array<float,-1,1,0,-1,1>>::_check_template_params(void)'

eigen\src\core\array.h(134): note: see reference to function template instantiation 'void Eigen::PlainObjectBase<Eigen::Array<float,-1,1,0,-1,1>>::_check_template_params(void)' being compiled

eigen\src\core\array.h(47): note: see reference to class template instantiation 'Eigen::PlainObjectBase<Eigen::Array<float,-1,1,0,-1,1>>' being compiled
eigentest.h(74): note: see reference to class template instantiation 'Eigen::Array<float,-1,1,0,-1,1>' being compiled

i am using VS2017 with the latest Eigen Ver 3.6.6

it is not look like a code issue, and i assuming it related to "Using custom scalar types" topic since Eigen probably dont recognize MEX defs, but i have no idea how to fix it.

Code: Select all
#ifndef __EIGEN_TEST_H__
#define __EIGEN_TEST_H__

#include <Eigen/Dense>
#include <complex>

#include "AlgDefs.h"
#include "MatrixType.h"
#include <random>
#include <functional>
#include <numeric>

#define TWO_PI 2*M_PI

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
class EigenTest
{
public:
    struct CConfig
    {
        CU_UINT uiFrameSize = 112;
        CU_UINT uiRandSeed = 0;
        CU_UINT uiSourcesNumber = 1000;
        CU_FP fMeanIntensity = 0.25;
        CU_FP fMaxRadius = 0.5 * M_PI;
      CU_FP apertureShape = 1; // 1 = 'circular', 0 = 'square';
        CU_FP fRotateDeg = 0; //no rotation
        CU_FP fStrechSpeckle = 1; //no strech
    };

    struct CInput
    {
        CU_FP fPosX;
        CU_FP fPosY;
    };
   
public:
    EigenTest(ILogger* pILogger = NULL);
    virtual ~EigenTest();
   
    CU_STATUS Init(CConfig aConfig);
    CU_STATUS Reset();
    CU_STATUS Term();
    CU_STATUS Execute(CInput* pDataIn);

private:
     void SpeckleImageCreator(CU_FP fPosX, CU_FP fPosY);
   
public:
    CConfig mConfig;
   
//private:
    ILogger* m_pILogger;
   
    //Matrix Declaration
   Eigen::MatrixXcf m_fHarmonic1;
   Eigen::MatrixXcf m_fHarmonic2;
   Eigen::ArrayXXf m_intensityImg;
   
    //vecor Declaration
   Eigen::ArrayXf m_fOmega1;
   Eigen::ArrayXf m_fOmega2;
   Eigen::ArrayXf m_fPhiRadians;
   
    //variables Declaration
    CU_FP m_fCumSumPosX;
    CU_FP m_fCumSumPosY;
    CU_FP m_fNrmMeanIntensity;
};

#endif //__EIGEN_TEST_H__


#include "EigenTest.h"

EigenTest::EigenTest(ILogger* pILogger)
    : m_pILogger(pILogger)
{
   
}

EigenTest::~EigenTest()
{
    Term();
}

//==========================================================================
// Public Functions
//==========================================================================
CU_STATUS EigenTest::Init(CConfig aConfig)
{
   // Initialize / reset discrete-state properties
    mConfig = aConfig;
   
    // Create Cumulative sum signal (for calculating phi):
    m_fCumSumPosX = 0;
    m_fCumSumPosY = 0;
   
    // Create normalizatoin coeficient to acheive designated mean intensity.
   m_fNrmMeanIntensity = sqrt(mConfig.fMeanIntensity / mConfig.uiSourcesNumber);
   
    //Initialize random-number-generator (RNG) with seed:
   std::random_device rd;
   std::mt19937 gen(rd());
    std::uniform_real_distribution<CU_FP> dist (0, 1); // random numbers distribution

   CU_FP MaxRadius = mConfig.fMaxRadius / 2.0f;

   m_fOmega1.resize(mConfig.uiSourcesNumber);
   m_fOmega2.resize(mConfig.uiSourcesNumber);
   if (mConfig.apertureShape) //case of 'circular' aperture shape
   {
      //radius vector - distance from origin (sqrt is Jaacobiam)
      Eigen::ArrayXf fRadius = Eigen::ArrayXf::NullaryExpr(mConfig.uiSourcesNumber, 1,
         [&]() {return sqrt(dist(gen))*MaxRadius; });
      
      //azimuth vector - azimuth from origin
      Eigen::ArrayXf fAzimuth = Eigen::ArrayXf::NullaryExpr(mConfig.uiSourcesNumber, 1,
         [&]() {return dist(gen)*TWO_PI; });
      
      m_fOmega1 = fRadius * (fAzimuth.cos());
      
      m_fOmega2 = fRadius * (fAzimuth.sin());
   }
   else //case of 'square' aperture shape
   {
      m_fOmega1 = Eigen::ArrayXf::NullaryExpr(mConfig.uiSourcesNumber, 1,
            [&]() {return (dist(gen)-0.5f)*MaxRadius; });
      m_fOmega2 = Eigen::ArrayXf::NullaryExpr(mConfig.uiSourcesNumber, 1,
            [&]() {return (dist(gen) - 0.5f)*MaxRadius; });
   }

    //Rotating and Streching the speckles
    if(mConfig.fRotateDeg != 0 || mConfig.fStrechSpeckle != 1)
    {
        CU_FP rotateRad = mConfig.fRotateDeg * (M_PI/180.0f);//convert degrees to radians
        CU_FP rotateA = mConfig.fStrechSpeckle*std::pow(cos(rotateRad),2.0) + std::pow(sin(rotateRad),2.0);
        CU_FP rotateB = sin(rotateRad)*cos(rotateRad)*(1-mConfig.fStrechSpeckle);
        CU_FP rotateC = mConfig.fStrechSpeckle*std::pow(sin(rotateRad),2.0) + std::pow(cos(rotateRad),2.0);
      Eigen::ArrayXf OrigOmegaX = m_fOmega1;

      m_fOmega1 = rotateA * OrigOmegaX + rotateB * m_fOmega2;
      m_fOmega2 = rotateB * OrigOmegaX + rotateC * m_fOmega2;
    }

   //fPhiRadians=rand(srcNumber)*2pi; - Randomly select initial phases
   m_fPhiRadians = Eigen::ArrayXf::NullaryExpr(mConfig.uiSourcesNumber, 1,
      [&]() {return dist(gen)*TWO_PI; });

   
   //Grid axis initialization for exponent argument
   CU_INT gridSize = mConfig.uiFrameSize;

   Eigen::VectorXf fGridN(gridSize);
   fGridN = Eigen::VectorXf::LinSpaced(gridSize, -gridSize / 2, gridSize / 2 - 1);

   Eigen::VectorXf fGridM(gridSize);
   fGridM = Eigen::VectorXf::LinSpaced(gridSize, -gridSize / 2, gridSize / 2 - 1);
   
   //create complex harmonic matrices
   const std::complex<CU_FP> If(0.0f, 1.0f);
   m_fHarmonic1.resize(mConfig.uiFrameSize, mConfig.uiSourcesNumber);
   m_fHarmonic1 = exp((If*(fGridN * m_fOmega1.transpose().matrix())).array());
   
   m_fHarmonic2.resize(mConfig.uiSourcesNumber, mConfig.uiFrameSize);
   m_fHarmonic2 = exp((If*(m_fOmega2.matrix() * fGridM.transpose())).array());

    Reset();

    return eCU_OK;
}

CU_STATUS EigenTest::Reset()
{
    return eCU_OK;
}

CU_STATUS EigenTest::Term()
{
    return eCU_OK;
}

CU_STATUS EigenTest::Execute(CInput* pDataIn)
{
    //function to create 2D Speckle according to outside pos
    SpeckleImageCreator(pDataIn->fPosX,pDataIn->fPosY);
   
    return eCU_OK;
}

//==========================================================================
// Private Functions
//==========================================================================

void EigenTest::SpeckleImageCreator(CU_FP fPosX, CU_FP fPosY)
{
   
   //update cumulative series
    m_fCumSumPosX += fPosX;
    m_fCumSumPosY += fPosY;
   
    //Update Omega - points in furier space
   m_fOmega1 *= (-m_fCumSumPosX);
   m_fOmega2 *= (-m_fCumSumPosY);

   //Compute the complex-shift corresponding to each harmonic
   const std::complex<CU_FP> If(0.0f, 1.0f);
   Eigen::ArrayXcf ComplexShift(mConfig.uiSourcesNumber);
   ComplexShift = exp(If*(m_fPhiRadians + m_fOmega1 + m_fOmega2)) * m_fNrmMeanIntensity;
   
   //Create Field - matrix multiplication - Harmonic1 multiplied by shifted Harmonic2
   Eigen::ArrayXXcf acumField(mConfig.uiFrameSize, mConfig.uiFrameSize);
   acumField = m_fHarmonic1 * (m_fHarmonic2.array().colwise() * ComplexShift).matrix();

   //Create output - intensity image
   m_intensityImg.resize(mConfig.uiFrameSize, mConfig.uiFrameSize);
   m_intensityImg = acumField.real().pow(2) + acumField.imag().pow(2);
}
//==========================================================================
// Mex Functions
//==========================================================================


#include "mex.hpp"
#include "mexAdapter.hpp"
#include <map>

using matlab::mex::ArgumentList;
using namespace matlab::data;

// List actions
enum class Action
{
   Init,
   Execute,
   Reset,
   Term
};
// Map string (first input argument to mexFunction) to an Action
const std::map<std::string, Action> actionTypeMap =
{
{ "init",       Action::Init },
{ "execute",    Action::Execute },
{ "reset",      Action::Reset },
{ "term",      Action::Term }
};


class MexFunction : public matlab::mex::Function {
public:

    void operator()(ArgumentList outputs, ArgumentList inputs) {
        // Get the command string
        CharArray actionCstr(inputs[0]);
        std::string actionStr = actionCstr.toAscii();

        switch (actionTypeMap.at(actionStr))
        {
        case Action::Init:
        {
            //Init Config
            EigenTest::CConfig aConfig;
            StructArray ConfigStructure = std::move(inputs[1]);

            //Assign configuration sent from matlab
         
            TypedArrayRef<double> structField = ConfigStructure[0]["frameSize"];
            aConfig.uiFrameSize = *structField.begin();
            TypedArrayRef<double> structField1 = ConfigStructure[0]["randSeed"];
            aConfig.uiRandSeed = *structField1.begin();
            TypedArrayRef<double> structField2 = ConfigStructure[0]["sourcesNumber"];
            aConfig.uiSourcesNumber = *structField2.begin();
            TypedArrayRef<double> structField3 = ConfigStructure[0]["meanIntensity"];
            aConfig.fMeanIntensity = *structField3.begin();
            TypedArrayRef<double> structField4 = ConfigStructure[0]["maxRadius"];
            aConfig.fMaxRadius = *structField4.begin();
            TypedArrayRef<double> structField5 = ConfigStructure[0]["apertureShape"];
            aConfig.fMaxRadius = *structField5.begin();
            TypedArrayRef<double> structField6 = ConfigStructure[0]["rotateDeg"];
            aConfig.fRotateDeg = *structField6.begin();
            TypedArrayRef<double> structField7 = ConfigStructure[0]["strechSpeckle"];
            aConfig.fStrechSpeckle = *structField7.begin();
         
            //Init Algorithm
            m_Alg.Init(aConfig);

            break;
        }
        case Action::Reset:
        {
            //Reset Algorithm
            m_Alg.Reset();

            break;
        }
        case Action::Term:
        {
            //Term Algorithm
            m_Alg.Term();

            break;
        }
        case Action::Execute:
        {

            //Assign (x,y) pos sent from matlab
            m_aInput.fPosX = std::move(inputs[1][0]);
            m_aInput.fPosY = std::move(inputs[2][0]);

            //Execute Algorithm
            m_Alg.Execute(&m_aInput);

            //Assigne frame to output
         //TypedArray<float> fFrame = m_Factory.createArray({ m_Alg.mConfig.uiFrameSize,m_Alg.mConfig.uiFrameSize },
            //m_Alg.m_intensityImg.data(), m_Alg.m_intensityImg.data()+ m_Alg.m_intensityImg.size());

            //outputs[0] = fFrame;

            break;
        }
        default:

            break;
        }
    }
   
public:
   EigenTest m_Alg;
    ArrayFactory m_Factory;
   EigenTest::CInput m_aInput;
};









Bookmarks



Who is online

Registered users: bartoloni, Bing [Bot], Google [Bot], Yahoo [Bot]