Package de.lmu.ifi.dbs.elki.utilities

Source Code of de.lmu.ifi.dbs.elki.utilities.Util$ForwardComparator

package de.lmu.ifi.dbs.elki.utilities;

/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures

Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

import gnu.trove.map.hash.TIntFloatHashMap;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.StringTokenizer;

import de.lmu.ifi.dbs.elki.data.DoubleVector;
import de.lmu.ifi.dbs.elki.data.SparseFloatVector;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil;

/**
* This class collects various static helper methods.
*
* For helper methods related to special application fields see other utilities
* classes.
*
*
* @see de.lmu.ifi.dbs.elki.utilities
*/
public final class Util {
  /**
   * Returns a new double array containing the same objects as are contained in
   * the given array.
   *
   * @param array an array to copy
   * @return the copied array
   */
  public static double[] copy(double[] array) {
    double[] copy = new double[array.length];
    System.arraycopy(array, 0, copy, 0, array.length);
    return copy;
  }

  /**
   * Returns a new <code>Double</code> array initialized to the values
   * represented by the specified <code>String</code> and separated by comma, as
   * performed by the <code>valueOf</code> method of class <code>Double</code>.
   *
   * @param s the string to be parsed.
   * @return a new <code>Double</code> array represented by s
   */
  public static double[] parseDoubles(String s) {
    List<Double> result = new ArrayList<Double>();
    StringTokenizer tokenizer = new StringTokenizer(s, ",");
    while(tokenizer.hasMoreTokens()) {
      String d = tokenizer.nextToken();
      result.add(Double.parseDouble(d));
    }
    return ArrayLikeUtil.toPrimitiveDoubleArray(result);
  }

  /**
   * Prints the given list to the specified PrintStream. The list entries are
   * separated by the specified separator. The last entry is not followed by a
   * separator. Thus, if a newline is used as separator, it might make sense to
   * print a newline to the PrintStream after calling this method.
   *
   * @param <O> object class
   * @param list the list to be printed
   * @param separator the separator to separate entries of the list
   * @param out the target PrintStream
   */
  public static <O> void print(List<O> list, String separator, PrintStream out) {
    for(Iterator<O> iter = list.iterator(); iter.hasNext();) {
      out.print(iter.next());
      if(iter.hasNext()) {
        out.print(separator);
      }
    }
  }

  /**
   * Creates a new BitSet of fixed cardinality with randomly set bits.
   *
   * @param cardinality the cardinality of the BitSet to create
   * @param capacity the capacity of the BitSet to create - the randomly
   *        generated indices of the bits set to true will be uniformly
   *        distributed between 0 (inclusive) and capacity (exclusive)
   * @param random a Random Object to create the sequence of indices set to true
   *        - the same number occurring twice or more is ignored but the already
   *        selected bit remains true
   * @return a new BitSet with randomly set bits
   */
  public static BitSet randomBitSet(int cardinality, int capacity, Random random) {
    assert (cardinality >= 0) : "Cannot set a negative number of bits!";
    assert (cardinality < capacity) : "Cannot set " + cardinality + " of " + capacity + " bits!";
    BitSet bitset = new BitSet(capacity);
    if(cardinality < capacity >>> 1) {
      while(bitset.cardinality() < cardinality) {
        bitset.set(random.nextInt(capacity));
      }
    }
    else {
      bitset.flip(0, capacity);
      while(bitset.cardinality() > cardinality) {
        bitset.clear(random.nextInt(capacity));
      }
    }
    return bitset;
  }

  /**
   * Provides a new DoubleVector as a projection on the specified attributes.
   *
   * If the given DoubleVector has already an ID not <code>null</code>, the same
   * ID is set in the returned new DoubleVector. Nevertheless, the returned
   * DoubleVector is not backed by the given DoubleVector, i.e., any changes
   * affecting <code>v</code> after calling this method will not affect the
   * newly returned DoubleVector.
   *
   * @param v a DoubleVector to project
   * @param selectedAttributes the attributes selected for projection
   * @return a new DoubleVector as a projection on the specified attributes
   * @throws IllegalArgumentException if the given selected attributes specify
   *         an attribute as selected which is out of range for the given
   *         DoubleVector.
   * @see DoubleVector#doubleValue(int)
   */
  public static DoubleVector project(DoubleVector v, BitSet selectedAttributes) {
    double[] newAttributes = new double[selectedAttributes.cardinality()];
    int i = 0;
    for(int d = selectedAttributes.nextSetBit(0); d >= 0; d = selectedAttributes.nextSetBit(d + 1)) {
      newAttributes[i] = v.doubleValue(d + 1);
      i++;
    }
    DoubleVector projectedVector = new DoubleVector(newAttributes);
    return projectedVector;
  }

  /**
   * Provides a new SparseFloatVector as a projection on the specified
   * attributes.
   *
   * If the given SparseFloatVector has already an ID not <code>null</code>, the
   * same ID is set in the returned new SparseFloatVector. Nevertheless, the
   * returned SparseFloatVector is not backed by the given SparseFloatVector,
   * i.e., any changes affecting <code>v</code> after calling this method will
   * not affect the newly returned SparseFloatVector.
   *
   * @param v a SparseFloatVector to project
   * @param selectedAttributes the attributes selected for projection
   * @return a new SparseFloatVector as a projection on the specified attributes
   * @throws IllegalArgumentException if the given selected attributes specify
   *         an attribute as selected which is out of range for the given
   *         SparseFloatVector.
   */
  public static SparseFloatVector project(SparseFloatVector v, BitSet selectedAttributes) {
    TIntFloatHashMap values = new TIntFloatHashMap(selectedAttributes.cardinality(), 1);
    for(int d = selectedAttributes.nextSetBit(0); d >= 0; d = selectedAttributes.nextSetBit(d + 1)) {
      if(v.getValue(d + 1) != 0.0f) {
        values.put(d, v.getValue(d + 1));
      }
    }
    SparseFloatVector projectedVector = new SparseFloatVector(values, selectedAttributes.cardinality());
    return projectedVector;
  }

  /**
   * Mix multiple hashcodes into one.
   *
   * @param hash Hashcodes to mix
   * @return Mixed hash code
   */
  public static final int mixHashCodes(int... hash) {
    final long prime = 2654435761L;
    if(hash.length == 0) {
      return 0;
    }
    long result = hash[0];
    for(int i = 1; i < hash.length; i++) {
      result = result * prime + hash[i];
    }
    return (int) result;
  }

  /**
   * Static instance
   */
  private static final Comparator<?> FORWARD = new ForwardComparator();

  /**
   * Regular comparator. See {@link java.util.Collections#reverseOrder()} for a
   * reverse comparator.
   *
   * @author Erich Schubert
   *
   * @apiviz.exclude
   */
  private static final class ForwardComparator implements Comparator<Comparable<Object>> {
    @Override
    public int compare(Comparable<Object> o1, Comparable<Object> o2) {
      return o1.compareTo(o2);
    }
  }

  /**
   * Compare two objects, forward. See
   * {@link java.util.Collections#reverseOrder()} for a reverse comparator.
   *
   * @return Forward comparator
   */
  @SuppressWarnings("unchecked")
  public static final <T> Comparator<T> forwardOrder() {
    return (Comparator<T>) FORWARD;
  }
}
TOP

Related Classes of de.lmu.ifi.dbs.elki.utilities.Util$ForwardComparator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.