2009-03-12 04:58:01 +08:00
|
|
|
package org.broadinstitute.sting.utils;
|
2009-02-27 05:50:29 +08:00
|
|
|
|
2009-06-05 16:48:34 +08:00
|
|
|
import net.sf.samtools.*;
|
2009-05-12 06:45:11 +08:00
|
|
|
import net.sf.samtools.util.StringUtil;
|
2009-10-23 14:31:15 +08:00
|
|
|
import org.apache.log4j.Logger;
|
2009-02-27 05:50:29 +08:00
|
|
|
|
2009-03-25 23:17:38 +08:00
|
|
|
import java.io.File;
|
2009-10-23 14:31:15 +08:00
|
|
|
import java.util.*;
|
2009-03-27 22:02:55 +08:00
|
|
|
|
2009-02-27 05:50:29 +08:00
|
|
|
/**
|
|
|
|
|
* Created by IntelliJ IDEA.
|
|
|
|
|
* User: depristo
|
|
|
|
|
* Date: Feb 24, 2009
|
|
|
|
|
* Time: 10:12:31 AM
|
|
|
|
|
* To change this template use File | Settings | File Templates.
|
|
|
|
|
*/
|
|
|
|
|
public class Utils {
|
2009-10-23 14:31:15 +08:00
|
|
|
/** our log, which we want to capture anything from this class */
|
2009-06-05 23:02:17 +08:00
|
|
|
private static Logger logger = Logger.getLogger(Utils.class);
|
2009-03-27 22:02:55 +08:00
|
|
|
|
2009-03-17 07:22:04 +08:00
|
|
|
public static void warnUser(final String msg) {
|
2009-03-29 04:37:27 +08:00
|
|
|
logger.warn(String.format("********************************************************************************"));
|
|
|
|
|
logger.warn(String.format("* WARNING:"));
|
|
|
|
|
logger.warn(String.format("*"));
|
2009-06-05 23:49:03 +08:00
|
|
|
prettyPrintWarningMessage(msg);
|
2009-03-29 04:37:27 +08:00
|
|
|
logger.warn(String.format("********************************************************************************"));
|
2009-03-17 07:22:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void scareUser(final String msg) {
|
2009-04-15 06:13:10 +08:00
|
|
|
//System.out.printf("********************************************************************************%n");
|
|
|
|
|
//System.out.printf("* ERROR:%n");
|
|
|
|
|
//System.out.printf("*%n");
|
|
|
|
|
//System.out.printf("* %s%n", msg);
|
|
|
|
|
//System.out.printf("********************************************************************************%n");
|
2009-04-08 06:19:54 +08:00
|
|
|
logger.fatal(msg);
|
2009-07-14 04:42:12 +08:00
|
|
|
throw new StingException(msg);
|
2009-03-17 07:22:04 +08:00
|
|
|
}
|
|
|
|
|
|
2009-08-23 08:56:02 +08:00
|
|
|
/**
|
|
|
|
|
* Compares two objects, either of which might be null.
|
2009-10-23 14:31:15 +08:00
|
|
|
*
|
2009-08-23 08:56:02 +08:00
|
|
|
* @param lhs One object to compare.
|
|
|
|
|
* @param rhs The other object to compare.
|
2009-10-23 14:31:15 +08:00
|
|
|
*
|
2009-08-23 08:56:02 +08:00
|
|
|
* @return True if the two objects are equal, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
public static boolean equals(Object lhs, Object rhs) {
|
2009-10-23 14:31:15 +08:00
|
|
|
if (lhs == null && rhs == null) return true;
|
|
|
|
|
else if (lhs == null) return false;
|
2009-08-23 08:56:02 +08:00
|
|
|
else return lhs.equals(rhs);
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-06 07:34:37 +08:00
|
|
|
public static <T> List<T> cons(final T elt, final List<T> l) {
|
|
|
|
|
List<T> l2 = new ArrayList<T>();
|
|
|
|
|
l2.add(elt);
|
2009-10-23 14:31:15 +08:00
|
|
|
if (l != null) l2.addAll(l);
|
2009-06-06 07:34:37 +08:00
|
|
|
return l2;
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-05 23:49:03 +08:00
|
|
|
/**
|
|
|
|
|
* pretty print the warning message supplied
|
2009-10-23 14:31:15 +08:00
|
|
|
*
|
2009-06-05 23:49:03 +08:00
|
|
|
* @param message the message
|
|
|
|
|
*/
|
|
|
|
|
private static void prettyPrintWarningMessage(String message) {
|
|
|
|
|
StringBuilder builder = new StringBuilder(message);
|
|
|
|
|
while (builder.length() > 70) {
|
|
|
|
|
int space = builder.lastIndexOf(" ", 70);
|
|
|
|
|
if (space <= 0) space = 70;
|
2009-10-23 14:31:15 +08:00
|
|
|
logger.warn(String.format("* %s", builder.substring(0, space)));
|
|
|
|
|
builder.delete(0, space + 1);
|
2009-06-05 23:49:03 +08:00
|
|
|
}
|
|
|
|
|
logger.warn(String.format("* %s", builder));
|
|
|
|
|
}
|
|
|
|
|
|
2009-10-23 14:31:15 +08:00
|
|
|
public static SAMFileHeader copySAMFileHeader(SAMFileHeader toCopy) {
|
2009-07-02 20:55:51 +08:00
|
|
|
SAMFileHeader copy = new SAMFileHeader();
|
|
|
|
|
|
|
|
|
|
copy.setSortOrder(toCopy.getSortOrder());
|
|
|
|
|
copy.setGroupOrder(toCopy.getGroupOrder());
|
|
|
|
|
copy.setProgramRecords(toCopy.getProgramRecords());
|
|
|
|
|
copy.setReadGroups(toCopy.getReadGroups());
|
|
|
|
|
copy.setSequenceDictionary(toCopy.getSequenceDictionary());
|
|
|
|
|
|
2009-10-23 14:31:15 +08:00
|
|
|
for (Map.Entry<String, Object> e : toCopy.getAttributes())
|
2009-07-02 20:55:51 +08:00
|
|
|
copy.setAttribute(e.getKey(), e.getValue());
|
2009-10-23 14:31:15 +08:00
|
|
|
|
2009-07-02 20:55:51 +08:00
|
|
|
return copy;
|
|
|
|
|
}
|
2009-06-05 23:49:03 +08:00
|
|
|
|
2009-06-05 16:48:34 +08:00
|
|
|
public static SAMFileWriter createSAMFileWriterWithCompression(SAMFileHeader header, boolean presorted, String file, int compression) {
|
|
|
|
|
if (file.endsWith(".bam"))
|
|
|
|
|
return new SAMFileWriterFactory().makeBAMWriter(header, presorted, new File(file), compression);
|
|
|
|
|
return new SAMFileWriterFactory().makeSAMOrBAMWriter(header, presorted, new File(file));
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-27 22:02:55 +08:00
|
|
|
/**
|
|
|
|
|
* Returns a new list built from those objects found in collection <c> that satisfy the
|
2009-03-18 03:06:40 +08:00
|
|
|
* predicate ( i.e. pred.apply() is true for the objects in th eresulting list ).
|
2009-03-27 22:02:55 +08:00
|
|
|
*
|
|
|
|
|
* @param pred filtering condition ( objects, for which pred.apply() is true pass the filter )
|
|
|
|
|
* @param c collection to filter (will not be modified)
|
2009-10-23 14:31:15 +08:00
|
|
|
*
|
2009-03-27 22:02:55 +08:00
|
|
|
* @return new list built from elements of <c> passing the filter
|
2009-03-18 03:06:40 +08:00
|
|
|
* @see #filterInPlace(Predicate pred, Collection c)
|
|
|
|
|
*/
|
2009-04-17 23:15:21 +08:00
|
|
|
public static <T> List<T> filter(Predicate<? super T> pred, Collection<T> c) {
|
2009-02-27 05:50:29 +08:00
|
|
|
List<T> filtered = new ArrayList<T>();
|
|
|
|
|
// loop through all the elements in c
|
|
|
|
|
for (T obj : c) {
|
|
|
|
|
// if the predicate is true for the current element
|
|
|
|
|
if (pred.apply(obj)) {
|
|
|
|
|
// append it to the result list
|
|
|
|
|
filtered.add(obj);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return filtered;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-27 22:02:55 +08:00
|
|
|
/**
|
|
|
|
|
* Removes from the collection <c> all the elements that do not pass the filter (i.e. those elements,
|
2009-03-18 03:06:40 +08:00
|
|
|
* for which pred.apply() is false ). This is an in-place method - the argument is modified, and no new
|
|
|
|
|
* objects are created/copied. Collection's iterator (as returned by iterator()) must implement
|
|
|
|
|
* optional remove() interface method that allows multiple subsequent removals of elements from the
|
|
|
|
|
* underlying collection (this is the standard contract). This method
|
|
|
|
|
* works best for collections that support cheap, constant time
|
|
|
|
|
* object removal (such as LinkedList, HashSet etc.). It is also specifically designed to
|
|
|
|
|
* detect ArrayLists and use optimized strategy for them. However
|
|
|
|
|
* with other, custom lists that 1) do not inherit (are not instanceof) from ArrayList and 2) do not implement
|
|
|
|
|
* fast (constant time) remove() operation, the performance can degrade significantly (linear traversal times,
|
|
|
|
|
* e.g., linear removal ~ N^2).
|
2009-03-27 22:02:55 +08:00
|
|
|
*
|
2009-03-18 03:06:40 +08:00
|
|
|
* @param pred filtering condition (only elements, for which pred.apply() is true will be kept in the collection)
|
2009-03-27 22:02:55 +08:00
|
|
|
* @param c collection to filter (will be modified - should be mutable and should implement remove() )
|
2009-10-23 14:31:15 +08:00
|
|
|
*
|
2009-03-18 03:06:40 +08:00
|
|
|
* @return reference to the same (modified) collection <c>
|
|
|
|
|
* @see #filter(Predicate pred, Collection c)
|
|
|
|
|
*/
|
2009-04-17 23:15:21 +08:00
|
|
|
public static <T> Collection<T> filterInPlace(Predicate<? super T> pred, Collection<T> c) {
|
2009-03-27 22:02:55 +08:00
|
|
|
if (c instanceof ArrayList) {
|
2009-03-18 03:06:40 +08:00
|
|
|
// arraylists are a special case that we know how to process efficiently
|
|
|
|
|
// (generic implementation below removes one element at a time and is not well suited
|
|
|
|
|
// for ArrayLists
|
2009-03-27 22:02:55 +08:00
|
|
|
List<T> list = (List<T>) c;
|
2009-03-18 03:06:40 +08:00
|
|
|
int j = 0; // copy-to location
|
|
|
|
|
// perform one linear pass copying forward all elements that pass the filter,
|
|
|
|
|
// so that the head of the list is continuous sequence of such elements:
|
2009-03-27 22:02:55 +08:00
|
|
|
for (int i = 0; i < list.size(); i++) {
|
2009-03-18 03:06:40 +08:00
|
|
|
// if object passes, copy it forward and increment j (=copy-to location);
|
|
|
|
|
// otherwise keep the same copy-to location and move on to the next element
|
2009-03-27 22:02:55 +08:00
|
|
|
if (pred.apply(list.get(i))) list.set(j++, list.get(i));
|
2009-03-18 03:06:40 +08:00
|
|
|
}
|
|
|
|
|
// j now points to first unused copy-to location; elements 0...j-1 pass the filter
|
2009-03-27 22:02:55 +08:00
|
|
|
list.subList(j, list.size()).clear(); // remove tail of the list
|
2009-03-18 03:06:40 +08:00
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
// loop through all the elements in c
|
|
|
|
|
for (T obj : c) {
|
|
|
|
|
// if the predicate is false for the current element
|
|
|
|
|
if (! pred.apply(obj)) {
|
|
|
|
|
// remove that element from the collection
|
|
|
|
|
c.remove(obj);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
Iterator<T> it = c.iterator();
|
2009-03-27 22:02:55 +08:00
|
|
|
while (it.hasNext()) {
|
|
|
|
|
if (pred.apply(it.next())) continue;
|
2009-03-18 03:06:40 +08:00
|
|
|
it.remove();
|
|
|
|
|
}
|
|
|
|
|
return c;
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-12 06:45:11 +08:00
|
|
|
public static ArrayList<Byte> subseq(char[] fullArray) {
|
|
|
|
|
byte[] fullByteArray = new byte[fullArray.length];
|
2009-10-23 14:31:15 +08:00
|
|
|
StringUtil.charsToBytes(fullArray, 0, fullArray.length, fullByteArray, 0);
|
2009-05-12 06:45:11 +08:00
|
|
|
return subseq(fullByteArray);
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-16 22:46:19 +08:00
|
|
|
public static ArrayList<Byte> subseq(byte[] fullArray) {
|
2009-10-23 14:31:15 +08:00
|
|
|
return subseq(fullArray, 0, fullArray.length - 1);
|
2009-03-16 22:46:19 +08:00
|
|
|
}
|
2009-03-27 22:02:55 +08:00
|
|
|
|
2009-03-16 22:46:19 +08:00
|
|
|
public static ArrayList<Byte> subseq(byte[] fullArray, int start, int end) {
|
2009-04-06 11:51:35 +08:00
|
|
|
assert end < fullArray.length;
|
2009-03-27 22:02:55 +08:00
|
|
|
ArrayList<Byte> dest = new ArrayList<Byte>(end - start + 1);
|
2009-05-12 06:45:11 +08:00
|
|
|
for (int i = start; i <= end; i++) {
|
2009-03-16 22:46:19 +08:00
|
|
|
dest.add(fullArray[i]);
|
|
|
|
|
}
|
|
|
|
|
return dest;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static String baseList2string(List<Byte> bases) {
|
|
|
|
|
byte[] basesAsbytes = new byte[bases.size()];
|
|
|
|
|
int i = 0;
|
2009-03-27 22:02:55 +08:00
|
|
|
for (Byte b : bases) {
|
2009-03-16 22:46:19 +08:00
|
|
|
basesAsbytes[i] = b;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
return new String(basesAsbytes);
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-24 03:53:51 +08:00
|
|
|
public static boolean is454Read(SAMRecord read) {
|
2009-10-15 03:27:40 +08:00
|
|
|
SAMReadGroupRecord readGroup = read.getReadGroup();
|
2009-10-23 14:31:15 +08:00
|
|
|
if (readGroup != null) {
|
2009-06-25 23:09:53 +08:00
|
|
|
Object readPlatformAttr = readGroup.getAttribute("PL");
|
2009-10-23 14:31:15 +08:00
|
|
|
if (readPlatformAttr != null)
|
2009-06-25 23:09:53 +08:00
|
|
|
return readPlatformAttr.toString().toUpperCase().contains("454");
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-27 22:02:55 +08:00
|
|
|
private static final Map<Integer, String> readFlagNames
|
|
|
|
|
= new HashMap<Integer, String>();
|
|
|
|
|
|
|
|
|
|
static {
|
|
|
|
|
readFlagNames.put(0x1, "Paired");
|
|
|
|
|
readFlagNames.put(0x2, "Proper");
|
|
|
|
|
readFlagNames.put(0x4, "Unmapped");
|
|
|
|
|
readFlagNames.put(0x8, "MateUnmapped");
|
|
|
|
|
readFlagNames.put(0x10, "Forward");
|
|
|
|
|
//readFlagNames.put(0x20, "MateForward");
|
|
|
|
|
readFlagNames.put(0x4, "FirstOfPair");
|
|
|
|
|
readFlagNames.put(0x8, "SecondOfPair");
|
|
|
|
|
readFlagNames.put(0x100, "NotPrimary");
|
|
|
|
|
readFlagNames.put(0x200, "NON-PF");
|
|
|
|
|
readFlagNames.put(0x400, "Duplicate");
|
|
|
|
|
}
|
2009-02-27 05:50:29 +08:00
|
|
|
|
|
|
|
|
public static String readFlagsAsString(SAMRecord rec) {
|
|
|
|
|
String flags = "";
|
2009-03-27 22:02:55 +08:00
|
|
|
for (int flag : readFlagNames.keySet()) {
|
|
|
|
|
if ((rec.getFlags() & flag) != 0) {
|
2009-02-27 05:50:29 +08:00
|
|
|
flags += readFlagNames.get(flag) + " ";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return flags;
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-28 01:07:57 +08:00
|
|
|
public static String join(String separator, String[] strings) {
|
2009-04-02 06:54:38 +08:00
|
|
|
return join(separator, strings, 0, strings.length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static String join(String separator, String[] strings, int start, int end) {
|
|
|
|
|
if ((end - start) == 0) {
|
2009-02-28 01:07:57 +08:00
|
|
|
return "";
|
|
|
|
|
}
|
2009-04-02 06:54:38 +08:00
|
|
|
StringBuilder ret = new StringBuilder(strings[start]);
|
2009-10-23 14:31:15 +08:00
|
|
|
for (int i = start + 1; i < end; ++i) {
|
2009-02-28 01:07:57 +08:00
|
|
|
ret.append(separator);
|
|
|
|
|
ret.append(strings[i]);
|
|
|
|
|
}
|
|
|
|
|
return ret.toString();
|
|
|
|
|
}
|
2009-03-03 02:18:48 +08:00
|
|
|
|
2009-03-13 07:30:19 +08:00
|
|
|
//public static String join(String separator, Collection<String> strings) {
|
|
|
|
|
// return join( separator, strings.toArray(new String[0]) );
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
public static <T> String join(String separator, Collection<T> objects) {
|
|
|
|
|
ArrayList<String> strs = new ArrayList<String>();
|
2009-03-27 22:02:55 +08:00
|
|
|
for (Object x : objects)
|
2009-03-13 07:30:19 +08:00
|
|
|
strs.add(x.toString());
|
2009-03-27 22:02:55 +08:00
|
|
|
return join(separator, strs.toArray(new String[0]));
|
2009-03-03 02:18:48 +08:00
|
|
|
}
|
|
|
|
|
|
2009-03-03 05:49:08 +08:00
|
|
|
public static double average(List<Long> vals, int maxI) {
|
|
|
|
|
long sum = 0L;
|
|
|
|
|
|
|
|
|
|
int i = 0;
|
2009-03-27 22:02:55 +08:00
|
|
|
for (long x : vals) {
|
|
|
|
|
if (i > maxI)
|
2009-03-03 05:49:08 +08:00
|
|
|
break;
|
|
|
|
|
sum += x;
|
|
|
|
|
i++;
|
2009-03-03 06:19:39 +08:00
|
|
|
//System.out.printf(" %d/%d", sum, i);
|
2009-03-03 05:49:08 +08:00
|
|
|
}
|
|
|
|
|
|
2009-03-03 06:19:39 +08:00
|
|
|
//System.out.printf("Sum = %d, n = %d, maxI = %d, avg = %f%n", sum, i, maxI, (1.0 * sum) / i);
|
2009-03-03 05:49:08 +08:00
|
|
|
|
|
|
|
|
return (1.0 * sum) / i;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-23 03:41:30 +08:00
|
|
|
public static double averageDouble(List<Double> vals, int maxI) {
|
|
|
|
|
double sum = 0.0;
|
|
|
|
|
|
|
|
|
|
int i = 0;
|
2009-03-27 22:02:55 +08:00
|
|
|
for (double x : vals) {
|
|
|
|
|
if (i > maxI)
|
2009-03-23 03:41:30 +08:00
|
|
|
break;
|
|
|
|
|
sum += x;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
return (1.0 * sum) / i;
|
2009-03-03 05:49:08 +08:00
|
|
|
}
|
2009-03-27 22:02:55 +08:00
|
|
|
|
|
|
|
|
public static double average(List<Long> vals) {
|
|
|
|
|
return average(vals, vals.size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static double averageDouble(List<Double> vals) {
|
|
|
|
|
return averageDouble(vals, vals.size());
|
|
|
|
|
}
|
2009-03-03 05:49:08 +08:00
|
|
|
|
2009-03-12 05:26:29 +08:00
|
|
|
// Java Generics can't do primitive types, so I had to do this the simplistic way
|
2009-03-27 22:02:55 +08:00
|
|
|
|
|
|
|
|
public static Integer[] SortPermutation(final int[] A) {
|
2009-04-17 23:15:21 +08:00
|
|
|
class comparator implements Comparator<Integer> {
|
|
|
|
|
public int compare(Integer a, Integer b) {
|
|
|
|
|
if (A[a.intValue()] < A[b.intValue()]) {
|
2009-03-27 22:02:55 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
2009-04-17 23:15:21 +08:00
|
|
|
if (A[a.intValue()] == A[b.intValue()]) {
|
2009-03-27 22:02:55 +08:00
|
|
|
return 0;
|
|
|
|
|
}
|
2009-04-17 23:15:21 +08:00
|
|
|
if (A[a.intValue()] > A[b.intValue()]) {
|
2009-03-27 22:02:55 +08:00
|
|
|
return 1;
|
|
|
|
|
}
|
2009-03-12 05:26:29 +08:00
|
|
|
return 0;
|
2009-03-27 22:02:55 +08:00
|
|
|
}
|
2009-03-12 05:26:29 +08:00
|
|
|
}
|
|
|
|
|
Integer[] permutation = new Integer[A.length];
|
2009-03-27 22:02:55 +08:00
|
|
|
for (int i = 0; i < A.length; i++) {
|
2009-03-12 05:26:29 +08:00
|
|
|
permutation[i] = i;
|
|
|
|
|
}
|
|
|
|
|
Arrays.sort(permutation, new comparator());
|
|
|
|
|
return permutation;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-27 22:02:55 +08:00
|
|
|
public static Integer[] SortPermutation(final double[] A) {
|
2009-04-17 23:15:21 +08:00
|
|
|
class comparator implements Comparator<Integer> {
|
|
|
|
|
public int compare(Integer a, Integer b) {
|
2009-10-23 14:31:15 +08:00
|
|
|
if (A[a.intValue()] < A[b.intValue()]) {
|
2009-03-27 22:02:55 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
2009-10-23 14:31:15 +08:00
|
|
|
if (A[a.intValue()] == A[b.intValue()]) {
|
2009-03-27 22:02:55 +08:00
|
|
|
return 0;
|
|
|
|
|
}
|
2009-10-23 14:31:15 +08:00
|
|
|
if (A[a.intValue()] > A[b.intValue()]) {
|
2009-03-27 22:02:55 +08:00
|
|
|
return 1;
|
|
|
|
|
}
|
2009-03-12 05:26:29 +08:00
|
|
|
return 0;
|
2009-03-27 22:02:55 +08:00
|
|
|
}
|
2009-03-12 05:26:29 +08:00
|
|
|
}
|
|
|
|
|
Integer[] permutation = new Integer[A.length];
|
2009-03-27 22:02:55 +08:00
|
|
|
for (int i = 0; i < A.length; i++) {
|
2009-03-12 05:26:29 +08:00
|
|
|
permutation[i] = i;
|
|
|
|
|
}
|
|
|
|
|
Arrays.sort(permutation, new comparator());
|
|
|
|
|
return permutation;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-27 22:02:55 +08:00
|
|
|
public static <T extends Comparable> Integer[] SortPermutation(List<T> A) {
|
2009-03-23 04:40:26 +08:00
|
|
|
final Object[] data = A.toArray();
|
|
|
|
|
|
2009-03-27 22:02:55 +08:00
|
|
|
class comparator implements Comparator<Integer> {
|
|
|
|
|
public int compare(Integer a, Integer b) {
|
|
|
|
|
return ((T) data[a]).compareTo(data[b]);
|
2009-03-23 04:40:26 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Integer[] permutation = new Integer[A.size()];
|
2009-03-27 22:02:55 +08:00
|
|
|
for (int i = 0; i < A.size(); i++) {
|
2009-03-23 04:40:26 +08:00
|
|
|
permutation[i] = i;
|
|
|
|
|
}
|
|
|
|
|
Arrays.sort(permutation, new comparator());
|
|
|
|
|
return permutation;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-03-27 22:02:55 +08:00
|
|
|
public static int[] PermuteArray(int[] array, Integer[] permutation) {
|
2009-03-12 05:26:29 +08:00
|
|
|
int[] output = new int[array.length];
|
2009-03-27 22:02:55 +08:00
|
|
|
for (int i = 0; i < output.length; i++) {
|
2009-03-12 05:26:29 +08:00
|
|
|
output[i] = array[permutation[i]];
|
|
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-27 22:02:55 +08:00
|
|
|
public static double[] PermuteArray(double[] array, Integer[] permutation) {
|
2009-03-12 05:26:29 +08:00
|
|
|
double[] output = new double[array.length];
|
2009-03-27 22:02:55 +08:00
|
|
|
for (int i = 0; i < output.length; i++) {
|
2009-03-12 05:26:29 +08:00
|
|
|
output[i] = array[permutation[i]];
|
|
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-27 22:02:55 +08:00
|
|
|
public static Object[] PermuteArray(Object[] array, Integer[] permutation) {
|
2009-03-12 05:26:29 +08:00
|
|
|
Object[] output = new Object[array.length];
|
2009-03-27 22:02:55 +08:00
|
|
|
for (int i = 0; i < output.length; i++) {
|
2009-03-12 05:26:29 +08:00
|
|
|
output[i] = array[permutation[i]];
|
|
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-27 22:02:55 +08:00
|
|
|
public static String[] PermuteArray(String[] array, Integer[] permutation) {
|
2009-03-12 05:26:29 +08:00
|
|
|
String[] output = new String[array.length];
|
2009-03-27 22:02:55 +08:00
|
|
|
for (int i = 0; i < output.length; i++) {
|
2009-03-12 05:26:29 +08:00
|
|
|
output[i] = array[permutation[i]];
|
|
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
2009-10-23 14:31:15 +08:00
|
|
|
public static <T> List<T> PermuteList(List<T> list, Integer[] permutation) {
|
2009-04-23 04:26:51 +08:00
|
|
|
List<T> output = new ArrayList<T>();
|
|
|
|
|
for (int i = 0; i < permutation.length; i++) {
|
|
|
|
|
output.add(list.get(permutation[i]));
|
|
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-18 03:06:40 +08:00
|
|
|
|
2009-04-13 20:14:53 +08:00
|
|
|
/** Draw N random elements from list. */
|
2009-10-23 14:31:15 +08:00
|
|
|
public static <T> List<T> RandomSubset(List<T> list, int N) {
|
|
|
|
|
if (list.size() <= N) {
|
|
|
|
|
return list;
|
|
|
|
|
}
|
2009-04-13 20:14:53 +08:00
|
|
|
|
|
|
|
|
java.util.Random random = new java.util.Random();
|
|
|
|
|
|
|
|
|
|
int idx[] = new int[list.size()];
|
2009-10-23 14:31:15 +08:00
|
|
|
for (int i = 0; i < list.size(); i++) {
|
|
|
|
|
idx[i] = random.nextInt();
|
|
|
|
|
}
|
2009-04-13 20:14:53 +08:00
|
|
|
|
2009-10-23 14:31:15 +08:00
|
|
|
Integer[] perm = SortPermutation(idx);
|
2009-04-13 20:14:53 +08:00
|
|
|
|
|
|
|
|
List<T> ans = new ArrayList<T>();
|
2009-10-23 14:31:15 +08:00
|
|
|
for (int i = 0; i < N; i++) {
|
|
|
|
|
ans.add(list.get(perm[i]));
|
|
|
|
|
}
|
2009-04-13 20:14:53 +08:00
|
|
|
|
|
|
|
|
return ans;
|
|
|
|
|
}
|
|
|
|
|
|
2009-04-19 23:35:07 +08:00
|
|
|
// lifted from the internet
|
|
|
|
|
// http://www.cs.princeton.edu/introcs/91float/Gamma.java.html
|
2009-10-23 14:31:15 +08:00
|
|
|
public static double logGamma(double x) {
|
|
|
|
|
double tmp = (x - 0.5) * Math.log(x + 4.5) - (x + 4.5);
|
|
|
|
|
double ser = 1.0 + 76.18009173 / (x + 0) - 86.50532033 / (x + 1)
|
|
|
|
|
+ 24.01409822 / (x + 2) - 1.231739516 / (x + 3)
|
|
|
|
|
+ 0.00120858003 / (x + 4) - 0.00000536382 / (x + 5);
|
|
|
|
|
return tmp + Math.log(ser * Math.sqrt(2 * Math.PI));
|
2009-04-19 23:35:07 +08:00
|
|
|
}
|
|
|
|
|
|
2009-10-23 14:31:15 +08:00
|
|
|
public static double percentage(double x, double base) {
|
|
|
|
|
return (base > 0 ? (x / base) * 100.0 : 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static double percentage(int x, int base) {
|
|
|
|
|
return (base > 0 ? ((double) x / (double) base) * 100.0 : 0);
|
|
|
|
|
}
|
2009-04-17 23:15:21 +08:00
|
|
|
|
2009-10-23 14:31:15 +08:00
|
|
|
public static double percentage(long x, long base) {
|
|
|
|
|
return (base > 0 ? ((double) x / (double) base) * 100.0 : 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static String dupString(char c, int nCopies) {
|
2009-05-22 06:23:52 +08:00
|
|
|
char[] chars = new char[nCopies];
|
2009-10-23 14:31:15 +08:00
|
|
|
Arrays.fill(chars, c);
|
2009-05-22 06:23:52 +08:00
|
|
|
return new String(chars);
|
|
|
|
|
}
|
2009-05-08 02:03:49 +08:00
|
|
|
|
2009-07-06 23:41:30 +08:00
|
|
|
public static int countOccurrences(char c, String s) {
|
2009-05-08 02:03:49 +08:00
|
|
|
int count = 0;
|
2009-10-23 14:31:15 +08:00
|
|
|
for (int i = 0; i < s.length(); i++) {
|
2009-05-08 02:03:49 +08:00
|
|
|
count += s.charAt(i) == c ? 1 : 0;
|
|
|
|
|
}
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-09 23:36:12 +08:00
|
|
|
public static <T> int countOccurrences(T x, List<T> l) {
|
|
|
|
|
int count = 0;
|
2009-10-23 14:31:15 +08:00
|
|
|
for (T y : l) {
|
|
|
|
|
if (x.equals(y)) count++;
|
2009-09-09 23:36:12 +08:00
|
|
|
}
|
2009-10-23 14:31:15 +08:00
|
|
|
|
2009-09-09 23:36:12 +08:00
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-08 02:03:49 +08:00
|
|
|
public static byte listMaxByte(List<Byte> quals) {
|
2009-10-23 14:31:15 +08:00
|
|
|
if (quals.size() == 0) return 0;
|
2009-05-08 02:03:49 +08:00
|
|
|
byte m = quals.get(0);
|
2009-10-23 14:31:15 +08:00
|
|
|
for (byte b : quals) {
|
2009-05-08 02:03:49 +08:00
|
|
|
m = b > m ? b : m;
|
|
|
|
|
}
|
|
|
|
|
return m;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-11-16 10:41:20 +08:00
|
|
|
// returns the maximum value in the array
|
|
|
|
|
public static double findMaxEntry(double[] array) {
|
|
|
|
|
return findIndexAndMaxEntry(array).first;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// returns the index of the maximum value in the array
|
|
|
|
|
public static int findIndexOfMaxEntry(double[] array) {
|
|
|
|
|
return findIndexAndMaxEntry(array).second;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// returns the the maximum value and its index in the array
|
|
|
|
|
private static Pair<Double, Integer> findIndexAndMaxEntry(double[] array) {
|
|
|
|
|
if ( array.length == 0 )
|
|
|
|
|
return new Pair<Double, Integer>(0.0, -1);
|
|
|
|
|
int index = 0;
|
|
|
|
|
double max = array[0];
|
|
|
|
|
for (int i = 1; i < array.length; i++) {
|
|
|
|
|
if ( array[i] > max ) {
|
|
|
|
|
max = array[i];
|
|
|
|
|
index = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return new Pair<Double, Integer>(max, index);
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-30 04:15:00 +08:00
|
|
|
/** Returns indices of all occurrences of the specified symbol in the string */
|
|
|
|
|
public static int[] indexOfAll(String s, int ch) {
|
2009-10-23 14:31:15 +08:00
|
|
|
int[] pos = new int[64];
|
|
|
|
|
int z = 0;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < s.length(); i++) {
|
|
|
|
|
if (s.charAt(i) == ch) pos[z++] = i;
|
|
|
|
|
}
|
|
|
|
|
return reallocate(pos, z);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns new (reallocated) integer array of the specified size, with content
|
2009-05-30 04:15:00 +08:00
|
|
|
* of the original array <code>orig</code> copied into it. If <code>newSize</code> is
|
|
|
|
|
* less than the size of the original array, only first <code>newSize</code> elements will be copied.
|
|
|
|
|
* If new size is greater than the size of the original array, the content of the original array will be padded
|
2009-10-23 14:31:15 +08:00
|
|
|
* with zeros up to the new size. Finally, if new size is the same as original size, no memory reallocation
|
|
|
|
|
* will be performed and the original array will be returned instead.
|
|
|
|
|
*
|
2009-05-30 04:15:00 +08:00
|
|
|
* @param orig
|
|
|
|
|
* @param newSize
|
2009-10-23 14:31:15 +08:00
|
|
|
*
|
2009-05-30 04:15:00 +08:00
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static int[] reallocate(int[] orig, int newSize) {
|
2009-10-23 14:31:15 +08:00
|
|
|
if (orig.length == newSize) return orig;
|
|
|
|
|
int[] new_array = new int[newSize];
|
|
|
|
|
int L = (newSize > orig.length ? orig.length : newSize);
|
|
|
|
|
for (int i = 0; i < L; i++) new_array[i] = orig[i];
|
|
|
|
|
return new_array;
|
2009-05-30 04:15:00 +08:00
|
|
|
}
|
2009-10-23 14:31:15 +08:00
|
|
|
|
2009-04-17 23:15:21 +08:00
|
|
|
/* TEST ME
|
2009-10-23 14:31:15 +08:00
|
|
|
public static void main(String[] argv) {
|
|
|
|
|
List<Integer> l1 = new LinkedList<Integer>();
|
|
|
|
|
List<Integer> l2 = new ArrayList<Integer>();
|
|
|
|
|
|
|
|
|
|
l1.add(1);
|
|
|
|
|
l1.add(5);
|
|
|
|
|
l1.add(3);
|
|
|
|
|
l1.add(10);
|
|
|
|
|
l1.add(4);
|
|
|
|
|
l1.add(2);
|
|
|
|
|
l2.add(1);
|
|
|
|
|
l2.add(5);
|
|
|
|
|
l2.add(3);
|
|
|
|
|
l2.add(10);
|
|
|
|
|
l2.add(4);
|
|
|
|
|
l2.add(2);
|
|
|
|
|
|
|
|
|
|
Predicate<Integer> p = new Predicate<Integer>() {
|
|
|
|
|
public boolean apply(Integer i) {
|
|
|
|
|
return i > 2;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
filterInPlace(p, l1);
|
|
|
|
|
filterInPlace(p, l2);
|
|
|
|
|
|
|
|
|
|
for ( int i = 0 ; i < l1.size(); i++ ) System.out.print(" "+l1.get(i));
|
|
|
|
|
System.out.println();
|
|
|
|
|
for ( int i = 0 ; i < l2.size(); i++ ) System.out.print(" " + l2.get(i));
|
|
|
|
|
System.out.println();
|
|
|
|
|
|
|
|
|
|
}
|
2009-03-18 03:06:40 +08:00
|
|
|
|
2009-10-23 14:31:15 +08:00
|
|
|
*/
|
2009-03-18 03:06:40 +08:00
|
|
|
|
2009-10-23 14:31:15 +08:00
|
|
|
/**
|
|
|
|
|
* a helper method. Turns a single character string into a char.
|
|
|
|
|
*
|
|
|
|
|
* @param str the string
|
|
|
|
|
*
|
|
|
|
|
* @return a char
|
|
|
|
|
*/
|
|
|
|
|
public static char stringToChar(String str) {
|
|
|
|
|
if (str.length() != 1) throw new IllegalArgumentException("String length must be one");
|
|
|
|
|
return str.charAt(0);
|
2009-03-18 03:06:40 +08:00
|
|
|
}
|
|
|
|
|
|
2009-10-23 14:31:15 +08:00
|
|
|
|
2009-02-27 05:50:29 +08:00
|
|
|
}
|
2009-03-12 05:26:29 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|