From 314f4b1a505c4bfad7f13f3580e6245ce3beb82f Mon Sep 17 00:00:00 2001 From: Sergey Lisitsyn Date: Wed, 3 Aug 2011 21:04:59 +0400 Subject: [PATCH] Changed isomap geodesic distance with Dijkstra Heap instead of Floyd --- src/shogun/preprocessor/Isomap.cpp | 136 ++++++++++++++++++++--------- 1 file changed, 97 insertions(+), 39 deletions(-) diff --git a/src/shogun/preprocessor/Isomap.cpp b/src/shogun/preprocessor/Isomap.cpp index 06979ae7622..b0dbe123cfd 100644 --- a/src/shogun/preprocessor/Isomap.cpp +++ b/src/shogun/preprocessor/Isomap.cpp @@ -11,6 +11,7 @@ #include #ifdef HAVE_LAPACK #include +#include #include #include #include @@ -21,65 +22,122 @@ using namespace shogun; CCustomDistance* CIsomap::isomap_distance(CDistance* distance) { int32_t N,k,i,j; + float64_t tmp; SGMatrix D_matrix=distance->get_distance_matrix(); N=D_matrix.num_cols; + ASSERT(m_kclear(); + for (i=0; ie with infty - for (i=0; iinsert(j,D_matrix.matrix[i*N+j]); + + // extract nearest neighbor: the jth object itself + heap->extract_min(tmp); + + // extract m_k neighbors and distances + for (j=0; jm_epsilon) - D_matrix.matrix[i] = CMath::ALMOST_INFTY; + edges_idx_matrix[i*m_k+j] = heap->extract_min(tmp); + edges_matrix[i*m_k+j] = tmp; } + // clear heap + heap->clear(); } - if (m_type==KISOMAP) - { - // cut by k-nearest neighbors - - float64_t* col = SG_MALLOC(float64_t, N); - int32_t* col_idx = SG_MALLOC(int32_t, N); - - // -> INFTY edges connecting NOT neighbors - for (i=0; iclear(); - for (j=m_k+1; jinsert(k,0.0); + f[k] = true; - // Floyd-Warshall on distance matrix - // TODO replace by dijkstra - for (k=0; kget_num_nodes()>0) { - for (j=0; jextract_min(tmp); + s[min_item] = true; + f[min_item] = false; + + // for-each edge (min_item->w) + for (i=0; idecrease_key(w, dist); + } + else + { + // insert w to heap and set (f)rontier as true + heap->insert(w, dist); + f[w] = true; + } + } + } } } + // clear heap to re-use + heap->clear(); } + // cleanup + delete heap; + SG_FREE(edges_matrix); + SG_FREE(s); + SG_FREE(f); - CCustomDistance* geodesic_distance = new CCustomDistance(D_matrix.matrix,N,N); + CCustomDistance* geodesic_distance = new CCustomDistance(shortest_D,N,N); // should be removed if custom distance doesn't copy the matrix - SG_FREE(D_matrix.matrix); + SG_FREE(shortest_D); return geodesic_distance; }