Hi,
I have a problem with cblas_dgemv in a MEX file as follows:
**********************
#include <stdio.h>
#include <cblas.h>
#include <mex.h>
#include <matrix.h>
#include <math.h>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
/* Declare variables */
mxArray *uData, *vData;
double *uMatrix, *v, *gradS;
int i,j;
int m,n;
double v2[mxGetN(prhs[0])], evu[mxGetN(prhs[0])],
ev2u[mxGetN(prhs[0])], ev2, ev3, ev22;
/* Get data */
uData = prhs[0];
vData = prhs[1];
uMatrix = mxGetPr(uData);
v = mxGetPr(vData);
m = mxGetM(uData);
n = mxGetN(uData);
/* l = mxGetN(vData); */
/* Make way for the output */
plhs[0] = mxCreateDoubleMatrix(m, 1, mxREAL);
gradS = mxGetPr(plhs[0]);
/* Do the deed */
ev2 = 0;
ev3 = 0;
for(i=0; i<n; i++) {
v2[i] = v[i]*v[i];
ev2 = ev2+v2[i];
ev3 = ev3+v2[i]*v[i];
}
ev2 = ev2/n;
ev3 = ev3/n;
ev22 = 1/pow(ev2,1.5);
cblas_dgemv(CblasRowMajor, CblasTrans, m, n, 1.0, uMatrix,
n, v, 1, 0.0, evu, 1);
cblas_dgemv(CblasRowMajor, CblasTrans, m, n, 1.0, uMatrix,
n, v, 1, 0.0, ev2u, 1);
for(i=0; i<m; i++) {
evu[i] = evu[i]*(ev3/(ev2*n));
ev2u[i] = ev2u[i]/n;
gradS[i] = (ev2u[i] - evu[i])*ev22;
}
}
*****************
This produces the expected output for square matrices uMatrix, but not for m x n matrices (at least not where n>m, which is the intended use). It seems to be related to row/column major order, for calling it with
uMatrix = [1,2,3;4,5,6]
v = [1,0,0]
or
v2 = [0,1,0]
results in
uMatrix*v = [1,5]'
and
uMatrix*v2 = [4,3]'
Simply using CblasColMajor does not work however, it results in some NaNs and other trouble. If someone can help to clear out this mess and point out what my mistake is, I'd be very grateful.
I have a problem with cblas_dgemv in a MEX file as follows:
**********************
#include <stdio.h>
#include <cblas.h>
#include <mex.h>
#include <matrix.h>
#include <math.h>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
/* Declare variables */
mxArray *uData, *vData;
double *uMatrix, *v, *gradS;
int i,j;
int m,n;
double v2[mxGetN(prhs[0])], evu[mxGetN(prhs[0])],
ev2u[mxGetN(prhs[0])], ev2, ev3, ev22;
/* Get data */
uData = prhs[0];
vData = prhs[1];
uMatrix = mxGetPr(uData);
v = mxGetPr(vData);
m = mxGetM(uData);
n = mxGetN(uData);
/* l = mxGetN(vData); */
/* Make way for the output */
plhs[0] = mxCreateDoubleMatrix(m, 1, mxREAL);
gradS = mxGetPr(plhs[0]);
/* Do the deed */
ev2 = 0;
ev3 = 0;
for(i=0; i<n; i++) {
v2[i] = v[i]*v[i];
ev2 = ev2+v2[i];
ev3 = ev3+v2[i]*v[i];
}
ev2 = ev2/n;
ev3 = ev3/n;
ev22 = 1/pow(ev2,1.5);
cblas_dgemv(CblasRowMajor, CblasTrans, m, n, 1.0, uMatrix,
n, v, 1, 0.0, evu, 1);
cblas_dgemv(CblasRowMajor, CblasTrans, m, n, 1.0, uMatrix,
n, v, 1, 0.0, ev2u, 1);
for(i=0; i<m; i++) {
evu[i] = evu[i]*(ev3/(ev2*n));
ev2u[i] = ev2u[i]/n;
gradS[i] = (ev2u[i] - evu[i])*ev22;
}
}
*****************
This produces the expected output for square matrices uMatrix, but not for m x n matrices (at least not where n>m, which is the intended use). It seems to be related to row/column major order, for calling it with
uMatrix = [1,2,3;4,5,6]
v = [1,0,0]
or
v2 = [0,1,0]
results in
uMatrix*v = [1,5]'
and
uMatrix*v2 = [4,3]'
Simply using CblasColMajor does not work however, it results in some NaNs and other trouble. If someone can help to clear out this mess and point out what my mistake is, I'd be very grateful.