Examples (clustering) - 5.2 English - 68552

AOCL API Guide (68552)

Document ID
68552
Release Date
2025-12-29
Version
5.2 English

The code below is supplied with your installation (see Python examples).

  1# Copyright (C) 2024-2025 Advanced Micro Devices, Inc. All rights reserved.
  2#
  3# Redistribution and use in source and binary forms, with or without modification,
  4# are permitted provided that the following conditions are met:
  5# 1. Redistributions of source code must retain the above copyright notice,
  6#    this list of conditions and the following disclaimer.
  7# 2. Redistributions in binary form must reproduce the above copyright notice,
  8#    this list of conditions and the following disclaimer in the documentation
  9#    and/or other materials provided with the distribution.
 10# 3. Neither the name of the copyright holder nor the names of its contributors
 11#    may be used to endorse or promote products derived from this software without
 12#    specific prior written permission.
 13#
 14# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 15# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 16# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 17# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 18# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 19# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 20# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 21# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 23# POSSIBILITY OF SUCH DAMAGE.
 24#
 25
 26"""
 27k-means clustering example Python script
 28"""
 29
 30import sys
 31import numpy as np
 32from aoclda.clustering import kmeans
 33
 34
 35def kmeans_example():
 36    """
 37    k-means clustering example
 38    """
 39
 40    # Define data arrays
 41    a = np.array([[2., 1.],
 42                  [-1., -2.],
 43                  [3., 2.],
 44                  [2., 3.],
 45                  [-3., -2.],
 46                  [-2., -1.],
 47                  [-2., -3.],
 48                  [1., 2.]])
 49
 50    c = np.array([[1., 1.],
 51                  [-3., -3.]])
 52
 53    x = np.array([[0., 1.],
 54                  [0., -1.]])
 55
 56    print("\nk-means clustering for a small data matrix\n")
 57    try:
 58        km = kmeans(n_clusters=2, C=c)
 59        km.fit(a)
 60        x_transform = km.transform(x)
 61        x_labels = km.predict(x)
 62    except RuntimeError:
 63        sys.exit(1)
 64
 65    # Print results
 66    print("\nComputed cluster centres:\n")
 67    print(km.cluster_centres)
 68    print("\nLabels for original data matrix:\n")
 69    print(km.labels)
 70    print("\nx_transform:\n")
 71    print(x_transform)
 72    print("\nx labels:\n")
 73    print(x_labels)
 74
 75    # Check against expected results
 76
 77    expected_centres = np.array([[2., 2.], [-2., -2.]])
 78    expected_labels = np.array([0, 1, 0, 0, 1, 1, 1, 0])
 79
 80    expected_x_transform = np.array([[2.23606797749979, 3.605551275463989],
 81                                     [3.605551275463989, 2.23606797749979]])
 82    expected_x_labels = np.array([0, 1])
 83
 84    norm_components = np.linalg.norm(
 85        km.cluster_centres - expected_centres)
 86    norm_x_transform = np.linalg.norm(x_transform - expected_x_transform)
 87
 88    incorrect_labels = np.any(
 89        expected_labels - km.labels) or np.any(expected_x_labels - x_labels)
 90
 91    tol = 1.0e-12
 92
 93    if norm_components > tol or norm_x_transform > tol or incorrect_labels:
 94        print("\nSolution is not within expected tolerance\n")
 95        sys.exit(1)
 96
 97    print("\nk-means clusters successfully computed\n")
 98
 99
100if __name__ == "__main__":
101    kmeans_example()
 1# Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved.
 2#
 3# Redistribution and use in source and binary forms, with or without modification,
 4# are permitted provided that the following conditions are met:
 5# 1. Redistributions of source code must retain the above copyright notice,
 6#    this list of conditions and the following disclaimer.
 7# 2. Redistributions in binary form must reproduce the above copyright notice,
 8#    this list of conditions and the following disclaimer in the documentation
 9#    and/or other materials provided with the distribution.
10# 3. Neither the name of the copyright holder nor the names of its contributors
11#    may be used to endorse or promote products derived from this software without
12#    specific prior written permission.
13#
14# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23# POSSIBILITY OF SUCH DAMAGE.
24#
25
26"""
27DBSCAN clustering example Python script
28"""
29
30import sys
31import numpy as np
32from aoclda.clustering import DBSCAN
33
34
35def dbscan_example():
36    """
37    DBSCAN clustering example
38    """
39
40    # Define data arrays
41    a = np.array([[2., 1.],
42                  [-1., -2.],
43                  [3., 2.],
44                  [2., 3.],
45                  [-3., -2.],
46                  [-2., -1.],
47                  [-2., -3.],
48                  [1., 2.],
49                  [2., 2.],
50                  [-2., -2.]])
51
52    print("\nDBSCAN clustering for a small data matrix\n")
53    try:
54        db = DBSCAN(eps=1.1, min_samples=4)
55        db.fit(a)
56    except RuntimeError:
57        sys.exit(1)
58
59    # Print results
60    print("\nLabels:\n")
61    print(db.labels)
62    print("\nCore sample indices:\n")
63    print(db.core_sample_indices)
64
65    # Check against expected results
66
67    expected_labels = np.array([0, 1, 0, 0, 1, 1, 1, 0, 0, 1])
68    expected_core_sample_indices = np.array([8, 9])
69
70    incorrect_results = np.any(expected_labels - db.labels) or np.any(
71        expected_core_sample_indices - db.core_sample_indices)
72
73    tol = 1.0e-12
74
75    if incorrect_results:
76        print("\nThe expected solution was not obtained\n")
77        sys.exit(1)
78
79    print("\nDBSCAN clusters successfully computed\n")
80
81
82if __name__ == "__main__":
83    dbscan_example()

The code below can be found in the examples folder of your installation.

  1/*
  2 * Copyright (C) 2024-2025 Advanced Micro Devices, Inc. All rights reserved.
  3 *
  4 * Redistribution and use in source and binary forms, with or without modification,
  5 * are permitted provided that the following conditions are met:
  6 * 1. Redistributions of source code must retain the above copyright notice,
  7 *    this list of conditions and the following disclaimer.
  8 * 2. Redistributions in binary form must reproduce the above copyright notice,
  9 *    this list of conditions and the following disclaimer in the documentation
 10 *    and/or other materials provided with the distribution.
 11 * 3. Neither the name of the copyright holder nor the names of its contributors
 12 *    may be used to endorse or promote products derived from this software without
 13 *    specific prior written permission.
 14 *
 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 18 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 21 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 24 * POSSIBILITY OF SUCH DAMAGE.
 25 *
 26 */
 27
 28#include "aoclda.h"
 29#include <iostream>
 30
 31/*
 32 * Basic k-means example
 33 *
 34 * This example computes k-means clustering for a small data matrix.
 35 */
 36
 37int main() {
 38
 39    // Initialize the handle
 40    da_handle handle = nullptr;
 41
 42    std::cout << "-----------------------------------------------------------------------"
 43              << std::endl;
 44    std::cout << "Basic k-means" << std::endl;
 45    std::cout << "k-means clustering for a small data matrix" << std::endl << std::endl;
 46    std::cout << std::fixed;
 47    std::cout.precision(5);
 48
 49    int exit_code = 0;
 50    bool pass = true;
 51
 52    // Input data
 53    double A[16] = {2.0, -1.0, 3.0, 2.0, -3.0, -2.0, -2.0, 1.0,
 54                    1.0, -2.0, 2.0, 3.0, -2.0, -1.0, -3.0, 2.0};
 55    double C[4] = {1.0, -3.0, 1.0, -3.0};
 56
 57    da_int n_samples = 8, n_features = 2, n_clusters = 2, lda = 8, ldc = 2;
 58
 59    // Create the handle and pass it the data matrix
 60    pass = pass && (da_handle_init_d(&handle, da_handle_kmeans) == da_status_success);
 61
 62    // Set options
 63    pass = pass &&
 64           (da_options_set_int(handle, "n_clusters", n_clusters) == da_status_success);
 65    pass = pass && (da_options_set_int(handle, "n_init", 1) == da_status_success);
 66    pass = pass && (da_options_set_string(handle, "initialization method", "supplied") ==
 67                    da_status_success);
 68
 69    // Set the data matrix
 70    pass = pass && (da_kmeans_set_data_d(handle, n_samples, n_features, A, lda) ==
 71                    da_status_success);
 72
 73    // Set the initial cluster centres
 74    pass = pass && (da_kmeans_set_init_centres_d(handle, C, ldc) == da_status_success);
 75
 76    // Compute the clusters
 77    pass = pass && (da_kmeans_compute_d(handle) == da_status_success);
 78
 79    // Extract results from the handle
 80    da_int cluster_centres_dim = n_clusters * n_features;
 81    da_int labels_dim = n_samples;
 82    double *cluster_centres = new double[cluster_centres_dim];
 83    da_int *labels = new da_int[labels_dim];
 84
 85    pass = pass && (da_handle_get_result_d(handle, da_kmeans_cluster_centres,
 86                                           &cluster_centres_dim,
 87                                           cluster_centres) == da_status_success);
 88    pass = pass && (da_handle_get_result_int(handle, da_kmeans_labels, &labels_dim,
 89                                             labels) == da_status_success);
 90
 91    // Transform another data matrix into the cluster space and predict its labels
 92    double X[4] = {0.0, 0.0, 1.0, -1.0};
 93    da_int m_samples = 2, m_features = 2, ldx = 2, ldx_transform = 2;
 94    double *X_transform = new double[m_samples * n_clusters];
 95    da_int *X_labels = new da_int[m_samples];
 96    pass =
 97        pass && (da_kmeans_transform_d(handle, m_samples, m_features, X, ldx, X_transform,
 98                                       ldx_transform) == da_status_success);
 99
100    pass = pass && (da_kmeans_predict_d(handle, m_samples, m_features, X, ldx,
101                                        X_labels) == da_status_success);
102
103    // Check status (we could do this after every function call)
104    if (pass) {
105        std::cout << "k-means clustering computed successfully" << std::endl << std::endl;
106
107        std::cout << "Cluster centres:" << std::endl;
108        for (da_int j = 0; j < n_clusters; j++) {
109            for (da_int i = 0; i < n_features; i++) {
110                std::cout << cluster_centres[n_clusters * i + j] << "  ";
111            }
112            std::cout << std::endl;
113        }
114        std::cout << std::endl;
115
116        std::cout << "Labels:" << std::endl;
117        for (da_int i = 0; i < n_samples; i++) {
118            std::cout << labels[i] << "  ";
119        }
120        std::cout << std::endl;
121
122        // Check against expected results
123        double cluster_centres_exp[4] = {2.0, -2.0, 2.0, -2.0};
124        da_int labels_exp[8] = {0, 1, 0, 0, 1, 1, 1, 0};
125        double X_transform_exp[4] = {2.23606797749979, 3.605551275463989,
126                                     3.605551275463989, 2.23606797749979};
127        da_int X_labels_exp[2] = {0, 1};
128
129        double tol = 1.0e-14;
130        double err = 0.0;
131        for (da_int i = 0; i < cluster_centres_dim; i++)
132            err = std::max(err, std::abs(cluster_centres[i] - cluster_centres_exp[i]));
133        bool incorrect_labels = false;
134        for (da_int i = 0; i < labels_dim; i++) {
135            if (labels[i] != labels_exp[i]) {
136                incorrect_labels = true;
137                break;
138            }
139        }
140        for (da_int i = 0; i < m_samples * n_clusters; i++) {
141            err = std::max(err, std::abs(X_transform[i] - X_transform_exp[i]));
142            std::cout << X_transform[i] << " " << X_transform_exp[i] << std::endl;
143        }
144        for (da_int i = 0; i < m_samples; i++) {
145            if (X_labels[i] != X_labels_exp[i]) {
146                incorrect_labels = true;
147                break;
148            }
149        }
150        if (err > tol || incorrect_labels) {
151            std::cout << "Solution is not within the expected tolerance: " << err
152                      << std::endl;
153            exit_code = 1;
154        }
155    } else {
156        exit_code = 1;
157    }
158
159    // Clean up
160    da_handle_destroy(&handle);
161    delete[] cluster_centres;
162    delete[] labels;
163    delete[] X_transform;
164    delete[] X_labels;
165
166    std::cout << "-----------------------------------------------------------------------"
167              << std::endl;
168
169    return exit_code;
170}
  1/*
  2 * Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved.
  3 *
  4 * Redistribution and use in source and binary forms, with or without modification,
  5 * are permitted provided that the following conditions are met:
  6 * 1. Redistributions of source code must retain the above copyright notice,
  7 *    this list of conditions and the following disclaimer.
  8 * 2. Redistributions in binary form must reproduce the above copyright notice,
  9 *    this list of conditions and the following disclaimer in the documentation
 10 *    and/or other materials provided with the distribution.
 11 * 3. Neither the name of the copyright holder nor the names of its contributors
 12 *    may be used to endorse or promote products derived from this software without
 13 *    specific prior written permission.
 14 *
 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 18 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 21 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 24 * POSSIBILITY OF SUCH DAMAGE.
 25 *
 26 */
 27
 28#include "aoclda.h"
 29#include <iostream>
 30
 31/*
 32 * Basic DBSCAN example
 33 *
 34 * This example computes DBSCAN clustering for a small data matrix.
 35 */
 36
 37int main() {
 38
 39    // Initialize the handle
 40    da_handle handle = nullptr;
 41
 42    std::cout << "-----------------------------------------------------------------------"
 43              << std::endl;
 44    std::cout << "Basic DBSCAN" << std::endl;
 45    std::cout << "DBSCAN clustering for a small data matrix" << std::endl << std::endl;
 46    std::cout << std::fixed;
 47    std::cout.precision(5);
 48
 49    int exit_code = 0;
 50    bool pass = true;
 51
 52    // Input data
 53    double A[20] = {2.0, -1.0, 3.0, 2.0, -3.0, -2.0, -2.0, 1.0, 2.0, -2.0,
 54                    1.0, -2.0, 2.0, 3.0, -2.0, -1.0, -3.0, 2.0, 2.0, -2.0};
 55
 56    da_int n_samples = 10, n_features = 2, lda = 10, min_samples = 4;
 57    double eps = 1.1;
 58
 59    // Create the handle and pass it the data matrix
 60    pass = pass && (da_handle_init_d(&handle, da_handle_dbscan) == da_status_success);
 61    pass = pass && (da_dbscan_set_data_d(handle, n_samples, n_features, A, lda) ==
 62                    da_status_success);
 63
 64    // Set options
 65    pass = pass &&
 66           (da_options_set_int(handle, "min samples", min_samples) == da_status_success);
 67    pass = pass && (da_options_set_real_d(handle, "eps", eps) == da_status_success);
 68
 69    // Compute the clusters
 70    pass = pass && (da_dbscan_compute_d(handle) == da_status_success);
 71
 72    // Extract results from the handle
 73    da_int n_clusters = 0, n_core_samples = 0, dim = 1;
 74
 75    pass = pass && (da_handle_get_result_int(handle, da_dbscan_n_clusters, &dim,
 76                                             &n_clusters) == da_status_success);
 77    pass = pass && (da_handle_get_result_int(handle, da_dbscan_n_core_samples, &dim,
 78                                             &n_core_samples) == da_status_success);
 79
 80    da_int *labels = new da_int[n_samples];
 81    da_int *core_sample_indices = new da_int[n_core_samples];
 82
 83    pass = pass && (da_handle_get_result_int(handle, da_dbscan_labels, &n_samples,
 84                                             labels) == da_status_success);
 85    pass = pass && (da_handle_get_result_int(handle, da_dbscan_core_sample_indices,
 86                                             &n_core_samples,
 87                                             core_sample_indices) == da_status_success);
 88
 89    // Check status (we could do this after every function call)
 90    if (pass) {
 91        std::cout << "DBSCAN clustering computed successfully" << std::endl << std::endl;
 92
 93        std::cout << "Labels:" << std::endl;
 94        for (da_int i = 0; i < n_samples; i++) {
 95            std::cout << labels[i] << "  ";
 96        }
 97        std::cout << std::endl;
 98
 99        std::cout << "Core samples:" << std::endl;
100        for (da_int i = 0; i < n_core_samples; i++) {
101            std::cout << core_sample_indices[i] << "  ";
102        }
103        std::cout << std::endl;
104
105        // Check against expected results
106        da_int labels_exp[10] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1};
107        da_int core_sample_indices_exp[2] = {8, 9};
108
109        bool incorrect_results = false;
110        for (da_int i = 0; i < n_samples; i++) {
111            if (labels[i] != labels_exp[i]) {
112                incorrect_results = true;
113                break;
114            }
115        }
116
117        for (da_int i = 0; i < n_core_samples; i++) {
118            if (core_sample_indices[i] != core_sample_indices_exp[i]) {
119                incorrect_results = true;
120                break;
121            }
122        }
123
124        if (incorrect_results) {
125            std::cout << "The expected solution was not obtained." << std::endl;
126            exit_code = 1;
127        }
128    } else {
129        exit_code = 1;
130    }
131
132    // Clean up
133    da_handle_destroy(&handle);
134    delete[] labels;
135    delete[] core_sample_indices;
136
137    std::cout << "-----------------------------------------------------------------------"
138              << std::endl;
139
140    return exit_code;
141}