This repository has been archived by the owner on Nov 30, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTasks_2_graph.qs
89 lines (85 loc) · 3.38 KB
/
Tasks_2_graph.qs
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
77
78
79
80
81
82
83
84
85
86
87
88
89
namespace Final_Project
{
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Primitive;
open Microsoft.Quantum.Extensions.Convert;
/// # Summary
/// Creates Neighbourhood Graph where edges are formed between every point and the centers
/// where the centers are chosen by quant_find_k_smallest
/// and edges are weighted by the distance to the center
///
/// # Input
/// ## n
/// Number of qubits required to represent indices
/// ## m
/// Number of qubits required to represent distance between any 2 points
/// ## indices
/// Indices of datapoints over which to look for pair of points.
/// ## distances
/// Distances between two points where distances[c] is
/// distance between points c0, c1, such that c0 = c / n; c1 = c % n.
/// ## k
/// Number of centers for quant_find_k_smallest to find
///
/// # Example
/// ```Q#
/// let graph = quantum_neighbourhood_graph(n, m, indices, k, distances);
/// ```
operation quantum_neighbourhood_graph (n : Int, m : Int, indices: Int[], k : Int, distances: Int[]) : Int[][] {
let N = PowI(2, n);
mutable graph = initSquareMatrix(N);
for (i in 0 .. N - 1) {
// find closest values for given value
let results = quant_find_k_smallest(N, m, indices, k, distances);
// iterate through closest values
for (j in 0 .. k - 1) {
set graph[i][results[j][0]] = distances[i*SqrtI(Length(distances)) + results[j][0]]; // create an edge weighted by the distance
set graph[results[j][0]][i] = distances[results[j][0]*SqrtI(Length(distances)) + i]; // the graph is stored as a symmetric matrix
}
}
return graph;
}
/// # Summary
/// Uses Neighbourhood Graph to calculate the sume of the distances
/// from every point to k centers, then marks points with a sum greater than w
/// as outliers and returns those marks
///
/// # Input
/// ## n
/// Number of qubits required to represent indices
/// ## m
/// Number of qubits required to represent distance between any 2 points
/// ## indices
/// Indices of datapoints over which to look for pair of points.
/// ## k
/// Number of centers for quant_find_k_smallest to find
/// ## w
/// threshold for distinguishing outliers
/// ## distances
/// Distances between two points where distances[c] is
/// distance between points c0, c1, such that c0 = c / n; c1 = c % n.
///
/// # Example
/// ```Q#
/// let outliers = quantum_detection_outlier (n, m, indices, k, w, distances);
/// ```
operation quantum_detection_outlier (n : Int, m : Int, indices: Int[], k : Int, w : Int, distances: Int[]) : Int[] {
let graph = quantum_neighbourhood_graph(n, m, indices, k, distances); // generate neighborhood graph
let N = PowI(2, n);
mutable outliers = new Int[N];
for (i in 0 .. N - 1) {
// sum distances associated with value
mutable sum = 0;
for (j in 0 .. k - 1) {
set sum = sum + graph[i][j];
}
// print distances
Message(ToStringI(sum));
// if distances are sufficiently large, it is an outlier
if (sum > w) {
set outliers[i] = 1;
}
}
return outliers;
}
}