All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ojalgo.data.cluster.Point Maven / Gradle / Ivy

Go to download

oj! Algorithms - ojAlgo - is Open Source Java code that has to do with mathematics, linear algebra and optimisation.

The newest version!
package org.ojalgo.data.cluster;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;

import org.ojalgo.function.constant.PrimitiveMath;

public final class Point implements Comparable {

    /**
     * Primarily used when constructing test cases and similar. For real world applications you should
     * probably use {@link Point#convert(List, Function)} instead.
     */
    public static final class Factory {

        private final int myDimensions;
        private final AtomicInteger myNextID = new AtomicInteger();

        public Factory(final int dimensions) {
            super();
            myDimensions = dimensions;
        }

        public Point newPoint(final float... coordinates) {
            if (coordinates.length != myDimensions) {
                throw new IllegalArgumentException();
            }
            return new Point(myNextID.getAndIncrement(), coordinates);
        }

        public void reset() {
            myNextID.set(0);
        }

    }

    /**
     * Essentially works like this:
     * 
    *
  1. Calculate, and store, distances between all the points (to enable statistical analysis, and speed * up the following steps) *
  2. Perform statistical analysis of the distances to determine a suitable distance threshold for greedy * clustering *
  3. Perform greedy clustering to get an initial set of centroids *
  4. Filter out centroids/clusters corresponding to extremely small clusters (This determines the 'k') *
  5. Perform k-means clustering to refine the clusters and centroids *
*/ public static List> cluster(final Collection input) { PointDistanceCache cache = new PointDistanceCache(); cache.setup(input, Point::distance); GeneralisedKMeans clusterar = new GeneralisedKMeans<>(cache::initialiser, cache::centroid, cache::distance); return clusterar.cluster(input); } /** * Converts a list of objects to a list of points using the provided converter to derive the coordinates. * There will be one point for each object in the input list, at matching positions. Further the point id * will be the index of the object in the input list. * * @param The type of the objects in the input list * @param input The list of objects to convert * @param converter The function to convert the objects to coordinates * @return A list of points */ public static List convert(final List input, final Function converter) { int size = input.size(); List points = new ArrayList<>(size); for (int i = 0; i < size; i++) { points.add(new Point(i, converter.apply(input.get(i)))); } return points; } public static Point mean(final Collection points) { double[] sum = null; int length = 0; for (Point point : points) { if (sum == null) { length = point.coordinates.length; sum = new double[length]; } for (int i = 0; i < length; i++) { sum[i] += point.coordinates[i]; } } float[] retVal = new float[length]; for (int i = 0; i < length; i++) { retVal[i] = (float) (sum[i] / points.size()); } return new Point(-1, retVal); } public static Point.Factory newFactory(final int dimensions) { return new Point.Factory(dimensions); } /** * Greedy algorithm. The distance measurement is the same as for k-means ({@link #distance(Point)}) and * the threshold must match that. */ public static ClusteringAlgorithm newGreedyClusterer(final double distanceThreshold) { return new GreedyClustering<>(Point::mean, Point::distance, distanceThreshold); } /** * Standard k-means clustering */ public static ClusteringAlgorithm newKMeansClusterer(final int k) { RandomClustering initialiser = new RandomClustering<>(k); return new GeneralisedKMeans<>(initialiser::centroids, Point::mean, Point::distance); } public static Point of(final int id, final float... coordinates) { return new Point(id, coordinates); } public final float[] coordinates; public final int id; Point(final int id, final float[] coordinates) { super(); this.id = id; this.coordinates = coordinates; } @Override public int compareTo(final Point ref) { return Integer.compare(id, ref.id); } /** * The sum of the squared differences between the coordinates of this and the other point. (Not the * Euclidean distance. This is the squared Euclidean distance.) */ public double distance(final Point other) { double retVal = PrimitiveMath.ZERO; int limit = Math.min(coordinates.length, other.coordinates.length); float diff; for (int i = 0; i < limit; i++) { diff = coordinates[i] - other.coordinates[i]; retVal += diff * diff; } return retVal; } @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (!(obj instanceof Point)) { return false; } Point other = (Point) obj; if (id != other.id || !Arrays.equals(coordinates, other.coordinates)) { return false; } return true; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + id; result = prime * result + Arrays.hashCode(coordinates); return result; } @Override public String toString() { return Arrays.toString(coordinates); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy