001/* 002 * Java Genetic Algorithm Library (jenetics-8.0.0). 003 * Copyright (c) 2007-2024 Franz Wilhelmstötter 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 * Author: 018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com) 019 */ 020package io.jenetics.internal.math; 021 022import static java.lang.Double.doubleToLongBits; 023 024import io.jenetics.stat.LongSummary; 025 026/** 027 * This object contains mathematical helper functions. 028 * 029 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a> 030 * @since 1.0 031 * @version 5.2 032 */ 033public final class Basics { 034 private Basics() {} 035 036 /** 037 * Normalize the given double array, so that it sums to one. The 038 * normalization is performed in place and the same {@code values} are 039 * returned. 040 * 041 * @param values the values to normalize. 042 * @return the {@code values} array. 043 * @throws NullPointerException if the given double array is {@code null}. 044 */ 045 public static double[] normalize(final double[] values) { 046 final double sum = 1.0/DoubleAdder.sum(values); 047 for (int i = values.length; --i >= 0;) { 048 values[i] = values[i]*sum; 049 } 050 051 return values; 052 } 053 054 public static double[] normalize(final long[] values) { 055 final double[] result = new double[values.length]; 056 final double sum = 1.0/LongSummary.sum(values); 057 for (int i = values.length; --i >= 0;) { 058 result[i] = values[i]*sum; 059 } 060 061 return result; 062 } 063 064 /** 065 * Component wise division of the given double array. 066 * 067 * @param values the double values to divide. 068 * @param divisor the divisor. 069 * @throws NullPointerException if the given double array is {@code null}. 070 */ 071 public static void divide(final double[] values, final double divisor) { 072 for (int i = values.length; --i >= 0;) { 073 values[i] /= divisor; 074 } 075 } 076 077 /** 078 * Binary exponentiation algorithm. 079 * 080 * @param b the base number. 081 * @param e the exponent. 082 * @return {@code b^e}. 083 */ 084 public static long pow(final long b, final long e) { 085 long base = b; 086 long exp = e; 087 long result = 1; 088 089 while (exp != 0) { 090 if ((exp & 1) != 0) { 091 result *= base; 092 } 093 exp >>>= 1; 094 base *= base; 095 } 096 097 return result; 098 } 099 100 public static boolean isMultiplicationSave(final int a, final int b) { 101 final long m = (long)a*(long)b; 102 return (int)m == m; 103 } 104 105 /** 106 * Return the <a href="http://en.wikipedia.org/wiki/Unit_in_the_last_place">ULP</a> 107 * distance of the given two double values. 108 * 109 * @param a first double. 110 * @param b second double. 111 * @return the ULP distance. 112 * @throws ArithmeticException if the distance doesn't fit in a long value. 113 */ 114 public static long ulpDistance(final double a, final double b) { 115 return Math.subtractExact(ulpPosition(a), ulpPosition(b)); 116 } 117 118 /** 119 * Calculating the <a href="http://en.wikipedia.org/wiki/Unit_in_the_last_place">ULP</a> 120 * position of a double number. 121 * 122 * {@snippet lang="java": 123 * double a = 0.0; 124 * for (int i = 0; i < 10; ++i) { 125 * a = Math.nextAfter(a, Double.POSITIVE_INFINITY); 126 * } 127 * 128 * for (int i = 0; i < 19; ++i) { 129 * a = Math.nextAfter(a, Double.NEGATIVE_INFINITY); 130 * System.out.println( 131 * a + "\t" + ulpPosition(a) + "\t" + ulpDistance(0.0, a) 132 * ); 133 * } 134 * } 135 * 136 * The code fragment above will create the following output: 137 * <pre> 138 * 4.4E-323 9 9 139 * 4.0E-323 8 8 140 * 3.5E-323 7 7 141 * 3.0E-323 6 6 142 * 2.5E-323 5 5 143 * 2.0E-323 4 4 144 * 1.5E-323 3 3 145 * 1.0E-323 2 2 146 * 4.9E-324 1 1 147 * 0.0 0 0 148 * -4.9E-324 -1 1 149 * -1.0E-323 -2 2 150 * -1.5E-323 -3 3 151 * -2.0E-323 -4 4 152 * -2.5E-323 -5 5 153 * -3.0E-323 -6 6 154 * -3.5E-323 -7 7 155 * -4.0E-323 -8 8 156 * -4.4E-323 -9 9 157 * </pre> 158 * 159 * @param a the double number. 160 * @return the ULP position. 161 */ 162 public static long ulpPosition(final double a) { 163 long t = doubleToLongBits(a); 164 if (t < 0) { 165 t = Long.MIN_VALUE - t; 166 } 167 return t; 168 } 169 170}