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

net.dermetfan.utils.math.MathUtils Maven / Gradle / Ivy

There is a newer version: 0.13.4
Show newest version
/** Copyright 2014 Robin Stumm ([email protected], http://dermetfan.net)
 *
 *  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. */

package net.dermetfan.utils.math;

/** math utility methods
 *  @author dermetfan */
public class MathUtils {

	/** @param n the number which cross sum to calculate
	 *  @return the cross sum (sum of a number's digits) */
	public static int crossSum(int n) {
		int csum = 0;
		while(n > 0) {
			csum += n % 10;
			n /= 10;
		}
		return csum;
	}

	/** int wrapper for {@link #factorial(float)}
	 *  @see #factorial(float) */
	public static int factorial(int n) {
		return (int) factorial((float) n);
	}

	/** @param n the number to find the factorial for
	 *  @return the factorial of the given number */
	public static float factorial(float n) {
		if(n < 0)
			throw new IllegalArgumentException("n must be >= 0: " + n);
		return n <= 1 ? 1 : n * factorial(n - 1);
	}

	/** @return if the given value is in between min and max (exclusive)
	 *  @see #between(float, float, float, boolean) */
	public static boolean between(float value, float min, float max) {
		return between(value, min, max, false);
	}

	/** min and max will be swapped if they are given in the wrong order
	 *  @param inclusive if the given value is allowed to be equal to min or max
	 *  @return if the given value is in between min and max */
	public static boolean between(float value, float min, float max, boolean inclusive) {
		min = Math.min(min, max);
		max = Math.max(min, max);
		return inclusive ? value >= min && value <= max : value > min && value < max;
	}

	/** @return the determinant of the given 3x3 matrix */
	public static float det(float x1, float y1, float x2, float y2, float x3, float y3) {
		return x1 * y2 + x2 * y3 + x3 * y1 - y1 * x2 - y2 * x3 - y3 * x1;
	}

	/** @param value the value to normalize between 0 and the given range
	 *  @param range the other bound of the interval with 0
	 *  @see #normalize(float, float, float) */
	public static float normalize(float value, float range) {
		return normalize(value, 0, range);
	}

	/** Normalizes/repeats the given value in the given interval [min, max] as if min and max were portals the value travels through. For example:
* * * * * * * * * * * * * * * * * * * * * * * * * *
valueminmaxresult
150010050
200-1001000
50010050
* @param value the value to normalize in the interval [min, max] * @param min the minimum * @param max the maximum * @return the value repeated in the interval [min, max] */ public static float normalize(float value, float min, float max) { if(min == max) return min; float oldMin = min, oldMax = max; min = Math.min(min, max); max = Math.max(oldMin, max); float under = value < min ? Math.abs(min - value) : 0, over = value > max ? value - Math.abs(max) : 0; if(under > 0) return normalize(oldMax + (oldMax > oldMin ? -under : under), min, max); if(over > 0) return normalize(oldMin + (oldMin < oldMax ? over : -over), min, max); return value; } /** @param value the value to mirror * @param baseline the max/min value * @return the value mirrored at baseline */ public static float mirror(float value, float baseline) { return baseline * 2 - value; } /** @return value, min or max */ public static float clamp(float value, float min, float max) { return value < min ? min : value > max ? max : value; } /** @return {@code replacement} if {@code value} is NaN */ public static float replaceNaN(float value, float replacement) { return Float.isNaN(value) ? replacement : value; } /** @return the given values with each element being the {@link Math#abs(float) absolute} of its value */ public static float[] abs(float[] values) { for(int i = 0; i < values.length; i++) values[i] = Math.abs(values[i]); return values; } /** @return the given values with each element multiplied with the given factor */ public static float[] mul(float[] values, float factor) { for(int i = 0; i < values.length; i++) values[i] *= factor; return values; } /** @return the given values with each element divided by the given divisor */ public static float[] div(float[] values, float divisor) { return mul(values, 1 / divisor); } /** @return the given values with the given value added to each element */ public static float[] add(float[] values, float value) { for(int i = 0; i < values.length; i++) values[i] += value; return values; } /** @return the given values with the given value subtracted from each element */ public static float[] sub(float[] values, float value) { return add(values, -value); } /** @return the sum of all values in the given array */ public static float sum(float[] values) { float sum = 0; for(float v : values) sum += v; return sum; } /** @return the peak-to-peak amplitude of the given array */ public static float amplitude(float[] f) { return Math.abs(max(f) - min(f)); } /** @return the largest element of the given array */ public static float max(float[] floats) { float max = Float.NEGATIVE_INFINITY; for(float f : floats) if(f > max) max = f; return max; } /** @return the smallest element of the given array */ public static float min(float[] floats) { float min = Float.POSITIVE_INFINITY; for(float f : floats) if(f < min) min = f; return min; } /** @param value the desired value * @param values the values to inspect * @param range values out of this range will not be returned * @return the nearest to value in values, {@code NaN} if none is found */ public static float nearest(float value, float[] values, float range) { float diff, smallestDiff = Float.POSITIVE_INFINITY, nearest = Float.NaN; if(value == Float.POSITIVE_INFINITY) { float max = max(values); if(max - range <= value) return max; return nearest; } else if(value == Float.NEGATIVE_INFINITY) { float min = min(values); if(min + range >= value) return min; return nearest; } for(float candidate : values) { if(candidate == value) return value; if((diff = Math.abs(candidate - value)) < smallestDiff) if((smallestDiff = diff) <= range) nearest = candidate; } return nearest; } /** @return the nearest to value in values * @see #nearest(float, float[], float) */ public static float nearest(float value, float[] values) { return nearest(value, values, Float.POSITIVE_INFINITY); } /** scales the given float array to have the given min and max values * @param values the values to scale * @param min the desired minimal value in the array * @param max the desired maximal value in the array * @param clamp if the values should be clamped to correct floating point inaccuracy * @return the scaled array */ public static float[] scale(float[] values, float min, float max, boolean clamp) { int i; float tmp = amplitude(values) / (max - min); for(i = 0; i < values.length; i++) values[i] /= tmp; tmp = min - min(values); for(i = 0; i < values.length; i++) values[i] += tmp; if(clamp) for(i = 0; i < values.length; i++) if(values[i] > max) values[i] = max; return values; } /** @param sum the sum at which to return the element * @param values the values to add together to calculate {@code sum} * @param elements the elements from which to return one when {@code sum} is reached * @return the element from {@code elements} when {@code sum} was reached by adding the given {@code values} together */ public static T elementAtSum(float sum, float[] values, T[] elements) { float total = 0; for(int i = 0; i < values.length; i++) if((total += values[i]) >= sum) return elements[i]; return total <= 0 ? elements[0] : elements[elements.length - 1]; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy