In the code below "h_fir" is giving all zeros differently from the equivalent Matlab code.
"L" = 204621
This is a function inside a mex file. The call from Matlab is working well and it come back well.
Can you devise the reason?
Matlab 2015a
Below a minimal example.
Thanks
Luis Gonçalves
#include "C:\Program Files\MATLAB\MATLAB Production Server\R2015a\extern\include\mex.h"
#include "C:\Program Files\MATLAB\MATLAB Production Server\R2015a\extern\include\matrix.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <malloc.h>
#include <time.h>
#include <string.h>
#define MAX(p,q) ((p>q)?p:q)
void example(mxArray *,double, double);
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double v,f_simb,ts,vkmh,fd,c,R,p,q,fc,pqmax;
mxArray *h_fir;
int g2;
double *a3,*a4;
ts=10e-3;
vkmh=50;
c=3e8;
fc=2e9;
f_simb=1/ts;
v=vkmh/3.6;
fd=v/c*fc;
R=f_simb/(fd*110.5);
p = 100.0;
q = (double)(int)(p/R+0.5);
if (q<0.001)
q= 1.0;
h_fir= mxCreateDoubleMatrix(1,(int)(2.0*10.0*MAX(p,q) + 1.5),mxCOMPLEX);
example(h_fir,p,q);
a3 = mxGetPr(h_fir);
a4=mxGetPi(h_fir);
for(g2=102306-10;g2<102306+10;g2++)
mexPrintf("%e %e\n",a3[g2],a4[g2]);
return;
}
void example(mxArray *h_fir,double p, double q)
{
double N,pqmax,fc,L;
mxArray *L1,*ARRAY1,*ARRAY2;
double *array1,*array2,*hr,*hi;
mxArray *ppFevalRhs[3];
mxArray *ppFevalRhsin[1], *OUT1;
int i1,i2,*l1;
const size_t dims[2]={1,1};
N = 10.0;
pqmax = MAX(p,q);
fc = 1.0/2.0/pqmax;
L = 2.0*N*pqmax + 1.0;
L1 = mxCreateNumericArray(2, dims,mxINT32_CLASS, mxREAL);
l1 = (int *)mxGetData(L1);
*l1= (int)(L-1);
ppFevalRhs[0]=L1;
ARRAY1 = mxCreateDoubleMatrix(4, 1, mxCOMPLEX);
array1 = mxGetPr(ARRAY1);
array1[0]= 0;
array1[1]= 2.0*fc;
array1[2]= 2.0*fc;
array1[3]= 1;
array1 = mxGetPi(ARRAY1);
array1[0]= 0;
array1[1]= 0;
array1[2]= 0;
array1[3]= 0;
ppFevalRhs[1]=ARRAY1;
ARRAY2 = mxCreateDoubleMatrix(4, 1, mxCOMPLEX);
array2 = mxGetPr(ARRAY2);
array2[0]= 1;
array2[1]= 1;
array2[2]= 0;
array2[3]= 0;
array2 = mxGetPi(ARRAY2);
array2[0]= 0;
array2[1]= 0;
array2[2]= 0;
array2[3]= 0;
ppFevalRhs[2]=ARRAY2;
ppFevalRhsin[0]=h_fir;
if (mexCallMATLAB(1, ppFevalRhsin, 3, ppFevalRhs, "firls")!=0)
mexPrintf("firls error\n");
mxDestroyArray(L1);
mxDestroyArray(ARRAY1);
mxDestroyArray(ARRAY2);
}
The output variables of a matlab function called from mex are created by matlab and do not needed to be allocated before. The previous allocated pointer passed to matlab is overwritten by matlab. That is why the code above do not works.
Related
Using mmap(), I am going to write a value to the GPIO register address of the Raspberry Pi.
I thought the register value would have the same when reading mapped GPIO address in unsigned int * or char *, but it was not. I compared the results for both cases.
This is my code.
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#define GPIO_BASE 0x3F200000
#define GPFSEL1 0x04
#define GPSET0 0x1C
#define GPCLR0 0x28
int main()
{
int fd = open("/dev/mem", O_RDWR|O_SYNC);
// Error Handling
if (fd < 0) {
printf("Can't open /dev/mem \n");
exit(1);
}
// Map pages of memory
char *gpio_memory_map = (char*)mmap(0, 4096, PROT_READ|PROT_WRITE,
MAP_SHARED, fd, GPIO_BASE);
// Error Handling
if (gpio_memory_map == MAP_FAILED) {
printf("Error : mmap \n");
exit(-1);
}
// GPIO18
//volatile unsigned int *gpio = (volatile unsigned int*)gpio_memory_map;
//gpio[GPFSEL1/4] = (1<<24);
volatile char *gpio = (volatile char *)gpio_memory_map;
int i;
for (i = 0; i < 16; i++)
printf("gpio[%d](%#x) = %#0x\n", i, &gpio[i], gpio[i]);
/*
for (i = 0; i < 5; i++) {
gpio[GPCLR0 / 4] = (1 << 18);
sleep(1);
gpio[GPSET0 / 4] = (1 << 18);
sleep(1);
}
*/
// Unmap pages of memory
munmap(gpio_memory_map, 4096);
return 0;
}
And those below are the results.
volatile unsigned int *gpio = (volatile unsigned int *)gpio_memory_map;
gpio[0](0x76f12000) = 0x1
gpio[1](0x76f12004) = 0x1000000
gpio[2](0x76f12008) = 0
gpio[3](0x76f1200c) = 0x3fffffc0
gpio[4](0x76f12010) = 0x24000924
gpio[5](0x76f12014) = 0x924
gpio[6](0x76f12018) = 0
gpio[7](0x76f1201c) = 0x6770696f
gpio[8](0x76f12020) = 0x6770696f
gpio[9](0x76f12024) = 0x6770696f
gpio[10](0x76f12028) = 0x6770696f
gpio[11](0x76f1202c) = 0x6770696f
gpio[12](0x76f12030) = 0x6770696f
gpio[13](0x76f12034) = 0x2ffbbfff
gpio[14](0x76f12038) = 0x3ef4ff
gpio[15](0x76f1203c) = 0
volatile char *gpio = (volatile char *)gpio_memory_map;
As the result #1 above, I thought gpio[1], gpio[2], gpio[3] should be 0. But it was different. And even if I try to write a new value on gpio[1] or gpio[2] or gpio[3], it stays the same. Why are the results different when approaching char * and unsigned char *?
gpio[0](0x76f47000) = 0x1
gpio[1](0x76f47001) = 0x69
gpio[2](0x76f47002) = 0x70
gpio[3](0x76f47003) = 0x67
gpio[4](0x76f47004) = 0
gpio[5](0x76f47005) = 0x69
gpio[6](0x76f47006) = 0x70
gpio[7](0x76f47007) = 0x67
gpio[8](0x76f47008) = 0
gpio[9](0x76f47009) = 0x69
gpio[10](0x76f4700a) = 0x70
gpio[11](0x76f4700b) = 0x67
gpio[12](0x76f4700c) = 0xc0
gpio[13](0x76f4700d) = 0x69
gpio[14](0x76f4700e) = 0x70
gpio[15](0x76f4700f) = 0x67
I'm following this example but I'm not sure what I missed. Specifically, I have this struct in MATLAB:
a = struct; a.one = 1.0; a.two = 2.0; a.three = 3.0; a.four = 4.0;
And this is my test code in MEX ---
First, I wanted to make sure that I'm passing in the right thing, so I did this check:
int nfields = mxGetNumberOfFields(prhs[0]);
mexPrintf("nfields =%i \n\n", nfields);
And it does yield 4, since I have four fields.
However, when I tried to extract the value in field three:
tmp = mxGetField(prhs[0], 0, "three");
mexPrintf("data =%f \n\n", (double *)mxGetData(tmp) );
It returns data =1.000000. I'm not sure what I did wrong. My logic is that I want to get the first element (hence index is 0) of the field three, so I expected data =3.00000.
Can I get a pointer or a hint?
EDITED
Ok, since you didn't provide your full code but you are working on a test, let's try to make a new one from scratch.
On Matlab side, use the following code:
a.one = 1;
a.two = 2;
a.three = 3;
a.four = 4;
read_struct(a);
Now, create and compile the MEX read_struct function as follows:
#include "mex.h"
void read_struct(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if (nrhs != 1)
mexErrMsgTxt("One input argument required.");
/* Let's check if the input is a struct... */
if (!mxIsStruct(prhs[0]))
mexErrMsgTxt("The input must be a structure.");
int ne = mxGetNumberOfElements(prhs[0]);
int nf = mxGetNumberOfFields(prhs[0]);
mexPrintf("The structure contains %i elements and %i fields.\n", ne, nf);
mwIndex i;
mwIndex j;
mxArray *mxValue;
double *value;
for (i = 0; i < nf; ++i)
{
for (j = 0; j < ne; ++j)
{
mxValue = mxGetFieldByNumber(prhs[0], j, i);
value = mxGetPr(mxValue);
mexPrintf("Field %s(%d) = %.1f\n", mxGetFieldNameByNumber(prhs[0],i), j, value[0]);
}
}
return;
}
Does this correctly prints your structure?
I'm new to mex and this problem spent me days but I still cannot figure out what to do.
I create la_test.cpp file to test one of the subroutines in CLAPCK: cgemm_ (complex matrix-matrix multiplication). Here is the code:
#include "mex.h"
#include "matrix.h"
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <iostream>
#include <stdio.h>
#include "f2c.h"
#include "clapack.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
float *Xr,*Xi; // To store the input data
float *zsr,*zsi; // To store the output
long int m,n;
complex *A;
Xr = (float *) mxGetPr(prhs[0]);
Xi = (float *) mxGetPi(prhs[0]);
size_t K = mxGetNumberOfDimensions(prhs[0]);
const int *size = mxGetDimensions(prhs[0]);
m = mxGetM(prhs[0]);
n = mxGetN(prhs[0]);
A = new complex[m*n];
complex one = {1.0f, 0.0f}, zero = {0.0f, 0.0f};
for (int i=0; i<m; i++){
for (int j=0; j<n; j++){
complex rc = {Xr[j + n*i], Xi[j + n*i]};
A[j + n*i] = rc;
}
}
plhs[0] =(mxArray *) mxCreateDoubleMatrix( n, n, mxCOMPLEX );
zsr = (float *) mxGetPr(plhs[0]);
zsi = (float *) mxGetPi(plhs[0]);
complex *AtA = 0;
AtA = new complex[n*n];
char *chn = "N";
char *chc = "C";
cgemm_(chc, chn, &n, &n, &m, &one, A, &m, A, &m, &zero, AtA, &n);
for (int i=0; i<m; i++){
for (int j=0; j<n; j++){
zsr[j + n*i] = AtA[j + n*i].r;
zsi[j + n*i] = AtA[j + n*i].i;
}
}
}
Basically, I store input matrix into A and try to compute A'*A. Header files: f2c.h, clapack.h as well as three 64bit libraries: blas.lib, libf2c.lib and lapack.lib from http://icl.eecs.utk.edu/lapack-for-windows/clapack/index.html#install are all in the same file of la_test.cpp. I'm working on Windows 7 64bit system with matlab r2013a and Visual Studio 2012.
I have tried with both:
mex la_test.cpp lapack.lib libf2c.lib blas.lib
and
mex -llapack -llibf2c -lblas -L"C:\Users\Ziwu\Desktop\la_test" la_test.cpp
all with following error:
Creating library C:\Users\Ziwu\AppData\Local\Temp\mex_epl230\templib.x and object C:\Users\Ziwu\AppData\Local\Temp\mex_epl230\templib.exp
la_test.obj : error LNK2019: unresolved external symbol cgemm_ referenced in function mexFunction
la_test.mexw64 : fatal error LNK1120: 1 unresolved externals
I've checked on Internet for long time, but found no solution yet!
Please help me if you have any advice.
For faster loading of images in MATLAB I am using multi-page TIFF files which for me work much faster than MATLAB's simple imread. But my problem is that the size of the TIFF file is way bigger than normal images ( like ten times more ) so I'm looking in compression options. I have tried some of those options ( with the code I attached below ) some of them don't work and produce empty files and the rest kill the speed.
Is there any way to have both size and speed?
Thank you
P.S: I put my codes here. If I'm doing sth wrong please tell me.
#include <stdio.h>
#include <time.h>
#include "tiffio.h"
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace std;
#define XSIZE 1280
#define YSIZE 720
#define NPAGES 1000
#define CHANNEL 3
int main (int argc, char **argv)
{
uint32 image_width, image_height;
float xres, yres;
uint16 spp, bpp, photo, res_unit;
TIFF *out;
int i, j;
uint16 page;
Mat img;
int COMPRESSION_TAG = atoi(argv[1]);
unsigned char *array = new unsigned char [XSIZE * YSIZE*3];
char name[20];
out = TIFFOpen("myfile.tif", "w");
image_width = XSIZE;
image_height = YSIZE;
spp = CHANNEL; /* Samples per pixel */
bpp = 8; /* Bits per sample */
photo = PHOTOMETRIC_MINISBLACK;
for (page = 0; page < NPAGES; page++)
{
sprintf(name, "5_29%03d.jpg", page);
img = imread(name);
array = img.data;
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, image_width );
TIFFSetField(out, TIFFTAG_IMAGELENGTH, image_height);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bpp);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photo);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_TAG);
/* It is good to set resolutions too (but it is not nesessary) */
xres = yres = 100;
res_unit = RESUNIT_INCH;
TIFFSetField(out, TIFFTAG_XRESOLUTION, xres);
TIFFSetField(out, TIFFTAG_YRESOLUTION, yres);
TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, res_unit);
/* We are writing single page of the multipage file */
TIFFSetField(out, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
/* Set the page number */
TIFFSetField(out, TIFFTAG_PAGENUMBER, page, NPAGES);
for (j = 0; j < image_height; j++)
TIFFWriteScanline(out, &array[3*j * image_width], j, 0);
TIFFWriteDirectory(out);
}
TIFFClose(out);
return 0;
}
I am new to OpenMP. I have the following code which compiles fine using Matlab mex configured with MSVS2010. The computer has 8 processors available (which I checked also by using matlabpool).
#include "mex.h"
#include <omp.h>
typedef unsigned char uchar;
typedef unsigned int uint;
//Takes a uint8 input array and uint32 index array and preallocated uint8 array the same
//size as the first one and copies the data over using the indexed mapping
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] )
{
uint N = mxGetN(prhs[0]);
mexPrintf("n=%i\n", N); mexEvalString("drawnow");
uchar *input = (uchar*)mxGetData(prhs[0]);
uint *index = (uint*)mxGetData(prhs[1]);
uchar *output = (uchar*)mxGetData(prhs[2]);
uint nThreads, tid;
#pragma omp parallel private(tid) shared(input, index, output, N, nThreads) num_threads(8)
{
tid = omp_get_thread_num();
if (tid==0) {
nThreads = omp_get_num_threads();
}
for (int i=tid*N/nThreads;i<tid*N/nThreads+N/nThreads;i++){
output[i]=input[index[i]];
}
}
mexPrintf("nThreads = %i\n",nThreads);mexEvalString("drawnow");
}
The output I get is
n=600000000
nThreads = 1
Why is only one thread being created despite me requesting 8?
Sigh. Typical, spend hours trying and failing and then find the answer 5 minutes after posting to SO.
The file needs to be mexed with openmp support
mex mexIndexedCopy.cpp COMPFLAGS="/openmp $COMPFLAGS"