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

org.jenetics.internal.math.base Maven / Gradle / Ivy

There is a newer version: 3.6.0
Show newest version
/*
 * Java Genetic Algorithm Library (jenetics-3.1.0).
 * Copyright (c) 2007-2015 Franz Wilhelmstötter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author:
 *    Franz Wilhelmstötter ([email protected])
 */
package org.jenetics.internal.math;

import static java.lang.Double.doubleToLongBits;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;

import java.util.Random;

import org.jenetics.internal.util.require;

import org.jenetics.util.RandomRegistry;

/**
 * This object contains mathematical helper functions.
 *
 * @author Franz Wilhelmstötter
 * @since 1.0
 * @version 3.0
 */
public final class base {
	private base() {require.noInstance();}

	/**
	 * Clamping a value between a pair of boundary values.
	 * Note: using clamp with floating point numbers may give unexpected
	 * results if one of the values is {@code NaN}.
	 *
	 * @param v the value to clamp
	 * @param lo the lower bound.
	 * @param hi the upper bound.
	 * @return The clamped value:
	 *        
    *
  • {@code lo if v < lo}
  • *
  • {@code hi if hi < v}
  • *
  • {@code otherwise, v}
  • *
*/ public static double clamp(final double v, final double lo, final double hi) { return v < lo ? lo : (v > hi ? hi : v); } /** * Return the ULP * distance of the given two double values. * * @param a first double. * @param b second double. * @return the ULP distance. * @throws ArithmeticException if the distance doesn't fit in a long value. */ public static long ulpDistance(final double a, final double b) { return Math.subtractExact(ulpPosition(a), ulpPosition(b)); } /** * Calculating the ULP * position of a double number. * *
{@code
	 * double a = 0.0;
	 * for (int i = 0; i < 10; ++i) {
	 *     a = Math.nextAfter(a, Double.POSITIVE_INFINITY);
	 * }
	 *
	 * for (int i = 0; i < 19; ++i) {
	 *     a = Math.nextAfter(a, Double.NEGATIVE_INFINITY);
	 *     System.out.println(
	 *          a + "\t" + ulpPosition(a) + "\t" + ulpDistance(0.0, a)
	 *     );
	 * }
	 * }
* * The code fragment above will create the following output: *
	 *   4.4E-323    9  9
	 *   4.0E-323    8  8
	 *   3.5E-323    7  7
	 *   3.0E-323    6  6
	 *   2.5E-323    5  5
	 *   2.0E-323    4  4
	 *   1.5E-323    3  3
	 *   1.0E-323    2  2
	 *   4.9E-324    1  1
	 *   0.0         0  0
	 *  -4.9E-324   -1  1
	 *  -1.0E-323   -2  2
	 *  -1.5E-323   -3  3
	 *  -2.0E-323   -4  4
	 *  -2.5E-323   -5  5
	 *  -3.0E-323   -6  6
	 *  -3.5E-323   -7  7
	 *  -4.0E-323   -8  8
	 *  -4.4E-323   -9  9
	 * 
* * @param a the double number. * @return the ULP position. */ public static long ulpPosition(final double a) { long t = doubleToLongBits(a); if (t < 0) { t = Long.MIN_VALUE - t; } return t; } /** * Selects a random subset of size {@code k} from a set of size {@code n}. * * @see #subset(int, int[]) * * @param n the size of the set. * @param k the size of the subset. * @throws IllegalArgumentException if {@code n < k}, {@code k == 0} or if * {@code n*k} will cause an integer overflow. * @return the subset array. */ public static int[] subset(final int n, final int k) { return subset(n, k, RandomRegistry.getRandom()); } /** * Selects a random subset of size {@code k} from a set of size {@code n}. * * @see #subset(int, int[], Random) * * @param n the size of the set. * @param k the size of the subset. * @param random the random number generator used. * @throws NullPointerException if {@code random} is {@code null}. * @throws IllegalArgumentException if {@code n < k}, {@code k == 0} or if * {@code n*k} will cause an integer overflow. * @return the subset array. */ public static int[] subset(final int n, final int k, final Random random) { requireNonNull(random, "Random"); if (k <= 0) { throw new IllegalArgumentException(format( "Subset size smaller or equal zero: %s", k )); } if (n < k) { throw new IllegalArgumentException(format( "n smaller than k: %s < %s.", n, k )); } final int[] sub = new int[k]; subset(n, sub,random); return sub; } /** *

* Selects a random subset of size {@code sub.length} from a set of size * {@code n}. *

* *

* Authors: * FORTRAN77 original version by Albert Nijenhuis, Herbert Wilf. This * version based on the C++ version by John Burkardt. *

* *

* Reference: * Albert Nijenhuis, Herbert Wilf, * Combinatorial Algorithms for Computers and Calculators, * Second Edition, * Academic Press, 1978, * ISBN: 0-12-519260-6, * LC: QA164.N54. *

* * @param n the size of the set. * @param sub the sub set array. * @throws NullPointerException if {@code sub} is {@code null}. * @throws IllegalArgumentException if {@code n < sub.length}, * {@code sub.length == 0} or {@code n*sub.length} will cause an * integer overflow. */ public static void subset(final int n, final int sub[]) { subset(n, sub, RandomRegistry.getRandom()); } /** *

* Selects a random subset of size {@code sub.length} from a set of size * {@code n}. *

* *

* Authors: * FORTRAN77 original version by Albert Nijenhuis, Herbert Wilf. This * version based on the C++ version by John Burkardt. *

* *

* Reference: * Albert Nijenhuis, Herbert Wilf, * Combinatorial Algorithms for Computers and Calculators, * Second Edition, * Academic Press, 1978, * ISBN: 0-12-519260-6, * LC: QA164.N54. *

* * @param n the size of the set. * @param sub the sub set array. * @param random the random number generator used. * @return the sub-set array for the given parameter * @throws NullPointerException if {@code sub} or {@code random} is * {@code null}. * @throws IllegalArgumentException if {@code n < sub.length}, * {@code sub.length == 0} or {@code n*sub.length} will cause an * integer overflow. */ public static int[] subset(final int n, final int sub[], final Random random) { requireNonNull(random, "Random"); requireNonNull(sub, "Sub set array"); final int k = sub.length; if (k <= 0) { throw new IllegalArgumentException(format( "Subset size smaller or equal zero: %s", k )); } if (n < k) { throw new IllegalArgumentException(format( "n smaller than k: %s < %s.", n, k )); } if (!arithmetic.isMultiplicationSave(n, k)) { throw new IllegalArgumentException(format( "n*sub.length > Integer.MAX_VALUE (%s*%s = %s > %s)", n, sub.length, (long)n*(long)k, Integer.MAX_VALUE )); } if (sub.length == n) { for (int i = 0; i < sub.length; ++i) { sub[i] = i; } return sub; } for (int i = 0; i < k; ++i) { sub[i] = (i*n)/k; } int l = 0; int ix = 0; for (int i = 0; i < k; ++i) { do { ix = nextInt(random, 1, n); l = (ix*k - 1)/n; } while (sub[l] >= ix); sub[l] = sub[l] + 1; } int m = 0; int ip = 0; int is = k; for (int i = 0; i < k; ++i) { m = sub[i]; sub[i] = 0; if (m != (i*n)/k) { ip = ip + 1; sub[ip - 1] = m; } } int ihi = ip; int ids = 0; for (int i = 1; i <= ihi; ++i) { ip = ihi + 1 - i; l = 1 + (sub[ip - 1]*k - 1)/n; ids = sub[ip - 1] - ((l - 1)*n)/k; sub[ip - 1] = 0; sub[is - 1] = l; is = is - ids; } int ir = 0; int m0 = 0; for (int ll = 1; ll <= k; ++ll) { l = k + 1 - ll; if (sub[l - 1] != 0) { ir = l; m0 = 1 + ((sub[l - 1] - 1)*n)/k; m = (sub[l-1]*n)/k - m0 + 1; } ix = nextInt(random, m0, m0 + m - 1); int i = l + 1; while (i <= ir && ix >= sub[i - 1]) { ix = ix + 1; sub[ i- 2] = sub[i - 1]; i = i + 1; } sub[i - 2] = ix; --m; } return sub; } private static int nextInt(final Random random, final int a, final int b) { return a == b ? a - 1 : random.nextInt(b - a) + a; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy