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

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

Go to download

The DSI utilities are a mishmash of classes accumulated during the last twenty years in projects developed at the DSI (Dipartimento di Scienze dell'Informazione, i.e., Information Sciences Department), now DI (Dipartimento di Informatica, i.e., Informatics Department), of the Universita` degli Studi di Milano.

There is a newer version: 2.7.3
Show newest version
package it.unimi.dsi;

/*
 * DSI utilities
 *
 * Copyright (C) 2002-2019 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