void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {

    /* Check number of input arguments */
    if (nrhs > 4) {
        ERROR("Four or fewer input arguments are required.");
    } else if (nrhs < 3) {
        ERROR("At least three input arguments are required.");
    }

    /* Check number of output arguments */
    if (nlhs > 1) {
        ERROR("Too many output arguments.");
    }

    DOUBLE *X1 = (DOUBLE*) mxGetData(prhs[0]);
    DOUBLE *X2 = (DOUBLE*) mxGetData(prhs[1]);
    DOUBLE *S = (DOUBLE*) mxGetData(prhs[2]);
    INT sqrtFlag;
    if (nrhs >= 4) {
        sqrtFlag = (INT)*(DOUBLE*) mxGetData(prhs[3]);
        if (sqrtFlag > 0) {
            sqrtFlag = 1;
        }
    } else {
        sqrtFlag = 0;
    }

    INT N = (INT) mxGetM(prhs[0]);
    INT numSamples1 = (INT) mxGetN(prhs[0]);
    INT numSamples2 = (INT) mxGetN(prhs[1]);

    if ((numSamples2 != 0) && ((INT) mxGetM(prhs[1]) != N)) {
        ERROR("The signal dimension (first dimension) of the second sample matrix does not match the signal dimension (first dimension) of the first sample matrix.");
    } else if (mxGetM(prhs[2]) != N) {
        ERROR("The first dimension of the Mahalanobis matrix does not match the signal dimension (first dimension) of the first sample matrix.");
    } else if (mxGetN(prhs[2]) != N) {
        ERROR("The second dimension of the Mahalanobis matrix does not match the signal dimension (first dimension) of the first sample matrix.");
    }

    if (numSamples2 == 0) {
        X2 = NULL;
        plhs[0] = mxCreateNumericMatrix(numSamples1, numSamples1, MXPRECISION_CLASS, mxREAL);
    } else {
        plhs[0] = mxCreateNumericMatrix(numSamples1, numSamples2, MXPRECISION_CLASS, mxREAL);
    }
    DOUBLE *distanceMat = (DOUBLE *) mxGetData(plhs[0]);

    DOUBLE *tempX1 = (DOUBLE *) MALLOC(N * numSamples1 * sizeof(DOUBLE));
    DOUBLE *tempX2 = (DOUBLE *) MALLOC(N * numSamples2 * sizeof(DOUBLE));
    DOUBLE *normMat1 = (DOUBLE *) MALLOC(numSamples1 * 1 * sizeof(DOUBLE));
    DOUBLE *oneVec = (DOUBLE *) MALLOC(numSamples1 * 1 * sizeof(DOUBLE));

    mahalanobis_distance(distanceMat, X1, X2, S, N, numSamples1, numSamples2, \
                         sqrtFlag, tempX1, tempX2, normMat1, oneVec);

    FREE(tempX1);
    FREE(tempX2);
    FREE(normMat1);
    FREE(oneVec);
}
예제 #2
0
파일: distance.c 프로젝트: 317070/scipy
void pdist_mahalanobis(const double *X, const double *covinv,
		       double *dm, int m, int n) {
  int i, j;
  const double *u, *v;
  double *it = dm;
  double *dimbuf1, *dimbuf2;
  dimbuf1 = (double*)malloc(sizeof(double) * 2 * n);
  dimbuf2 = dimbuf1 + n;
  for (i = 0; i < m; i++) {
    for (j = i + 1; j < m; j++, it++) {
      u = X + (n * i);
      v = X + (n * j);
      *it = mahalanobis_distance(u, v, covinv, dimbuf1, dimbuf2, n);
    }
  }
  dimbuf2 = 0;
  free(dimbuf1);
}