Hello everyone,
There is a problem with getting elements from GF array in C++. For example, I create GF array:
gf([1 2], 5) % actually equals to [gf(1,5) gf(2,5)]
Then I want to read, for example, the first element. But I can't, I can only read whole array. There is no gf type in MATLAB API, so mxGetData won't work. gf type has some properties:
uint32_t x % array of elements
double m % field extention (I don't know why it's double)
uint32_t prim_poly % decimal representation of primitive polynomial
Array elements are stored in x, so it is possible to use mxGetProperty and convert each element back to gf. In this case, I'll have to call gf constructor a lot, but I'm trying to speed up my program by this C++ implementation.
Also, it seems that I have to do all numeric operations by calling them as MATLAB operators (like mexCallMATLAB(1,&hurr,2,&durr,"+"))
Is there any possible way to access one element of GF array explicitly?
MATLAB code:
function [ f_x ] = lagrange( rts, func ) rts_N = length(rts); func_N = length(func); f_x = 0; for i=1:func_N b_i = rts(i); buf = 1; for j=1:rts_N b_j = rts(j); if b_i ~= b_j buf = conv(buf, [1 -b_j]/(b_i - b_j)); end end f_x = f_x + func(i)*buf; end end
C++ code (some bugs here):
void lagrange(mxArray *rts, mxArray *func) { size_t rts_N = mxGetN(mxGetProperty(rts, 0, "x")); size_t func_N = mxGetN(mxGetProperty(func, 0, "x")); size_t func_dims[] = {1, func_N}; size_t rts_dims[] = {1, rts_N}; mxArray *m = mxGetProperty(rts, 0, "m"); if (m == NULL) {mexPrintf("Error! m is NULL \n"); return;} mxArray *f_x, *prhs[2]; prhs[0] = mxCreateDoubleScalar(0); prhs[1] = m; if (prhs[0] == NULL) {mexPrintf("Error! create f_X: prhs[0]\n"); return;} if (prhs[1] == NULL) {mexPrintf("Error! create f_X: prhs[1]\n"); return;} if (mexCallMATLAB(1,&f_x,2,prhs,"gf") != NULL) {mexPrintf("Error! create f_x\n"); return;} uint32_t *rts_numbers = mxGetUint32s(mxGetProperty(rts, 0, "x")); if (rts_numbers == NULL) {mexPrintf("Error! create rts_numbers\n"); return;} uint32_t *func_numbers = mxGetUint32s(mxGetProperty(func, 0, "x")); if (rts_numbers == NULL) {mexPrintf("Error! create rts_numbers\n"); return;} mexPrintf("rts_numbers: %d %d %d\n", rts_numbers[0], rts_numbers[1], func_N); for (int i = 0; i < func_N; i++) { //mexCallMATLAB(0,NULL,1,&f_x,"disp"); mxArray *b_i; prhs[0] = prhs[0] = mxCreateDoubleScalar(rts_numbers[i]); prhs[1] = m; if (mexCallMATLAB(1,&b_i,2,prhs,"gf") != NULL) {mexPrintf("Error! create b_i\n"); return;} mexCallMATLAB(0,NULL,1,&b_i,"disp"); mxArray *buf = mxCreateDoubleScalar(0); for (int j = 0; j < rts_N; j++) { mxArray *b_j; prhs[0] = mxCreateDoubleScalar(rts_numbers[j]); prhs[1] = m; if (mexCallMATLAB(1,&b_j,2,prhs,"gf") != NULL) {mexPrintf("Error! create b_i\n"); return;} if (rts_numbers[i] != rts_numbers[j]) { mxArray *buf1, *buf2, *buf3; prhs[0] = b_i; prhs[1] = b_j; mexCallMATLAB(1,&buf2,2,prhs,"-"); if (buf2 == NULL) {mexPrintf("Error! b_i - b_j\n"); return;} mxArray* arr = mxCreateDoubleMatrix((mwSize) 1, (mwSize) 2, mxREAL); double* d_arr = new double[2]; d_arr[0] = 1; d_arr[1] = rts_numbers[j]; mxSetData(arr, d_arr); prhs[0] = arr; prhs[1] = m; mexCallMATLAB(1, &buf1, 2, prhs, "gf"); if (buf1 == NULL) {mexPrintf("Error! [1 b_j] to gf\n"); return;} prhs[0] = buf1; prhs[1] = buf2; mexCallMATLAB(1, &buf3, 2, prhs, "/"); if (buf3 == NULL) {mexPrintf("Error! [1 b_j]/(b_i - b_j)\n"); return;} buf1 = buf; buf2 = buf3; prhs[0] = buf1; prhs[1] = buf2; mexCallMATLAB(1, &buf, 2, prhs, "conv"); if (buf == NULL) {mexPrintf("Error! conv(buf, [1 b_j]/(b_i - b_j))\n"); return;} } } prhs[0] = mxCreateDoubleScalar(func_numbers[i]); prhs[1] = buf; mxArray* f_x_buf; if (mexCallMATLAB(1, &f_x_buf, 2, prhs, "*") != NULL) {mexPrintf("Error! func_i*buf\n"); return;} prhs[0] = f_x; prhs[1] = f_x_buf; if (mexCallMATLAB(1, &f_x, 2, prhs, "+") != NULL) {mexPrintf("Error! f_x = f_x + func_i*buf;\n"); return;} } mexCallMATLAB(0,NULL,1,&f_x,"disp"); }
Best Answer