ordfilt2.c

来自「有关matlab的电子书籍有一定的帮助希望有用」· C语言 代码 · 共 680 行 · 第 1/2 页

C
680
字号
        }
    }

    return(aa);
}

uint8_T **MakeZeroPaddedInput8(uint8_T **xx, int mx, int nx, int md, int nd) {
    uint8_T **aa;
    int maa;
    int naa;
    int rowOrigin;
    int colOrigin;
    int row;
    int col;

    maa = mx + md - 1;
    naa = nx + nd - 1;

    rowOrigin = (md - 1) / 2;
    colOrigin = (nd - 1) / 2;

    aa = Make2SubscriptMatrix8((uint8_T *) mxCalloc(maa*naa, sizeof(uint8_T)),
                               maa, naa);

    for (col = 0; col < nx; col++) {
        for (row = 0; row < mx; row++) {
             aa[col+colOrigin][row+rowOrigin] = xx[col][row];
        }
    }

    return(aa);
}

#ifndef NDEBUG
/* comparison function cmp() is used in debugging call to qsort below. */
int cmp(const void *keyval, const void *datum)
{
    double val1;
    double val2;
    
    val1 = *((double *) keyval);
    val2 = *((double *) datum);
    
    if (val1 < val2)
    {
        return(-1);
    }
    else if (val1 == val2)
    {
        return(0);
    }
    else
    {
        return(1);
    }
}
#endif /* NDEBUG */


static void
ordfilt8(const mxArray *Y, const mxArray *X, int order,
        const mxArray *Domain, int domainSize, 
        const mxArray *S, bool offsetsAreZero) {

    uint8_T *y;
    uint8_T *x;
    int mx;
    int nx;
    double *d;
    int md;
    int nd;
    uint8_T **aa;         /* zero-padded input */
    double **dd;         /* 2-subscript domain array */
    uint8_T **yy;         /* 2-subscript output array */
    double *vector;      /* values passed to order_select() */
    int *domainRows;     /* row indices for nonzero domain elements */
    int *domainCols;     /* column indices for nonzero domain elements */
    int domainRowOrigin; /* center of domain */
    int domainColOrigin; /* center of domain */
    int counter;
    int row;
    int col;
    int r;
    int c;

    mxAssert(offsetsAreZero, "Called uint8 case with nonzero offsets");

    y = (uint8_T *) mxGetData(Y);
    x = (uint8_T *) mxGetData(X);
    mx = mxGetM(X);
    nx = mxGetN(X);
    d = (double *) mxGetData(Domain);
    md = mxGetM(Domain);
    nd = mxGetN(Domain);

    aa = MakeZeroPaddedInput8(Make2SubscriptMatrix8(x, mx, nx), 
                              mx, nx, md, nd);

    yy = Make2SubscriptMatrix8(y, mx, nx);

    /* Compute domain info */
    domainRowOrigin = (md - 1) / 2;
    domainColOrigin = (nd - 1) / 2;
    domainRows = (int *) mxCalloc(domainSize, sizeof(int));
    domainCols = (int *) mxCalloc(domainSize, sizeof(int));
    dd = Make2SubscriptMatrix(d, md, nd);
    counter = 0;
    for (row = 0; row < md; row++) {
        for (col = 0; col < nd; col++) {
            if (dd[col][row] != 0.0) {
                domainRows[counter] = row;
                domainCols[counter] = col;
                counter++;
            }
        }
    }
    
    vector = mxCalloc(domainSize, sizeof(double));
    
    for (col = 0; col < nx; col++) {
        for (row = 0; row < mx; row++) {
            /* Fill the vector */
            for (counter = 0; counter < domainSize; counter++) {
                r = domainRows[counter];
                c = domainCols[counter];
                vector[counter] = (double) aa[col+c][row+r];
            }
            yy[col][row] = (uint8_T) order_select(vector, domainSize, order);
#ifndef NDEBUG
            /* Check result against C lib function qsort() */
            for (counter = 0; counter < domainSize; counter++) {
                r = domainRows[counter];
                c = domainCols[counter];
                vector[counter] = (double) aa[col+c][row+r];
            }
            qsort((void *) vector, (size_t) domainSize, sizeof(double), cmp);
            mxAssert(((double) yy[col][row]) == vector[order-1], "");
#endif /* NDEBUG */
        }
    }

    mxFree((void *) vector); 
}

static void
ordfilt(const mxArray *Y, const mxArray *X, int order,
        const mxArray *Domain, int domainSize, 
        const mxArray *S, bool offsetsAreZero) {

    double *y;
    double *x;
    int mx;
    int nx;
    double *d;
    int md;
    int nd;
    double *s;
    double **aa;         /* zero-padded input */
    double **dd;         /* 2-subscript domain array */
    double **ss;         /* 2-subscript offsets array */
    double **yy;         /* 2-subscript output array */
    double *vector;      /* values passed to order_select() */
    int *domainRows;     /* row indices for nonzero domain elements */
    int *domainCols;     /* column indices for nonzero domain elements */
    int domainRowOrigin; /* center of domain */
    int domainColOrigin; /* center of domain */
    int counter;
    int row;
    int col;
    int r;
    int c;

    y = (double *) mxGetData(Y);
    x = (double *) mxGetData(X);
    mx = mxGetM(X);
    nx = mxGetN(X);
    d = (double *) mxGetData(Domain);
    md = mxGetM(Domain);
    nd = mxGetN(Domain);

    aa = MakeZeroPaddedInput(Make2SubscriptMatrix(x, mx, nx), mx, nx, md, nd);

    yy = Make2SubscriptMatrix(y, mx, nx);

    /* Compute domain info */
    domainRowOrigin = (md - 1) / 2;
    domainColOrigin = (nd - 1) / 2;
    domainRows = (int *) mxCalloc(domainSize, sizeof(int));
    domainCols = (int *) mxCalloc(domainSize, sizeof(int));
    dd = Make2SubscriptMatrix(d, md, nd);
    counter = 0;
    for (row = 0; row < md; row++) {
        for (col = 0; col < nd; col++) {
            if (dd[col][row] != 0.0) {
                domainRows[counter] = row;
                domainCols[counter] = col;
                counter++;
            }
        }
    }
    
    if (! offsetsAreZero) {
        s = (double *) mxGetData(S);
        ss = Make2SubscriptMatrix(s, md, nd);
    }

    vector = mxCalloc(domainSize, sizeof(double));
    
    if (! offsetsAreZero) {
	for (col = 0; col < nx; col++) {
            for (row = 0; row < mx; row++) {
                /* Fill the vector */
                for (counter = 0; counter < domainSize; counter++) {
                    r = domainRows[counter];
                    c = domainCols[counter];
                    vector[counter] = aa[col+c][row+r] + ss[c][r];
                }
                yy[col][row] = order_select(vector, domainSize, order);
#ifndef NDEBUG
                /* Check result against C lib function qsort() */
                for (counter = 0; counter < domainSize; counter++) {
                    r = domainRows[counter];
                    c = domainCols[counter];
                    vector[counter] = aa[col+c][row+r] + ss[c][r];
                }
                qsort((void *) vector, (size_t) domainSize, 
                      sizeof(double), cmp);
                mxAssert(yy[col][row] == vector[order-1], "");
#endif /* NDEBUG */
            }
        }
        mexAddFlops(nx * mx * domainSize);
    } else {
        for (col = 0; col < nx; col++) {
            for (row = 0; row < mx; row++) {
                /* Fill the vector */
                for (counter = 0; counter < domainSize; counter++) {
                    r = domainRows[counter];
                    c = domainCols[counter];
                    vector[counter] = aa[col+c][row+r];
                }
                yy[col][row] = order_select(vector, domainSize, order);
#ifndef NDEBUG
                /* Check result against C lib function qsort() */
                for (counter = 0; counter < domainSize; counter++) {
                    r = domainRows[counter];
                    c = domainCols[counter];
                    vector[counter] = aa[col+c][row+r];
                }
                qsort((void *) vector, (size_t) domainSize, 
                      sizeof(double), cmp);
                mxAssert(yy[col][row] == vector[order-1], "");
#endif /* NDEBUG */
            }
        }
    }

    mxFree((void *) vector);
}

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    const mxArray *X_in;
    const mxArray *X;
    const mxArray *Order_in;
    mxArray *Order;
    const mxArray *Domain_in;
    mxArray *Domain;
    const mxArray *S_in;
    mxArray *S;
    mxArray *Y;
    int domainSize;
    int order;           /* desired order statistic */
    bool offsetsAreZero; /* additive offsets flag */

    ValidateInputs(nlhs, nrhs, prhs, &X_in, &Order_in, &Domain_in,
                   &S_in);

    Order = ConvertToDouble(Order_in);  /* exploits MATLAB's copy-by-ref */
    Domain = ConvertToDouble(Domain_in);
    if (S_in != NULL) {
        S = ConvertToDouble(S_in);
    } else {
        S = NULL;
    }

    domainSize = NumNonzeros(Domain);
    if (domainSize == 0) {
        mexErrMsgTxt("DOMAIN must have at least one nonzero element");
    }

    order = GetOrder(Order, domainSize);

    /* Additive offsets? */
    if ((S == NULL) || (NumNonzeros(S) == 0)) {
        offsetsAreZero = true;
    } else {
        offsetsAreZero = false;
    }

    /* If additive offsets, convert input to double */
    if (offsetsAreZero) {
        X = (mxArray *) X_in;
    } else {
        X = ConvertToDouble(X_in);
    }

    /* Initialize outputs */
    Y = mxCreateNumericArray(mxGetNumberOfDimensions(X),
                             mxGetDimensions(X),
                             mxGetClassID(X),
                             mxREAL);
    if (mxIsLogical(X) && offsetsAreZero) {
        mxSetLogical(Y);
    }

    /* If the output matrix is empty we don't need to do anything. */
    if (! mxIsEmpty(Y)) {
        if (mxIsDouble(X)) {
            ordfilt(Y, X, order, Domain, domainSize, S, offsetsAreZero);
        } else if (mxIsUint8(X)) {
            ordfilt8(Y, X, order, Domain, domainSize, S, offsetsAreZero);
        } else {
            mxAssert(1, "Class of X is not 'double' or 'uint8'");
        }
    }

    /* Done!  Give back the answer and clean up. */
    plhs[0] = Y;
    if (X != X_in) {
        mxDestroyArray((mxArray *) X);
    }
    mxDestroyArray((mxArray *) Order);
    mxDestroyArray((mxArray *) Domain);
    if (S != NULL) {
        mxDestroyArray((mxArray *) S);
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?