Help me make faster R code for Kennard-Stone algorithm [My code is so slow from Matlab]

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Help me make faster R code for Kennard-Stone algorithm [My code is so slow from Matlab]

Kevin Hao-2
Hi all,

Can you help me change my Kennard-Stone algorithm to faster one?

[The original code can run fast in matlab, but when I change matlab code to
R code, it is so slow.]

Since my code so crude and too many loops (changed from matlab code), it is
too slow. I hope that you can help to improve the performance.

Thanks.

kevin

################################################################################
#
##############################################################################
# Kennard-Stone algorithm for selection of samples
ksFun = function(x, N) {
        # Initial the vector of minimum distance
        dminmax = sample(0, N, replace = TRUE) # Default: FALSE
        M = nrow(x)
        samples = 1:M
        # Initializes the matrix of distances
        D = matrix(0, nrow = M, ncol = M)
        for (i in 1:(M - 1)) {
                xa = x[i, ]
                for (j in (i + 1):M) {
                        xb = x[j, ]
                        # D: Upper Trianglar Matrix
                        # D[i, j] = Euclidean distance between object i and
j (j > i)
                        D[i, j] = max(svd(xa - xb)$d) # the largest
singular value
                }
        }

        cat("for (i in 1:(M - 1)) done! \n")

        maxD = apply(D, 2, max)
        index_row = apply(D, 2, function(x) which(x == max(x))[1])

        dummy = max(maxD)
        index_column = which(maxD == dummy)
        m = vector()
        m[1] = index_row[index_column]
        m[2] = index_column

        dminmax[2] = D[m[1], m[2]]

        for (i in 3:N) {
                pool = setdiff(samples, m)
                dmin = sample(0, M-i+1, replace = TRUE)
                for (j in 1:(M-i+1)) {
                        indexa = pool[j]
                        d = sample(0, i-i, replace = TRUE)
                        for ( k in 1:(i-1)) {
                                indexb = m[k]
                                if (indexa < indexb) {
                                        d[k] = D[indexa, indexb]
                                } else {
                                        d[k] = D[indexb, indexa]
                                }
                        }
                        dmin[j] = min(d)
                }
                #cat("for (j in 1:(M -i+1)) done! \n")
                dminmax[i] = max(dmin)
                index = which(dmin == max(dmin))
                m[i] = pool[index]
        }
        cat("for (i in 3:N) done! \n")
        res = list(m = m, dminmax = dminmax)
        return(res)
}

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.