|
| 1 | +#ifndef MATLAB_CALLER_IMPL_HPP |
| 2 | +#define MATLAB_CALLER_IMPL_HPP |
| 3 | + |
| 4 | +#include "engine.h" |
| 5 | +#include <vector> |
| 6 | +#include <iostream> |
| 7 | +#include <chrono> |
| 8 | + |
| 9 | +using namespace std::chrono; |
| 10 | + |
| 11 | +class MatlabCaller |
| 12 | +{ |
| 13 | + |
| 14 | +public: |
| 15 | + MatlabCaller(MatlabCaller const&) = delete; |
| 16 | + MatlabCaller& operator=(MatlabCaller const&) = delete; |
| 17 | + ~MatlabCaller() {} |
| 18 | + |
| 19 | + void setEngine(){ |
| 20 | + if (!(matlabPtr = engOpen(""))) { |
| 21 | + throw("\nCan't start MATLAB engine\n"); |
| 22 | + } |
| 23 | + }; |
| 24 | + |
| 25 | + void startMatlab(){ |
| 26 | + // this->matlabFuture = startMATLABAsync(); |
| 27 | + }; |
| 28 | + |
| 29 | + void cd(std::string path){ |
| 30 | + this->currentDirectory = path; |
| 31 | + dirChanged = true; |
| 32 | + }; |
| 33 | + |
| 34 | + void call(std::string functionName, std::vector<double>& params, std::vector<double>& bulkIn, |
| 35 | + std::vector<double>& bulkOut, int contrast, int domain, std::vector<double>& output, double* outputSize, double* rough) |
| 36 | + { |
| 37 | + if (!this->matlabPtr) |
| 38 | + this->setEngine(); |
| 39 | + if (dirChanged){ |
| 40 | + std::string cdCmd = "cd('" + (this->currentDirectory + "')"); |
| 41 | + engEvalString(this->matlabPtr, cdCmd.c_str()); |
| 42 | + } |
| 43 | + //this->matlabPtr->feval(u"cd", factory.createCharArray(this->currentDirectory)); |
| 44 | + dirChanged = false; |
| 45 | + mxArray *PARAMS = mxCreateDoubleMatrix(1,params.size(),mxREAL); |
| 46 | + memcpy(mxGetPr(PARAMS), ¶ms[0], params.size()*sizeof(double)); |
| 47 | + engPutVariable(this->matlabPtr, "params", PARAMS); |
| 48 | + mxArray *BULKIN = mxCreateDoubleMatrix(1,bulkIn.size(),mxREAL); |
| 49 | + memcpy((void *)mxGetPr(BULKIN), &bulkIn[0], bulkIn.size()*sizeof(double)); |
| 50 | + engPutVariable(this->matlabPtr, "bulkIn", BULKIN); |
| 51 | + mxArray *BULKOUT = mxCreateDoubleMatrix(1,bulkOut.size(),mxREAL); |
| 52 | + memcpy((void *)mxGetPr(BULKOUT), &bulkOut[0], bulkOut.size()*sizeof(double)); |
| 53 | + engPutVariable(this->matlabPtr, "bulkOut", BULKOUT); |
| 54 | + mxArray *CONTRAST = mxCreateDoubleScalar(contrast); |
| 55 | + // memcpy((void *)mxGetPr(CONTRAST), &contrast, 1*sizeof(double)); |
| 56 | + engPutVariable(this->matlabPtr, "contrast", CONTRAST); |
| 57 | + // if (domain > 0) |
| 58 | + // args.push_back(factory.createScalar<int>(domain)); |
| 59 | + std::string customCmd = "[output, subRough] = " + (functionName + "(params, bulkIn, bulkOut, contrast)"); |
| 60 | + engPutVariable(this->matlabPtr, "myFunction", mxCreateString(customCmd.c_str())); |
| 61 | + engOutputBuffer(this->matlabPtr, NULL, 0); |
| 62 | + //auto start = high_resolution_clock::now(); |
| 63 | + // std::vector<matlab::data::Array> results = this->matlabPtr->feval(functionName, 2, args); |
| 64 | + engEvalString(this->matlabPtr, "eval(myFunction)"); |
| 65 | + //auto stop = high_resolution_clock::now(); |
| 66 | + //auto duration = duration_cast<microseconds>(stop - start); |
| 67 | + //std::cout << duration.count() << "Usec" << std::endl; |
| 68 | + |
| 69 | + mxArray *matOutput = engGetVariable(this->matlabPtr, "output"); |
| 70 | + if (matOutput == NULL) |
| 71 | + { |
| 72 | + throw("FAILED!"); |
| 73 | + } |
| 74 | + mxArray *subRough = engGetVariable(this->matlabPtr, "subRough"); |
| 75 | + if (subRough == NULL) |
| 76 | + { |
| 77 | + throw("FAILED!"); |
| 78 | + } |
| 79 | + *rough = (double)mxGetScalar(subRough); |
| 80 | + const mwSize* dims = mxGetDimensions(matOutput); |
| 81 | + outputSize[0] = (double) dims[0]; |
| 82 | + outputSize[1] = (double) dims[1]; |
| 83 | + // output.push_back((double) matOutput[i]); |
| 84 | + double* s = (double *)mxGetData(matOutput); |
| 85 | + for (int i=0; i < dims[0] * dims[1]; i++) |
| 86 | + output.push_back(s[i]); |
| 87 | + //std::memcpy(output, (double *)mxGetData(matOutput), mxGetNumberOfElements(matOutput)* mxGetElementSize(matOutput)); |
| 88 | + }; |
| 89 | + |
| 90 | + static MatlabCaller* get_instance() |
| 91 | + { |
| 92 | + // Static local variable initialization is thread-safe |
| 93 | + // and will be initialized only once. |
| 94 | + static MatlabCaller instance{}; |
| 95 | + return &instance; |
| 96 | + }; |
| 97 | + |
| 98 | +private: |
| 99 | + explicit MatlabCaller() {} |
| 100 | + Engine *matlabPtr; |
| 101 | + std::string currentDirectory; |
| 102 | + bool dirChanged = false; |
| 103 | +}; |
| 104 | + |
| 105 | +#endif // MATLAB_CALLER_IMPL_HPP |
0 commit comments