Algorithm-Cluster

 view release on metacpan or  search on metacpan

perl/Cluster.xs  view on Meta::CPAN

new (class, nodes)
    char* class
    SV* nodes

    PREINIT:
    Tree* tree;
    SV* obj;
    int i;
    int n;
    AV* array;
    int* flag;

    CODE:
    if(!SvROK(nodes) || SvTYPE(SvRV(nodes)) != SVt_PVAV) { 
        croak("Algorithm::Cluster::Tree::new expects an array of nodes\n");
    }
    array = (AV *) SvRV(nodes);
    n = (int) av_len(array) + 1;
    tree = malloc(sizeof(Tree));
    if (tree) {
        tree->n = n;

perl/Cluster.xs  view on Meta::CPAN

        tree->nodes[i].distance = node->distance;
    }

    if (i < n) {
        /* break encountered */
        free(tree->nodes);
        free(tree);
        croak("Algorithm::Cluster::Tree::new expects an array of nodes\n");
    }

    flag = malloc((2*n+1)*sizeof(int));
    if(flag) {
         int j;
        for (i = 0; i < 2*n+1; i++) flag[i] = 0;
        for (i = 0; i < n; i++) {
            j = tree->nodes[i].left;
            if (j < 0) {
                j = -j-1;
                if (j>=i) break;
            }
            else j+=n;
            if (flag[j]) break;
            flag[j] = 1;
            j = tree->nodes[i].right;
            if (j < 0) {
                j = -j-1;
                if (j>=i) break;
            }
            else j+=n;
            if (flag[j]) break;
            flag[j] = 1;
        }
        free(flag);
    }

    if (!flag || i < n) {
        /* break encountered */
        free(tree->nodes);
        free(tree);
        croak("the array of nodes passed to Algorithm::Cluster::Tree::new does not represent a valid tree\n");
    }

    RETVAL = newSViv(0);
    obj = newSVrv(RETVAL, class);
    sv_setiv(obj, PTR2IV(tree));
    SvREADONLY_on(obj);

perl/Cluster.xs  view on Meta::CPAN

        n = tree->n + 1;
    }
    indices = malloc(n*sizeof(int));
    if (!indices) {
        if(values) free(values);
        croak("sort: insufficient memory");
    }
    /* --------------------------------------------------------------- */
    ok = sorttree(tree->n, tree->nodes, values, indices);
    if(values) free(values);
    /* -- Check for errors flagged by the C routine ------------------ */
    if (!ok) {
        free(indices);
        croak("sort: Error in the sorttree routine");
    }
    for(i=0; i<n; i++) XPUSHs(sv_2mortal(newSVnv(indices[i])));
    free(indices);

void
cut(obj, nclusters=0)
    SV* obj

src/cluster.c  view on Meta::CPAN


transpose (input) int
If transpose == 0, the distance between two rows in the matrix is calculated.
Otherwise, the distance between two columns in the matrix is calculated.
============================================================================
*/
{
    double result = 0.;
    double denom1 = 0.;
    double denom2 = 0.;
    int flag = 0;

    /* flag will remain zero if no nonzero combinations of mask1 and mask2 are
     * found.
     */
    if (transpose == 0) /* Calculate the distance between two rows */ {
        int i;
        for (i = 0; i < n; i++) {
            if (mask1[index1][i] && mask2[index2][i]) {
                double term1 = data1[index1][i];
                double term2 = data2[index2][i];
                double w = weight[i];
                result += w*term1*term2;
                denom1 += w*term1*term1;
                denom2 += w*term2*term2;
                flag = 1;
            }
        }
    }
    else {
        int i;
        for (i = 0; i < n; i++) {
            if (mask1[i][index1] && mask2[i][index2]) {
                double term1 = data1[i][index1];
                double term2 = data2[i][index2];
                double w = weight[i];
                result += w*term1*term2;
                denom1 += w*term1*term1;
                denom2 += w*term2*term2;
                flag = 1;
            }
        }
    }
    if (!flag) return 0.;
    if (denom1 == 0.) return 1.;
    if (denom2 == 0.) return 1.;
    result = result / sqrt(denom1*denom2);
    result = 1. - result;
    return result;
}

/* ********************************************************************* */

static double

src/cluster.c  view on Meta::CPAN


transpose (input) int
If transpose == 0, the distance between two rows in the matrix is calculated.
Otherwise, the distance between two columns in the matrix is calculated.
============================================================================
*/
{
    double result = 0.;
    double denom1 = 0.;
    double denom2 = 0.;
    int flag = 0;
    /* flag will remain zero if no nonzero combinations of mask1 and mask2 are
     * found.
     */

    if (transpose == 0) /* Calculate the distance between two rows */ {
        int i;
        for (i = 0; i < n; i++) {
            if (mask1[index1][i] && mask2[index2][i]) {
                double term1 = data1[index1][i];
                double term2 = data2[index2][i];
                double w = weight[i];
                result += w*term1*term2;
                denom1 += w*term1*term1;
                denom2 += w*term2*term2;
                flag = 1;
            }
        }
    }
    else {
        int i;
        for (i = 0; i < n; i++) {
            if (mask1[i][index1] && mask2[i][index2]) {
                double term1 = data1[i][index1];
                double term2 = data2[i][index2];
                double w = weight[i];
                result += w*term1*term2;
                denom1 += w*term1*term1;
                denom2 += w*term2*term2;
                flag = 1;
            }
        }
    }
    if (!flag) return 0.;
    if (denom1 == 0.) return 1.;
    if (denom2 == 0.) return 1.;
    result = fabs(result) / sqrt(denom1*denom2);
    result = 1. - result;
    return result;
}

/* *********************************************************************    */

static double

src/cluster.c  view on Meta::CPAN

transpose (input) int
If transpose == 0, the distance between two rows in the matrix is calculated.
Otherwise, the distance between two columns in the matrix is calculated.
============================================================================
*/
{
    double con = 0;
    double dis = 0;
    double exx = 0;
    double exy = 0;
    int flag = 0;
    /* flag will remain zero if no nonzero combinations of mask1 and mask2 are
     * found.
     */
    double denomx;
    double denomy;
    double tau;
    int i, j;

    if (transpose == 0) {
        for (i = 0; i < n; i++) {
            if (mask1[index1][i] && mask2[index2][i]) {

src/cluster.c  view on Meta::CPAN

                        const double x2 = data1[index1][j];
                        const double y1 = data2[index2][i];
                        const double y2 = data2[index2][j];
                        const double w = weight[i] * weight[j];
                        if (x1 < x2 && y1 < y2) con += w;
                        else if (x1 > x2 && y1 > y2) con += w;
                        else if (x1 < x2 && y1 > y2) dis += w;
                        else if (x1 > x2 && y1 < y2) dis += w;
                        else if (x1 == x2 && y1 != y2) exx += w;
                        else if (x1 != x2 && y1 == y2) exy += w;
                        flag = 1;
                    }
                }
            }
        }
    }
    else {
        for (i = 0; i < n; i++) {
            if (mask1[i][index1] && mask2[i][index2]) {
                for (j = 0; j < i; j++) {
                    if (mask1[j][index1] && mask2[j][index2]) {

src/cluster.c  view on Meta::CPAN

                        const double x2 = data1[j][index1];
                        const double y1 = data2[i][index2];
                        const double y2 = data2[j][index2];
                        const double w = weight[i] * weight[j];
                        if (x1 < x2 && y1 < y2) con += w;
                        else if (x1 > x2 && y1 > y2) con += w;
                        else if (x1 < x2 && y1 > y2) dis += w;
                        else if (x1 > x2 && y1 < y2) dis += w;
                        else if (x1 == x2 && y1 != y2) exx += w;
                        else if (x1 != x2 && y1 == y2) exy += w;
                        flag = 1;
                    }
                }
            }
        }
    }
    if (!flag) return 0.;
    denomx = con + dis + exx;
    denomy = con + dis + exy;
    if (denomx == 0) return 1;
    if (denomy == 0) return 1;
    tau = (con-dis)/sqrt(denomx*denomy);
    return 1.-tau;
}

/* *********************************************************************    */



( run in 2.123 seconds using v1.01-cache-2.11-cpan-94b05bcf43c )