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

src.it.unimi.dsi.Util Maven / Gradle / Ivy

package it.unimi.dsi;

/*
 * DSI utilities
 *
 * Copyright (C) 2002-2017 Sebastiano Vigna
 *
 *  This library is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU Lesser General Public License as published by the Free
 *  Software Foundation; either version 3 of the License, or (at your option)
 *  any later version.
 *
 *  This library 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 Lesser General Public License
 *  for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program; if not, see .
 *
 */

import it.unimi.dsi.fastutil.BigArrays;
import it.unimi.dsi.fastutil.longs.LongBigArrays;
import it.unimi.dsi.util.XoRoShiRo128PlusRandomGenerator;

import java.text.DecimalFormat;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.util.Locale;

/** All-purpose static-method container class.
 *
 * @author Sebastiano Vigna
 * @since 0.1
 */

public final class Util {
	private Util() {}

	/** A reasonable format for real numbers. Shared by all format methods. */
	private static final NumberFormat FORMAT_DOUBLE = NumberFormat.getInstance(Locale.US);
	static {
		if (FORMAT_DOUBLE instanceof DecimalFormat) ((DecimalFormat)FORMAT_DOUBLE).applyPattern("#,##0.00");
	}
	/** A reasonable format for integers. Shared by all format methods. */
	private static final NumberFormat FORMAT_LONG = NumberFormat.getInstance(Locale.US);
	static {
		if (FORMAT_DOUBLE instanceof DecimalFormat) ((DecimalFormat)FORMAT_LONG).applyPattern("#,###");
	}

	private static final FieldPosition UNUSED_FIELD_POSITION = new java.text.FieldPosition(0);

	/** Formats a number.
	 *
	 * 

This method formats a double separating thousands and printing just two fractional digits. *

Note that the method is synchronized, as it uses a static {@link NumberFormat}. * @param d a number. * @return a string containing a pretty print of the number. */ public synchronized static String format(final double d) { return FORMAT_DOUBLE.format(d, new StringBuffer(), UNUSED_FIELD_POSITION).toString(); } /** Formats a number. * *

This method formats a long separating thousands. *

Note that the method is synchronized, as it uses a static {@link NumberFormat}. * @param l a number. * @return a string containing a pretty print of the number. */ public synchronized static String format(final long l) { return FORMAT_LONG.format(l, new StringBuffer(), UNUSED_FIELD_POSITION).toString(); } /** Formats a number using a specified {@link NumberFormat}. * * @param d a number. * @param format a format. * @return a string containing a pretty print of the number. */ public static String format(final double d, final NumberFormat format) { final StringBuffer s = new StringBuffer(); return format.format(d, s, UNUSED_FIELD_POSITION).toString(); } /** Formats a number using a specified {@link NumberFormat}. * * @param l a number. * @param format a format. * @return a string containing a pretty print of the number. */ public static String format(final long l, final NumberFormat format) { final StringBuffer s = new StringBuffer(); return format.format(l, s, UNUSED_FIELD_POSITION).toString(); } /** Formats a size. * *

This method formats a long using suitable unit multipliers (e.g., K, M, G, and T) * and printing just two fractional digits. *

Note that the method is synchronized, as it uses a static {@link NumberFormat}. * @param l a number, representing a size (e.g., memory). * @return a string containing a pretty print of the number using unit multipliers. */ public static String formatSize(final long l) { if (l >= 1000000000000L) return format(l / 1000000000000.0) + "T"; if (l >= 1000000000L) return format(l / 1000000000.0) + "G"; if (l >= 1000000L) return format(l / 1000000.0) + "M"; if (l >= 1000L) return format(l / 1000.0) + "K"; return Long.toString(l); } /** Formats a binary size. * *

This method formats a long using suitable unit binary multipliers (e.g., Ki, Mi, Gi, and Ti) * and printing no fractional digits. The argument must be a power of 2. *

Note that the method is synchronized, as it uses a static {@link NumberFormat}. * @param l a number, representing a binary size (e.g., memory); must be a power of 2. * @return a string containing a pretty print of the number using binary unit multipliers. */ public static String formatBinarySize(final long l) { if ((l & -l) != l) throw new IllegalArgumentException("Not a power of 2: " + l); if (l >= (1L << 40)) return format(l >> 40) + "Ti"; if (l >= (1L << 30)) return format(l >> 30) + "Gi"; if (l >= (1L << 20)) return format(l >> 20) + "Mi"; if (l >= (1L << 10)) return format(l >> 10) + "Ki"; return Long.toString(l); } /** Formats a size. * *

This method formats a long using suitable binary * unit multipliers (e.g., Ki, Mi, Gi, and Ti) * and printing just two fractional digits. *

Note that the method is synchronized, as it uses a static {@link NumberFormat}. * @param l a number, representing a size (e.g., memory). * @return a string containing a pretty print of the number using binary unit multipliers. */ public static String formatSize2(final long l) { if (l >= 1L << 40) return format((double)l / (1L << 40)) + "Ti"; if (l >= 1L << 30) return format((double)l / (1L << 30)) + "Gi"; if (l >= 1L << 20) return format((double)l / (1L << 20)) + "Mi"; if (l >= 1L << 10) return format((double)l / (1L << 10)) + "Ki"; return Long.toString(l); } /** Formats a size using a specified {@link NumberFormat}. * *

This method formats a long using suitable unit multipliers (e.g., K, M, G, and T) * and the given {@link NumberFormat} for the digits. * @param l a number, representing a size (e.g., memory). * @param format a format. * @return a string containing a pretty print of the number using unit multipliers. */ public static String formatSize(final long l, final NumberFormat format) { if (l >= 1000000000000L) return format(l / 1000000000000.0) + "T"; if (l >= 1000000000L) return format(l / 1000000000.0) + "G"; if (l >= 1000000L) return format(l / 1000000.0) + "M"; if (l >= 1000L) return format(l / 1000.0) + "K"; return Long.toString(l); } /** Formats a size using a specified {@link NumberFormat}. * *

This method formats a long using suitable unit binary multipliers (e.g., Ki, Mi, Gi, and Ti) * and the given {@link NumberFormat} for the digits. The argument must be a power of 2. * @param l a number, representing a binary size (e.g., memory); must be a power of 2. * @param format a format. * @return a string containing a pretty print of the number using binary unit multipliers. */ public static String formatBinarySize(final long l, final NumberFormat format) { if ((l & -l) != l) throw new IllegalArgumentException("Not a power of 2: " + l); if (l >= (1L << 40)) return format(l >> 40) + "Ti"; if (l >= (1L << 30)) return format(l >> 30) + "Gi"; if (l >= (1L << 20)) return format(l >> 20) + "Mi"; if (l >= (1L << 10)) return format(l >> 10) + "Ki"; return Long.toString(l); } /** Formats a size using a specified {@link NumberFormat} and binary unit multipliers. * *

This method formats a long using suitable binary * unit multipliers (e.g., Ki, Mi, Gi, and Ti) * and the given {@link NumberFormat} for the digits. * @param l a number, representing a size (e.g., memory). * @param format a format. * @return a string containing a pretty print of the number using binary unit multipliers. */ public static String formatSize2(final long l, final NumberFormat format) { if (l >= 1L << 40) return format((double)l / (1L << 40)) + "Ti"; if (l >= 1L << 30) return format((double)l / (1L << 30)) + "Gi"; if (l >= 1L << 20) return format((double)l / (1L << 20)) + "Mi"; if (l >= 1L << 10) return format((double)l / (1L << 10)) + "Ki"; return Long.toString(l); } /** A static reference to {@link Runtime#getRuntime()}. */ public final static Runtime RUNTIME = Runtime.getRuntime(); /** Returns true if less then 5% of the available memory is free. * * @return true if less then 5% of the available memory is free. */ public static boolean memoryIsLow() { return availableMemory() * 100 < RUNTIME.totalMemory() * 5; } /** Returns the amount of available memory (free memory plus never allocated memory). * * @return the amount of available memory, in bytes. */ public static long availableMemory() { return RUNTIME.freeMemory() + (RUNTIME.maxMemory() - RUNTIME.totalMemory()); } /** Returns the percentage of available memory (free memory plus never allocated memory). * * @return the percentage of available memory. */ public static int percAvailableMemory() { return (int)((Util.availableMemory() * 100) / Runtime.getRuntime().maxMemory()); } /** Tries to compact memory as much as possible by forcing garbage collection. */ public static void compactMemory() { try { final byte[][] unused = new byte[128][]; for(int i = unused.length; i-- != 0;) unused[i] = new byte[2000000000]; } catch (OutOfMemoryError itsWhatWeWanted) {} System.gc(); } private static final XoRoShiRo128PlusRandomGenerator seedUniquifier = new XoRoShiRo128PlusRandomGenerator(System.nanoTime()); /** Returns a random seed generated by taking the output of a {@link XoRoShiRo128PlusRandomGenerator} * (seeded at startup with {@link System#nanoTime()}) and xoring it with {@link System#nanoTime()}. * * @return a reasonably good random seed. */ public static long randomSeed() { final long x; synchronized(seedUniquifier) { x = seedUniquifier.nextLong(); } return x ^ System.nanoTime(); } /** Returns a random seed generated by {@link #randomSeed()} under the form of an array of eight bytes. * * @return a reasonably good random seed. */ public static byte[] randomSeedBytes() { final long seed = Util.randomSeed(); final byte[] s = new byte[8]; for(int i = Long.SIZE / Byte.SIZE; i-- != 0;) s[i] = (byte)(seed >>> i); return s; } /** Computes in place the inverse of a permutation expressed * as an array of n distinct integers in [0 .. n). * *

Warning: if perm is not a permutation, * essentially anything can happen. * * @param perm the permutation to be inverted. * @return perm. */ public static int[] invertPermutationInPlace(int[] perm) { for(int n = perm.length; n-- != 0;) { int i = perm[n]; if (i < 0) perm[n] = -i - 1; else if (i != n) { int j, k = n; for(;;) { j = perm[i]; perm[i] = -k - 1; if (j == n) { perm[n] = i; break; } k = i; i = j; } } } return perm; } /** Computes the inverse of a permutation expressed * as an array of n distinct integers in [0 .. n). * *

Warning: if perm is not a permutation, * essentially anything can happen. * * @param perm the permutation to be inverted. * @param inv the array storing the inverse. * @return inv. */ public static int[] invertPermutation(int[] perm, int[] inv) { for(int i = perm.length; i-- != 0;) inv[perm[i]] = i; return inv; } /** Computes the inverse of a permutation expressed * as an array of n distinct integers in [0 .. n) * and stores the result in a new array. * *

Warning: if perm is not a permutation, * essentially anything can happen. * * @param perm the permutation to be inverted. * @return a new array containing the inverse permutation. */ public static int[] invertPermutation(int[] perm) { return invertPermutation(perm, new int[perm.length]); } /** Stores the identity permutation in an array. * * @param perm an array of integers. * @return perm, filled with the identity permutation. */ public static int[] identity(int[] perm) { for(int i = perm.length; i-- != 0;) perm[i] = i; return perm; } /** Stores the identity permutation in a new array of given length. * * @param n the size of the array. * @return a new array of length n, filled with the identity permutation. */ public static int[] identity(int n) { return identity(new int[n]); } /** Computes in place the inverse of a permutation expressed * as a {@linkplain BigArrays big array} of n distinct long integers in [0 .. n). * *

Warning: if perm is not a permutation, * essentially anything can happen. * * @param perm the permutation to be inverted. * @return perm. */ public static long[][] invertPermutationInPlace(long[][] perm) { for(long n = LongBigArrays.length(perm); n-- != 0;) { long i = LongBigArrays.get(perm, n); if (i < 0) LongBigArrays.set(perm, n, -i - 1); else if (i != n) { long j, k = n; for(;;) { j = LongBigArrays.get(perm, i); LongBigArrays.set(perm, i, -k - 1); if (j == n) { LongBigArrays.set(perm, n, i); break; } k = i; i = j; } } } return perm; } /** Computes the inverse of a permutation expressed * as a {@linkplain BigArrays big array} of n distinct long integers in [0 .. n). * *

Warning: if perm is not a permutation, * essentially anything can happen. * * @param perm the permutation to be inverted. * @param inv the big array storing the inverse. * @return inv. */ public static long[][] invertPermutation(long[][] perm, long[][] inv) { for(int i = perm.length; i-- != 0;) { final long t[] = perm[i]; for(int d = t.length; d-- != 0;) LongBigArrays.set(inv, t[d], BigArrays.index(i, d)); } return inv; } /** Computes the inverse of a permutation expressed * as a {@linkplain BigArrays big array} of n distinct long integers in [0 .. n) * and stores the result in a new big array. * *

Warning: if perm is not a permutation, * essentially anything can happen. * * @param perm the permutation to be inverted. * @return a new big array containing the inverse permutation. */ public static long[][] invertPermutation(long[][] perm) { return invertPermutation(perm, LongBigArrays.newBigArray(LongBigArrays.length(perm))); } /** Stores the identity permutation in a {@linkplain BigArrays big array}. * * @param perm a big array. * @return perm, filled with the identity permutation. */ public static long[][] identity(long[][] perm) { for(int i = perm.length; i-- != 0;) { final long[] t = perm[i]; for(int d = t.length; d-- != 0;) t[d] = BigArrays.index(i, d); } return perm; } /** Stores the identity permutation in a new big array of given length. * * @param n the size of the array. * @return a new array of length n, filled with the identity permutation. */ public static long[][] identity(long n) { return identity(LongBigArrays.newBigArray(n)); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy