aboutsummaryrefslogtreecommitdiff
path: root/measures.cpp
blob: 83f4e8aa026088848e3b1e984aa7af40d86493bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "mp.h"

#include <algorithm>

static
void knn(const arma::mat &dmat, arma::uword i, arma::uword k, arma::uvec &nn, arma::vec &dist)
{
    arma::uword n = dist.n_rows;
    if (k > n) {
        return;
    }

    for (arma::uword j = 0, l = 0; l < k; j++, l++) {
        if (j == i) {
            j++;
        }

        nn[l] = j;
        dist[l] = dmat(i, j);
    }

    double dmax = *std::max_element(dist.begin(), dist.end());
    for (arma::uword j = 0; j < n; j++) {
        if (j == i) {
            continue;
        }

        if (dmat(i, j) < dmax) {
            dmax = dmat(i, j);
            arma::uword l;
            for (l = 0; dmat(i, j) > dist[l] && l < k; l++);
            for (arma::uword m = l + 1; m < k; m++) {
                nn[m]   = nn[m - 1];
                dist[m] = dist[m - 1];
            }

            nn[l] = j;
            dist[l] = dmat(i, j);
        }
    }
}

arma::vec mp::neighborhoodPreservation(const arma::mat &distA,
                                       const arma::mat &distB,
                                       arma::uword k)
{
    arma::uword n = distA.n_rows;
    arma::vec np(n);

    #pragma omp parallel for shared(np, n)
    for (arma::uword i = 0; i < n; i++) {
        arma::uvec nnA(k);
        arma::uvec nnB(k);
        arma::vec dist(k);

        knn(distA, i, k, nnA, dist);
        knn(distB, i, k, nnB, dist);

        std::sort(nnA.begin(), nnA.end());
        std::sort(nnB.begin(), nnB.end());

        arma::uword l;
        for (l = 0; nnA[l] == nnB[l] && l < k; l++);
        np[i] = ((double) l) / k;
    }

    return np;
}

arma::vec mp::silhouette(const arma::mat &distA,
                         const arma::mat &distB,
                         const arma::vec &labels)
{
    // TODO
    return arma::vec(distA.n_rows, arma::fill::zeros);
}